Date: Sat, 6 Oct 2001 17:40:01 -0700 (PDT) From: Martin Blapp <mb@imp.ch> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/29171: [PATCH] keyserv and rpc.yppasswd Message-ID: <200110070040.f970e1P30686@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/29171; it has been noted by GNATS. From: Martin Blapp <mb@imp.ch> To: <freebsd-gnats-submit@FreeBSD.org> Cc: Subject: Re: bin/29171: [PATCH] keyserv and rpc.yppasswd Date: Sun, 7 Oct 2001 02:40:51 +0200 (CEST) One part: http://home.teleport.ch/freebsd/userland/local_transp_compat.diff has been comitted by Bill Paul. Thanks ! Here are the other patches: usr.sbin/keyserv/keyserv.c Fix the breakage in keyserv, Readded the svc_create() and the registering of the "unix" transport, now it is fixed. --- usr.sbin/keyserv/keyserv.c Thu Mar 22 05:31:29 2001 +++ usr.sbin/keyserv/keyserv.c Fri Apr 6 23:41:56 2001 @@ -117,6 +117,8 @@ int sock = RPC_ANYSOCK; int warn = 0; char *path = NULL; + void *localhandle; + struct netconfig *nconf = NULL; __key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog; __key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog; @@ -155,12 +157,15 @@ /* * Initialize */ - (void) umask(066); /* paranoia */ + (void) umask(S_IXUSR|S_IXGRP|S_IXOTH); if (geteuid() != 0) errx(1, "keyserv must be run as root"); setmodulus(HEXMODULUS); getrootkey(&masterkey, nflag); + rpcb_unset(KEY_PROG, KEY_VERS, NULL); + rpcb_unset(KEY_PROG, KEY_VERS2, NULL); + if (svc_create(keyprogram, KEY_PROG, KEY_VERS, "netpath") == 0) { (void) fprintf(stderr, @@ -174,6 +179,32 @@ "%s: unable to create service\n", argv[0]); exit(1); } + + localhandle = setnetconfig(); + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } + + if (nconf == NULL) + errx(1, "getnetconfig: %s", nc_sperror()); + + unlink(KEYSERVSOCK); + rpcb_unset(CRYPT_PROG, CRYPT_VERS, nconf); + transp = svcunix_create(RPC_ANYSOCK, 0, 0, KEYSERVSOCK); + if (transp == NULL) + errx(1, "cannot create AF_LOCAL service"); + if (!svc_reg(transp, KEY_PROG, KEY_VERS, keyprogram, nconf)) + errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)"); + if (!svc_reg(transp, KEY_PROG, KEY_VERS2, keyprogram, nconf)) + errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)"); + if (!svc_reg(transp, CRYPT_PROG, CRYPT_VERS, crypt_prog_1, nconf)) + errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)"); + + endnetconfig(localhandle); + + (void) umask(066); /* paranoia */ if (!debugging) { daemon(0,0); usr.sbin/rpc.yppasswdd/yppasswdd_main.c usr.sbin/rpc.yppasswdd/yppasswdd_server.c Fix the breakage in rpc.yppasswd. Readded the svc_create() and the registering of the "unix" transport, now it is fixed. Everywhere, rq_cred is taken to look what authentification we have. We can not bu sure that transp>xp_verf.oa_flavor is also filled in. This seems to be the same for all sun source. they take the flavor of rq_cred, instead of transp. - transp>xp_verf.oa_flavor != AUTH_UNIX) { + rqstp->rq_cred.oa_flavor != AUTH_UNIX) { Please look at my other fix: local_transp_svc_vc.c.diff to have a better explanation. --- usr.sbin/rpc.yppasswdd/yppasswdd_main.c Mon Mar 19 13:50:10 2001 +++ usr.sbin/rpc.yppasswdd/yppasswdd_main.c Thu Apr 19 13:55:29 2001 @@ -100,8 +100,8 @@ static void terminate(sig) int sig; { - svc_unregister(YPPASSWDPROG, YPPASSWDVERS); - svc_unregister(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS); + rpcb_unset(YPPASSWDPROG, YPPASSWDVERS, NULL); + rpcb_unset(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, NULL); unlink(sockname); exit(0); } @@ -156,13 +156,14 @@ char *argv[]; { register SVCXPRT *transp = NULL; - int sock; - int proto = 0; struct sockaddr_in saddr; int asize = sizeof (saddr); + struct netconfig *nconf; + void *localhandle; int ch; char *mastername; char myname[MAXHOSTNAMELEN + 2]; + extern int debug; debug = 1; @@ -246,78 +247,59 @@ if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) { int ssize = sizeof (int); - if (saddr.sin_family != AF_INET) exit(1); if (getsockopt(0, SOL_SOCKET, SO_TYPE, - (char *)&_rpcfdtype, &ssize) == -1) + (char *)&_rpcfdtype, &ssize) == -1) exit(1); - sock = 0; _rpcpmstart = 1; - proto = 0; - openlog("rpc.yppasswdd", LOG_PID, LOG_DAEMON); - } else { - if (!debug) { - if (daemon(0,0)) { - err(1,"cannot fork"); - } - } - openlog("rpc.yppasswdd", LOG_PID, LOG_DAEMON); - sock = RPC_ANYSOCK; - (void) pmap_unset(YPPASSWDPROG, YPPASSWDVERS); - (void) pmap_unset(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS); - unlink(sockname); - } - - if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) { - transp = svcudp_create(sock); - if (transp == NULL) { - yp_error("cannot create udp service."); - exit(1); - } - if (!_rpcpmstart) - proto = IPPROTO_UDP; - if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswdprog_1, proto)) { - yp_error("unable to register (YPPASSWDPROG, YPPASSWDVERS, udp)."); - exit(1); - } } - if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) { - transp = svctcp_create(sock, 0, 0); - if (transp == NULL) { - yp_error("cannot create tcp service."); - exit(1); - } - if (!_rpcpmstart) - proto = IPPROTO_TCP; - if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswdprog_1, proto)) { - yp_error("unable to register (YPPASSWDPROG, YPPASSWDVERS, tcp)."); - exit(1); + if (!debug && _rpcpmstart == 0) { + if (daemon(0,0)) { + err(1,"cannot fork"); } } + openlog("rpc.yppasswdd", LOG_PID, LOG_DAEMON); - unlink(sockname); - if (svc_create(yppasswdprog_1, YPPASSWDPROG, YPPASSWDVERS, - "netpath") == 0) { - (void) fprintf(stderr, - "%s: unable to create service\n", argv[0]); - exit(1); - } - if (svc_create(master_yppasswdprog_1, MASTER_YPPASSWDPROG, + rpcb_unset(YPPASSWDPROG, YPPASSWDVERS, NULL); + rpcb_unset(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, NULL); + + if (svc_create(yppasswdprog_1, YPPASSWDPROG, YPPASSWDVERS, "netpath") == 0) { + yp_error("cannot create yppasswd service."); + exit(1); + } + if (svc_create(master_yppasswdprog_1, MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, "netpath") == 0) { - (void) fprintf(stderr, - "%s: unable to create service\n", argv[0]); - exit(1); - } + yp_error("cannot create master_yppasswd service."); + exit(1); + } + + nconf = NULL; + localhandle = setnetconfig(); + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } + if (nconf == NULL) { + yp_error("getnetconfigent unix: %s", nc_sperror()); + exit(1); + } + unlink(sockname); + transp = svcunix_create(RPC_ANYSOCK, 0, 0, sockname); if (transp == NULL) { yp_error("cannot create AF_LOCAL service."); exit(1); } - if (!svc_register(transp, MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, master_yppasswdprog_1, 0)) { - yp_error("unable to register (MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, unix)."); + if (!svc_reg(transp, MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, + master_yppasswdprog_1, nconf)) { + yp_error("unable to register (MASTER_YPPASSWDPROG, + MASTER_YPPASSWDVERS, unix)."); exit(1); } + endnetconfig(localhandle); + /* Only root may connect() to the AF_UNIX link. */ if (chmod(sockname, 0)) err(1, "chmod of %s failed", sockname); --- usr.sbin/rpc.yppasswdd/yppasswdd_server.c Thu Mar 22 21:43:13 2001 +++ usr.sbin/rpc.yppasswdd/yppasswdd_server.c Wed Apr 18 18:54:22 2001 @@ -62,11 +62,6 @@ #include "yppasswd.h" #include "yppasswd_private.h" -struct cmessage { - struct cmsghdr cmsg; - struct cmsgcred cmcred; -}; - char *tempname; void reaper(sig) @@ -705,47 +700,43 @@ static int result; int pfd, tfd; int pid; + uid_t uid; int rval = 0; DBT key, data; char *passfile_hold; char passfile_buf[MAXPATHLEN + 2]; struct sockaddr_in *rqhost; - struct cmessage *cm; - SVCXPRT *transp; + SVCXPRT *transp; result = 1; + transp = rqstp->rq_xprt; /* * NO AF_INET CONNETCIONS ALLOWED! */ - rqhost = svc_getcaller(rqstp->rq_xprt); + rqhost = svc_getcaller(transp); if (rqhost->sin_family != AF_UNIX) { yp_error("Alert! %s/%d attempted to use superuser-only \ procedure!\n", inet_ntoa(rqhost->sin_addr), rqhost->sin_port); - svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED); + svcerr_auth(transp, AUTH_BADCRED); return(&result); } - transp = rqstp->rq_xprt; - - if (transp->xp_verf.oa_length < sizeof(struct cmessage) || - transp->xp_verf.oa_base == NULL || - transp->xp_verf.oa_flavor != AUTH_UNIX) { + if (rqstp->rq_cred.oa_flavor != AUTH_SYS) { yp_error("caller didn't send proper credentials"); - svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED); + svcerr_auth(transp, AUTH_BADCRED); return(&result); } - cm = (struct cmessage *)transp->xp_verf.oa_base; - if (cm->cmsg.cmsg_type != SCM_CREDS) { + if (__rpc_get_local_uid(transp, &uid) < 0) { yp_error("caller didn't send proper credentials"); - svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED); + svcerr_auth(transp, AUTH_BADCRED); return(&result); } - - if (cm->cmcred.cmcred_euid) { + + if (uid) { yp_error("caller euid is %d, expecting 0 -- rejecting request", - cm->cmcred.cmcred_euid); + uid); svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED); return(&result); } Last modified: 2001-10-06 02:00 Changed files: usr.bin/chpass/pw_yp.c usr.bin/passwd/yp_passwd.c lib/libc/rpc/crypt_client.c usr.bin/rpcinfo/rpcinfo.c Commment: The clnt_create(KEYSERVSOCK, CRYPT_PROG, CRYPT_VERS, "unix") hacks were removed and replaced them with clnt_tp_create, now the af_local support is fixed. I also removed the hack how rpcinfo contacted rpcbind, now we can relay on clnt_tp_create create the client-handle for us. Only rpcbind itself needs a hardcoded socket-path. Index: lib/libc/rpc/crypt_client.c =================================================================== RCS file: /usr/home/ncvs/src/lib/libc/rpc/crypt_client.c,v retrieving revision 1.5 diff -u -r1.5 crypt_client.c --- lib/libc/rpc/crypt_client.c 19 Mar 2001 12:49:50 -0000 1.5 +++ lib/libc/rpc/crypt_client.c 5 Oct 2001 23:47:51 -0000 @@ -42,10 +42,6 @@ static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/crypt_client.c,v 1.5 2001/03/19 12:49:50 alfred Exp $"; #endif -#ifndef KEYSERVSOCK -#define KEYSERVSOCK "/var/run/keyservsock" -#endif - int _des_crypt_call(buf, len, dparms) char *buf; @@ -55,12 +51,27 @@ CLIENT *clnt; desresp *result_1; desargs des_crypt_1_arg; - int stat; + struct netconfig *nconf; + void *localhandle; + int stat; - clnt = clnt_create(KEYSERVSOCK, CRYPT_PROG, CRYPT_VERS, "unix"); + nconf = NULL; + localhandle = setnetconfig(); + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } + if (nconf == NULL) { + warnx("getnetconfig: %s", nc_sperror()); + return(DESERR_HWERROR); + } + clnt = clnt_tp_create(NULL, CRYPT_PROG, CRYPT_VERS, nconf); if (clnt == (CLIENT *) NULL) { + endnetconfig(localhandle); return(DESERR_HWERROR); } + endnetconfig(localhandle); des_crypt_1_arg.desbuf.desbuf_len = len; des_crypt_1_arg.desbuf.desbuf_val = buf; Index: usr.bin/chpass/pw_yp.c =================================================================== RCS file: /usr/home/ncvs/src/usr.bin/chpass/pw_yp.c,v retrieving revision 1.16 diff -u -r1.16 pw_yp.c --- usr.bin/chpass/pw_yp.c 20 Oct 1999 15:20:00 -0000 1.16 +++ usr.bin/chpass/pw_yp.c 5 Oct 2001 23:47:51 -0000 @@ -354,7 +354,6 @@ char *mastername; int rval, localport; struct stat st; - char *sockname = YP_SOCKNAME; /* * Sometimes we are called just to probe for rpc.yppasswdd and @@ -407,7 +406,7 @@ /* See if _we_ are the master server. */ if (!force_old && !getuid() && (localport = getrpcport("localhost", YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP)) != 0) { - if (localport == rval && stat(sockname, &st) != -1) { + if (localport == rval) { suser_override = 1; mastername = "localhost"; } @@ -433,12 +432,14 @@ { struct yppasswd yppasswd; struct master_yppasswd master_yppasswd; + struct netconfig *nconf; + void *localhandle; CLIENT *clnt; char *master, *password; int *status = NULL; struct rpc_err err; - char *sockname = YP_SOCKNAME; + nconf = NULL; _use_yp = 1; /* Get NIS master server name */ @@ -490,13 +491,26 @@ if (suser_override) { /* Talk to server via AF_UNIX socket. */ - clnt = clnt_create(sockname, MASTER_YPPASSWDPROG, - MASTER_YPPASSWDVERS, "unix"); + localhandle = setnetconfig(); + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } + if (nconf == NULL) { + warnx("getnetconfig: %s", nc_sperror()); + pw_error(tempname, 0, 1); + } + + clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG, + MASTER_YPPASSWDVERS, nconf); if (clnt == NULL) { warnx("failed to contact rpc.yppasswdd: %s", clnt_spcreateerror(master)); + endnetconfig(localhandle); pw_error(tempname, 0, 1); } + endnetconfig(localhandle); } else { /* Create a handle to yppasswdd. */ Index: usr.bin/passwd/yp_passwd.c =================================================================== RCS file: /usr/home/ncvs/src/usr.bin/passwd/yp_passwd.c,v retrieving revision 1.15 diff -u -r1.15 yp_passwd.c --- usr.bin/passwd/yp_passwd.c 28 Sep 1997 08:51:02 -0000 1.15 +++ usr.bin/passwd/yp_passwd.c 5 Oct 2001 23:47:51 -0000 @@ -55,14 +55,16 @@ { struct yppasswd yppasswd; struct master_yppasswd master_yppasswd; + struct netconfig *nconf; + void *localhandle; struct passwd *pw; CLIENT *clnt; struct rpc_err err; char *master; int *status = NULL; uid_t uid; - char *sockname = YP_SOCKNAME; + nconf = NULL; _use_yp = 1; uid = getuid(); @@ -144,12 +146,24 @@ } if (suser_override) { - if ((clnt = clnt_create(sockname, MASTER_YPPASSWDPROG, - MASTER_YPPASSWDVERS, "unix")) == NULL) { + localhandle = setnetconfig(); + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } + if (nconf == NULL) { + warnx("getnetconfig: %s", nc_sperror()); + return(1); + } + if ((clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG, + MASTER_YPPASSWDVERS, nconf)) == NULL) { warnx("failed to contact rpc.yppasswdd on host %s: %s", master, clnt_spcreateerror("")); + endnetconfig(localhandle); return(1); } + endnetconfig(localhandle); } else { if ((clnt = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp")) == NULL) { Index: usr.bin/rpcinfo/rpcinfo.c =================================================================== RCS file: /usr/home/ncvs/src/usr.bin/rpcinfo/rpcinfo.c,v retrieving revision 1.11 diff -u -r1.11 rpcinfo.c --- usr.bin/rpcinfo/rpcinfo.c 19 Mar 2001 12:50:04 -0000 1.11 +++ usr.bin/rpcinfo/rpcinfo.c 5 Oct 2001 23:47:51 -0000 @@ -321,22 +321,24 @@ static CLIENT * local_rpcb(u_long prog, u_long vers) { - struct netbuf nbuf; - struct sockaddr_un sun; - int sock; + void *localhandle; + struct netconfig *nconf; + CLIENT *clnt; - memset(&sun, 0, sizeof sun); - sock = socket(AF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) - return NULL; + localhandle = setnetconfig(); + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } + if (nconf == NULL) { + warnx("getnetconfig: %s", nc_sperror()); + return (NULL); + } - sun.sun_family = AF_LOCAL; - strcpy(sun.sun_path, _PATH_RPCBINDSOCK); - nbuf.len = sun.sun_len = SUN_LEN(&sun); - nbuf.maxlen = sizeof (struct sockaddr_un); - nbuf.buf = &sun; - - return clnt_vc_create(sock, &nbuf, prog, vers, 0, 0); + clnt = clnt_tp_create(NULL, prog, vers, nconf); + endnetconfig(localhandle); + return clnt; } #ifdef PORTMAP Do not call addrinfo on local transport adresses, if returning a server handle (for reuse or whatever). We just return now a handle connected to the local rpcbind. Do not try to call checkcache, if host = NULL; For the local transport, fill in the adress of rpcbind. --- lib/libc/rpc/rpcb_clnt.c Mon Apr 2 23:41:43 2001 +++ lib/libc/rpc/rpcb_clnt.c Sat Apr 21 12:54:25 2001 @@ -300,7 +300,9 @@ /* Get the address of the rpcbind. Check cache first */ addr_to_delete.len = 0; rwlock_rdlock(&rpcbaddr_cache_lock); - ad_cache = check_cache(host, nconf->nc_netid); + ad_cache = NULL; + if (host != NULL) + ad_cache = check_cache(host, nconf->nc_netid); if (ad_cache != NULL) { addr = ad_cache->ac_taddr; client = clnt_tli_create(RPC_ANYFD, nconf, addr, @@ -345,9 +347,26 @@ nconf->nc_netid, si.si_af, si.si_proto, si.si_socktype); #endif - if (getaddrinfo(host, "sunrpc", &hints, &res) != 0) { - rpc_createerr.cf_stat = RPC_UNKNOWNHOST; - return NULL; + if (nconf->nc_protofmly != NULL && strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { + client = local_rpcb(); + if (! client) { +#ifdef ND_DEBUG + clnt_pcreateerror("rpcbind clnt interface"); +#endif + return (NULL); + } else { + struct sockaddr_un sun; + + *targaddr = malloc(sizeof(sun.sun_path)); + strncpy(*targaddr, _PATH_RPCBINDSOCK, + sizeof(sun.sun_path)); + return (client); + } + } else { + if (getaddrinfo(host, "sunrpc", &hints, &res) != 0) { + rpc_createerr.cf_stat = RPC_UNKNOWNHOST; + return NULL; + } } for (tres = res; tres != NULL; tres = tres->ai_next) { @@ -392,7 +411,8 @@ break; } } - freeaddrinfo(res); + if (res) + freeaddrinfo(res); return (client); } lib/libc/rpc/svc_vc.c Finally fix the credential stuff. I had to look at the code a long long time before I've seen what exactly was the breakage. In NetBSD, Solaris, xprt->xp_p2 pointed directly to the credentials, in FreeBSD xprt->xp_verf.oa_base was a pointer to a struct cmessage, which is defined as follow: struct cmessage { struct cmsghdr cmsg; struct cmsgcred cmcred; }; The credentials were submitted the right way and xprt->xp_p2 pointed to them. But cb_verf.oa_flavor was still empty. There was an assignment missing in svc_recv() in svc_vc.c: msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX; Also + if (addr.ss_family == AF_LOCAL) { + xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; + xprt->xp_addrlen = sizeof (struct sockaddr_in); + } was missing. But the first seems not to be needed: I guess in rpc.yppasswdd there was a typo: - transp>xp_verf.oa_flavor != AUTH_UNIX) { + rqstp->rq_cred.oa_flavor != AUTH_UNIX) { This little fix does fix the breakage in rpc.yppasswdd :-) + if (msg.msg_controllen == 0 || + (msg.msg_flags & MSG_CTRUNC) != 0) + return (-1); We cannot set the cb_verf.oa_length in svc_recv() of svc_vc.c, the credentials get overwritten then, and that's bad. diff -ruN lib/libc/rpc/svc_vc.c lib/libc/rpc/svc_vc.c --- lib/libc/rpc/svc_vc.c.orig Thu Oct 4 15:11:41 2001 +++ lib/libc/rpc/svc_vc.c Thu Oct 4 20:55:17 2001 @@ -313,6 +313,10 @@ return (FALSE); memcpy(xprt->xp_rtaddr.buf, &addr, len); xprt->xp_rtaddr.len = len; + if (addr.ss_family == AF_LOCAL) { + xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; + xprt->xp_addrlen = sizeof (struct sockaddr_in); + } #ifdef PORTMAP if (addr.ss_family == AF_INET) { xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; @@ -423,13 +427,15 @@ } } while ((pollfd.revents & POLLIN) == 0); + cm = NULL; sa = (struct sockaddr *)xprt->xp_rtaddr.buf; if (sa->sa_family == AF_LOCAL) { cm = (struct cmessage *)xprt->xp_verf.oa_base; if ((len = __msgread_withcred(sock, buf, len, cm)) > 0) { xprt->xp_p2 = &cm->cmcred; return (len); - } + } else + goto fatal_err; } else { if ((len = _read(sock, buf, (size_t)len)) > 0) return (len); @@ -656,7 +663,12 @@ ret = _recvmsg(sock, &msg, 0); bcopy(&cm.cmsg, &cmp->cmsg, sizeof(cmp->cmsg)); bcopy(CMSG_DATA(&cm), &cmp->cmcred, sizeof(cmp->cmcred)); - return ret; + + if (msg.msg_controllen == 0 || + (msg.msg_flags & MSG_CTRUNC) != 0) + return (-1); + + return (ret); } static int @@ -696,10 +708,21 @@ __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid) { struct cmsgcred *cmcred; + struct cmessage *cm; + struct cmsghdr *cmp; + + cm = (struct cmessage *)transp->xp_verf.oa_base; + + if (cm == NULL) + return (-1); + cmp = &cm->cmsg; + if (cmp == NULL || cmp->cmsg_level != SOL_SOCKET || + cmp->cmsg_type != SCM_CREDS) + return (-1); cmcred = __svc_getcallercreds(transp); if (cmcred == NULL) - return(-1); + return (-1); *uid = cmcred->cmcred_euid; - return(0); + return (0); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110070040.f970e1P30686>