Date: Sat, 22 Sep 2012 04:22:18 +0000 (UTC) From: "Pedro F. Giffuni" <pfg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r240800 - in stable/8: include/rpc lib/libc/rpc sys/rpc Message-ID: <201209220422.q8M4MIUH083715@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: pfg Date: Sat Sep 22 04:22:17 2012 New Revision: 240800 URL: http://svn.freebsd.org/changeset/base/240800 Log: MFC r239963: Bring some changes from Bull's NFSv4 libtirpc implementation. ____ Fixed infinite loop in svc_run() ____ __rpc_taddr2uaddr_af() assumes the netbuf to always have a non-zero data. This is a bad assumption and can lead to a seg-fault. This patch adds a check for zero length and returns NULL when found. ____ Changed clnt_spcreateerror() to return clearer and more concise error messages. ____ Converted all uid and gid variables of the type uid_t and gid_t. ____ libtirpc: set r_netid and r_owner in __rpcb_findaddr_timed These fields in the rpcbind GETADDR call are being passed uninitialized to CLNT_CALL. In the case of x86_64 at least, this usually leads to a segfault. On x86, it sometimes causes segfaults and other times causes garbage to be sent on the wire. rpcbind generally ignores the r_owner field for calls that come in over the wire, so it really doesn't matter what we send in that slot. We just need to send something. The reference implementation from Sun seems to send a blank string. Have ours follow suit. ____ libtirpc: be sure to free cl_netid and cl_tp When creating a client with clnt_tli_create, it uses strdup to copy strings for these fields if nconf is passed in. clnt_dg_destroy frees these strings already. Make sure clnt_vc_destroy frees them in the same way. ____ Obtained from: Bull GNU/Linux NFSv4 Project Modified: stable/8/include/rpc/auth.h stable/8/include/rpc/auth_unix.h stable/8/lib/libc/rpc/auth_unix.c stable/8/lib/libc/rpc/authunix_prot.c stable/8/lib/libc/rpc/clnt_perror.c stable/8/lib/libc/rpc/clnt_vc.c stable/8/lib/libc/rpc/rpc_generic.c stable/8/lib/libc/rpc/rpc_soc.3 stable/8/lib/libc/rpc/rpcb_clnt.c stable/8/lib/libc/rpc/svc_auth_unix.c stable/8/lib/libc/rpc/svc_run.c stable/8/sys/rpc/auth.h stable/8/sys/rpc/clnt_vc.c stable/8/sys/rpc/rpcb_clnt.c Directory Properties: stable/8/include/ (props changed) stable/8/include/rpc/ (props changed) stable/8/lib/ (props changed) stable/8/lib/libc/ (props changed) stable/8/lib/libc/rpc/ (props changed) stable/8/sys/ (props changed) stable/8/sys/rpc/ (props changed) Modified: stable/8/include/rpc/auth.h ============================================================================== --- stable/8/include/rpc/auth.h Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/include/rpc/auth.h Sat Sep 22 04:22:17 2012 (r240800) @@ -243,14 +243,13 @@ __END_DECLS * System style authentication * AUTH *authunix_create(machname, uid, gid, len, aup_gids) * char *machname; - * int uid; - * int gid; + * uid_t uid; + * gid_t gid; * int len; - * int *aup_gids; + * gid_t *aup_gids; */ __BEGIN_DECLS -extern AUTH *authunix_create(char *, int, int, int, - int *); +extern AUTH *authunix_create(char *, uid_t, gid_t, int, gid_t *); extern AUTH *authunix_create_default(void); /* takes no parameters */ extern AUTH *authnone_create(void); /* takes no parameters */ __END_DECLS Modified: stable/8/include/rpc/auth_unix.h ============================================================================== --- stable/8/include/rpc/auth_unix.h Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/include/rpc/auth_unix.h Sat Sep 22 04:22:17 2012 (r240800) @@ -60,10 +60,10 @@ struct authunix_parms { u_long aup_time; char *aup_machname; - int aup_uid; - int aup_gid; + uid_t aup_uid; + gid_t aup_gid; u_int aup_len; - int *aup_gids; + gid_t *aup_gids; }; #define authsys_parms authunix_parms Modified: stable/8/lib/libc/rpc/auth_unix.c ============================================================================== --- stable/8/lib/libc/rpc/auth_unix.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/auth_unix.c Sat Sep 22 04:22:17 2012 (r240800) @@ -94,10 +94,10 @@ struct audata { AUTH * authunix_create(machname, uid, gid, len, aup_gids) char *machname; - int uid; - int gid; + uid_t uid; + gid_t gid; int len; - int *aup_gids; + gid_t *aup_gids; { struct authunix_parms aup; char mymem[MAX_AUTH_BYTES]; @@ -207,9 +207,7 @@ authunix_create_default() abort(); if (ngids > NGRPS) ngids = NGRPS; - /* XXX: interface problem; those should all have been unsigned */ - auth = authunix_create(machname, (int)uid, (int)gid, ngids, - (int *)gids); + auth = authunix_create(machname, uid, gid, ngids, gids); free(gids); return (auth); } Modified: stable/8/lib/libc/rpc/authunix_prot.c ============================================================================== --- stable/8/lib/libc/rpc/authunix_prot.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/authunix_prot.c Sat Sep 22 04:22:17 2012 (r240800) @@ -60,7 +60,7 @@ xdr_authunix_parms(xdrs, p) XDR *xdrs; struct authunix_parms *p; { - int **paup_gids; + gid_t **paup_gids; assert(xdrs != NULL); assert(p != NULL); @@ -69,8 +69,8 @@ xdr_authunix_parms(xdrs, p) if (xdr_u_long(xdrs, &(p->aup_time)) && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) - && xdr_int(xdrs, &(p->aup_uid)) - && xdr_int(xdrs, &(p->aup_gid)) + && xdr_u_int(xdrs, &(p->aup_uid)) + && xdr_u_int(xdrs, &(p->aup_gid)) && xdr_array(xdrs, (char **) paup_gids, &(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int) ) { return (TRUE); Modified: stable/8/lib/libc/rpc/clnt_perror.c ============================================================================== --- stable/8/lib/libc/rpc/clnt_perror.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/clnt_perror.c Sat Sep 22 04:22:17 2012 (r240800) @@ -242,7 +242,7 @@ char * clnt_spcreateerror(s) const char *s; { - char *str; + char *str, *err; size_t len, i; assert(s != NULL); @@ -258,8 +258,21 @@ clnt_spcreateerror(s) switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: (void) strncat(str, " - ", len - 1); - (void) strncat(str, - clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4); + err = clnt_sperrno(rpc_createerr.cf_error.re_status); + if (err) + (void) strncat(str, err+5, len-5); + switch(rpc_createerr.cf_error.re_status) { + case RPC_CANTSEND: + case RPC_CANTRECV: + i = strlen(str); + len -= i; + snprintf(str+i, len, ": errno %d (%s)", + rpc_createerr.cf_error.re_errno, + strerror(rpc_createerr.cf_error.re_errno)); + break; + default: + break; + } break; case RPC_SYSTEMERROR: Modified: stable/8/lib/libc/rpc/clnt_vc.c ============================================================================== --- stable/8/lib/libc/rpc/clnt_vc.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/clnt_vc.c Sat Sep 22 04:22:17 2012 (r240800) @@ -672,6 +672,10 @@ clnt_vc_destroy(cl) if (ct->ct_addr.buf) free(ct->ct_addr.buf); mem_free(ct, sizeof(struct ct_data)); + if (cl->cl_netid && cl->cl_netid[0]) + mem_free(cl->cl_netid, strlen(cl->cl_netid) +1); + if (cl->cl_tp && cl->cl_tp[0]) + mem_free(cl->cl_tp, strlen(cl->cl_tp) +1); mem_free(cl, sizeof(CLIENT)); mutex_unlock(&clnt_fd_lock); thr_sigsetmask(SIG_SETMASK, &(mask), NULL); Modified: stable/8/lib/libc/rpc/rpc_generic.c ============================================================================== --- stable/8/lib/libc/rpc/rpc_generic.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/rpc_generic.c Sat Sep 22 04:22:17 2012 (r240800) @@ -269,7 +269,8 @@ __rpc_getconfip(nettype) } while ((nconf = getnetconfig(confighandle)) != NULL) { if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { - if (strcmp(nconf->nc_proto, NC_TCP) == 0) { + if (strcmp(nconf->nc_proto, NC_TCP) == 0 && + netid_tcp == NULL) { netid_tcp = strdup(nconf->nc_netid); if (main_thread) netid_tcp_main = netid_tcp; @@ -277,7 +278,8 @@ __rpc_getconfip(nettype) thr_setspecific(tcp_key, (void *) netid_tcp); } else - if (strcmp(nconf->nc_proto, NC_UDP) == 0) { + if (strcmp(nconf->nc_proto, NC_UDP) == 0 && + netid_udp == NULL) { netid_udp = strdup(nconf->nc_netid); if (main_thread) netid_udp_main = netid_udp; @@ -616,6 +618,9 @@ __rpc_taddr2uaddr_af(int af, const struc #endif u_int16_t port; + if (nbuf->len <= 0) + return NULL; + switch (af) { case AF_INET: sin = nbuf->buf; Modified: stable/8/lib/libc/rpc/rpc_soc.3 ============================================================================== --- stable/8/lib/libc/rpc/rpc_soc.3 Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/rpc_soc.3 Sat Sep 22 04:22:17 2012 (r240800) @@ -148,7 +148,7 @@ default authentication used by .Ft "AUTH *" .Xc .It Xo -.Fn authunix_create "char *host" "int uid" "int gid" "int len" "int *aup_gids" +.Fn authunix_create "char *host" "uid_t uid" "gid_t gid" "int len" "gid_t *aup_gids" .Xc .Pp Create and return an Modified: stable/8/lib/libc/rpc/rpcb_clnt.c ============================================================================== --- stable/8/lib/libc/rpc/rpcb_clnt.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/rpcb_clnt.c Sat Sep 22 04:22:17 2012 (r240800) @@ -770,6 +770,13 @@ __rpcb_findaddr_timed(program, version, } parms.r_addr = NULL; + parms.r_netid = nconf->nc_netid; + + /* + * According to wire captures, the reference implementation + * (OpenSolaris) sends a blank string here too. + */ + parms.r_owner = ""; /* * Use default total timeout if no timeout is specified. Modified: stable/8/lib/libc/rpc/svc_auth_unix.c ============================================================================== --- stable/8/lib/libc/rpc/svc_auth_unix.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/svc_auth_unix.c Sat Sep 22 04:22:17 2012 (r240800) @@ -68,7 +68,7 @@ _svcauth_unix(rqst, msg) struct area { struct authunix_parms area_aup; char area_machname[MAX_MACHINE_NAME+1]; - int area_gids[NGRPS]; + gid_t area_gids[NGRPS]; } *area; u_int auth_len; size_t str_len, gid_len; Modified: stable/8/lib/libc/rpc/svc_run.c ============================================================================== --- stable/8/lib/libc/rpc/svc_run.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/lib/libc/rpc/svc_run.c Sat Sep 22 04:22:17 2012 (r240800) @@ -60,14 +60,13 @@ svc_run() fd_set readfds, cleanfds; struct timeval timeout; - timeout.tv_sec = 30; - timeout.tv_usec = 0; - for (;;) { rwlock_rdlock(&svc_fd_lock); readfds = svc_fdset; cleanfds = svc_fdset; rwlock_unlock(&svc_fd_lock); + timeout.tv_sec = 30; + timeout.tv_usec = 0; switch (_select(svc_maxfd+1, &readfds, NULL, NULL, &timeout)) { case -1: FD_ZERO(&readfds); Modified: stable/8/sys/rpc/auth.h ============================================================================== --- stable/8/sys/rpc/auth.h Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/sys/rpc/auth.h Sat Sep 22 04:22:17 2012 (r240800) @@ -234,18 +234,17 @@ __END_DECLS * System style authentication * AUTH *authunix_create(machname, uid, gid, len, aup_gids) * char *machname; - * int uid; - * int gid; + * uid_t uid; + * gid_t gid; * int len; - * int *aup_gids; + * gid_t *aup_gids; */ __BEGIN_DECLS #ifdef _KERNEL struct ucred; extern AUTH *authunix_create(struct ucred *); #else -extern AUTH *authunix_create(char *, int, int, int, - int *); +extern AUTH *authunix_create(char *, uid_t, gid_t, int, gid_t *); extern AUTH *authunix_create_default(void); /* takes no parameters */ #endif extern AUTH *authnone_create(void); /* takes no parameters */ Modified: stable/8/sys/rpc/clnt_vc.c ============================================================================== --- stable/8/sys/rpc/clnt_vc.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/sys/rpc/clnt_vc.c Sat Sep 22 04:22:17 2012 (r240800) @@ -836,6 +836,10 @@ clnt_vc_destroy(CLIENT *cl) soclose(so); } mem_free(ct, sizeof(struct ct_data)); + if (cl->cl_netid && cl->cl_netid[0]) + mem_free(cl->cl_netid, strlen(cl->cl_netid) +1); + if (cl->cl_tp && cl->cl_tp[0]) + mem_free(cl->cl_tp, strlen(cl->cl_tp) +1); mem_free(cl, sizeof(CLIENT)); } Modified: stable/8/sys/rpc/rpcb_clnt.c ============================================================================== --- stable/8/sys/rpc/rpcb_clnt.c Sat Sep 22 04:18:42 2012 (r240799) +++ stable/8/sys/rpc/rpcb_clnt.c Sat Sep 22 04:22:17 2012 (r240800) @@ -780,6 +780,13 @@ __rpcb_findaddr_timed(program, version, } parms.r_addr = NULL; + parms.r_netid = nconf->nc_netid; + + /* + * According to wire captures, the reference implementation + * (OpenSolaris) sends a blank string here too. + */ + parms.r_owner = ""; /* * Use default total timeout if no timeout is specified.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209220422.q8M4MIUH083715>