Module Name: src Committed By: christos Date: Mon Mar 4 17:29:03 UTC 2013
Modified Files: src/include/rpc: svc.h src/lib/libc/rpc: rpc_soc.3 rpc_svc_reg.3 svc.c svc_dg.c svc_raw.c svc_vc.c Log Message: PR/47617: Thorsten Brehm: Memory and socket leak in librpc To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/include/rpc/svc.h cvs rdiff -u -r1.13 -r1.14 src/lib/libc/rpc/rpc_soc.3 cvs rdiff -u -r1.9 -r1.10 src/lib/libc/rpc/rpc_svc_reg.3 cvs rdiff -u -r1.31 -r1.32 src/lib/libc/rpc/svc.c cvs rdiff -u -r1.14 -r1.15 src/lib/libc/rpc/svc_dg.c cvs rdiff -u -r1.22 -r1.23 src/lib/libc/rpc/svc_raw.c cvs rdiff -u -r1.27 -r1.28 src/lib/libc/rpc/svc_vc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/include/rpc/svc.h diff -u src/include/rpc/svc.h:1.24 src/include/rpc/svc.h:1.25 --- src/include/rpc/svc.h:1.24 Tue Aug 30 13:06:20 2011 +++ src/include/rpc/svc.h Mon Mar 4 12:29:03 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: svc.h,v 1.24 2011/08/30 17:06:20 plunky Exp $ */ +/* $NetBSD: svc.h,v 1.25 2013/03/04 17:29:03 christos Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -221,7 +221,7 @@ __END_DECLS * SVCXPRT *xprt; */ __BEGIN_DECLS -extern void xprt_register (SVCXPRT *); +extern bool_t xprt_register (SVCXPRT *); __END_DECLS /* Index: src/lib/libc/rpc/rpc_soc.3 diff -u src/lib/libc/rpc/rpc_soc.3:1.13 src/lib/libc/rpc/rpc_soc.3:1.14 --- src/lib/libc/rpc/rpc_soc.3:1.13 Sat Jan 10 21:46:29 2009 +++ src/lib/libc/rpc/rpc_soc.3 Mon Mar 4 12:29:03 2013 @@ -1,5 +1,5 @@ .\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI -.\" $NetBSD: rpc_soc.3,v 1.13 2009/01/11 02:46:29 christos Exp $ +.\" $NetBSD: rpc_soc.3,v 1.14 2013/03/04 17:29:03 christos Exp $ .\" Converted to mdoc by Thomas Klausner <w...@netbsd.org> .\" .Dd December 12, 2008 @@ -221,7 +221,7 @@ .Fn xdr_rejected_reply "XDR *xdrs" "struct rejected_reply *rr" .Ft int .Fn xdr_replymsg "XDR *xdrs" "struct rpc_msg *rmsg" -.Ft void +.Ft bool_t .Fn xprt_register "SVCXPRT *xprt" .Ft void .Fn xprt_unregister "SVCXPRT *xprt" Index: src/lib/libc/rpc/rpc_svc_reg.3 diff -u src/lib/libc/rpc/rpc_svc_reg.3:1.9 src/lib/libc/rpc/rpc_svc_reg.3:1.10 --- src/lib/libc/rpc/rpc_svc_reg.3:1.9 Wed Mar 11 09:36:01 2009 +++ src/lib/libc/rpc/rpc_svc_reg.3 Mon Mar 4 12:29:03 2013 @@ -2,7 +2,7 @@ .\" Copyright 1989 AT&T .\" @(#)rpc_svc_call 1.6 89/07/20 SMI; .\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. -.\" $NetBSD: rpc_svc_reg.3,v 1.9 2009/03/11 13:36:01 joerg Exp $ +.\" $NetBSD: rpc_svc_reg.3,v 1.10 2013/03/04 17:29:03 christos Exp $ .Dd May 3, 1993 .Dt RPC_SVC_REG 3 .Os @@ -27,7 +27,7 @@ .Fn svc_unreg "const rpcprog_t prognum" "const rpcvers_t versnum" .Ft int .Fn svc_auth_reg "const int cred_flavor" "const enum auth_stat (*handler(struct svc_req *, struct rpc_msg *))" -.Ft void +.Ft bool_t .Fn xprt_register "const SVCXPRT *xprt" .Ft void .Fn xprt_unregister "const SVCXPRT *xprt" Index: src/lib/libc/rpc/svc.c diff -u src/lib/libc/rpc/svc.c:1.31 src/lib/libc/rpc/svc.c:1.32 --- src/lib/libc/rpc/svc.c:1.31 Tue Mar 20 13:14:50 2012 +++ src/lib/libc/rpc/svc.c Mon Mar 4 12:29:03 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: svc.c,v 1.31 2012/03/20 17:14:50 matt Exp $ */ +/* $NetBSD: svc.c,v 1.32 2013/03/04 17:29:03 christos Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC"; #else -__RCSID("$NetBSD: svc.c,v 1.31 2012/03/20 17:14:50 matt Exp $"); +__RCSID("$NetBSD: svc.c,v 1.32 2013/03/04 17:29:03 christos Exp $"); #endif #endif @@ -125,7 +125,7 @@ static void __xprt_do_unregister(SVCXPRT /* * Activate a transport handle. */ -void +bool_t xprt_register(SVCXPRT *xprt) { int sock; @@ -138,18 +138,25 @@ xprt_register(SVCXPRT *xprt) if (__svc_xports == NULL) { __svc_xports = mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); if (__svc_xports == NULL) { - warn("xprt_register"); + warn("%s: out of memory", __func__); goto out; } memset(__svc_xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *)); } - if (sock < FD_SETSIZE) { - __svc_xports[sock] = xprt; - FD_SET(sock, &svc_fdset); - svc_maxfd = max(svc_maxfd, sock); - } + if (sock >= FD_SETSIZE) { + warnx("%s: socket descriptor %d too large for setsize %u", + __func__, sock, (unsigned)FD_SETSIZE); + goto out; + } + __svc_xports[sock] = xprt; + FD_SET(sock, &svc_fdset); + svc_maxfd = max(svc_maxfd, sock); + rwlock_unlock(&svc_fd_lock); + return (TRUE); + out: rwlock_unlock(&svc_fd_lock); + return (FALSE); } void Index: src/lib/libc/rpc/svc_dg.c diff -u src/lib/libc/rpc/svc_dg.c:1.14 src/lib/libc/rpc/svc_dg.c:1.15 --- src/lib/libc/rpc/svc_dg.c:1.14 Tue Mar 20 13:14:50 2012 +++ src/lib/libc/rpc/svc_dg.c Mon Mar 4 12:29:03 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_dg.c,v 1.14 2012/03/20 17:14:50 matt Exp $ */ +/* $NetBSD: svc_dg.c,v 1.15 2013/03/04 17:29:03 christos Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -44,7 +44,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: svc_dg.c,v 1.14 2012/03/20 17:14:50 matt Exp $"); +__RCSID("$NetBSD: svc_dg.c,v 1.15 2013/03/04 17:29:03 christos Exp $"); #endif #include "namespace.h" @@ -128,15 +128,15 @@ svc_dg_create(int fd, u_int sendsize, u_ xprt = mem_alloc(sizeof (SVCXPRT)); if (xprt == NULL) - goto freedata; + goto outofmem; memset(xprt, 0, sizeof (SVCXPRT)); su = mem_alloc(sizeof (*su)); if (su == NULL) - goto freedata; + goto outofmem; su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4; if ((rpc_buffer(xprt) = malloc(su->su_iosz)) == NULL) - goto freedata; + goto outofmem; _DIAGASSERT(__type_fit(u_int, su->su_iosz)); xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), (u_int)su->su_iosz, XDR_DECODE); @@ -149,16 +149,19 @@ svc_dg_create(int fd, u_int sendsize, u_ slen = sizeof ss; if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) - goto freedata; + goto outofmem; xprt->xp_ltaddr.buf = mem_alloc(sizeof (struct sockaddr_storage)); xprt->xp_ltaddr.maxlen = sizeof (struct sockaddr_storage); xprt->xp_ltaddr.len = slen; memcpy(xprt->xp_ltaddr.buf, &ss, slen); - xprt_register(xprt); + if (!xprt_register(xprt)) + goto freedata; return (xprt); -freedata: + +outofmem: (void) warnx(svc_dg_str, __no_mem_str); +freedata: if (xprt) { if (su) (void) mem_free(su, sizeof (*su)); Index: src/lib/libc/rpc/svc_raw.c diff -u src/lib/libc/rpc/svc_raw.c:1.22 src/lib/libc/rpc/svc_raw.c:1.23 --- src/lib/libc/rpc/svc_raw.c:1.22 Tue Mar 20 13:14:50 2012 +++ src/lib/libc/rpc/svc_raw.c Mon Mar 4 12:29:03 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_raw.c,v 1.22 2012/03/20 17:14:50 matt Exp $ */ +/* $NetBSD: svc_raw.c,v 1.23 2013/03/04 17:29:03 christos Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -39,7 +39,7 @@ #if 0 static char sccsid[] = "@(#)svc_raw.c 1.25 89/01/31 Copyr 1984 Sun Micro"; #else -__RCSID("$NetBSD: svc_raw.c,v 1.22 2012/03/20 17:14:50 matt Exp $"); +__RCSID("$NetBSD: svc_raw.c,v 1.23 2013/03/04 17:29:03 christos Exp $"); #endif #endif @@ -117,7 +117,8 @@ svc_raw_create(void) svc_raw_ops(&srp->server); srp->server.xp_verf.oa_base = srp->verf_body; xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE); - xprt_register(&srp->server); + if (!xprt_register(&srp->server)) + goto out; mutex_unlock(&svcraw_lock); return (&srp->server); out: Index: src/lib/libc/rpc/svc_vc.c diff -u src/lib/libc/rpc/svc_vc.c:1.27 src/lib/libc/rpc/svc_vc.c:1.28 --- src/lib/libc/rpc/svc_vc.c:1.27 Mon Mar 4 12:17:56 2013 +++ src/lib/libc/rpc/svc_vc.c Mon Mar 4 12:29:03 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: svc_vc.c,v 1.27 2013/03/04 17:17:56 christos Exp $ */ +/* $NetBSD: svc_vc.c,v 1.28 2013/03/04 17:29:03 christos Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -35,7 +35,7 @@ static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; #else -__RCSID("$NetBSD: svc_vc.c,v 1.27 2013/03/04 17:17:56 christos Exp $"); +__RCSID("$NetBSD: svc_vc.c,v 1.28 2013/03/04 17:29:03 christos Exp $"); #endif #endif @@ -188,7 +188,8 @@ svc_vc_create(int fd, u_int sendsize, u_ memcpy(xprt->xp_ltaddr.buf, &sslocal, (size_t)sslocal.ss_len); xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage); - xprt_register(xprt); + if (!xprt_register(xprt)) + goto cleanup_svc_vc_create; return xprt; cleanup_svc_vc_create: if (xprt) @@ -268,11 +269,11 @@ makefd_xprt(int fd, u_int sendsize, u_in xprt = mem_alloc(sizeof(SVCXPRT)); if (xprt == NULL) - goto out; + goto outofmem; memset(xprt, 0, sizeof *xprt); cd = mem_alloc(sizeof(struct cf_conn)); if (cd == NULL) - goto out; + goto outofmem; cd->strm_stat = XPRT_IDLE; xdrrec_create(&(cd->xdrs), sendsize, recvsize, (caddr_t)(void *)xprt, read_vc, write_vc); @@ -283,12 +284,15 @@ makefd_xprt(int fd, u_int sendsize, u_in xprt->xp_fd = fd; if (__rpc_fd2sockinfo(fd, &si) && __rpc_sockinfo2netid(&si, &netid)) if ((xprt->xp_netid = strdup(netid)) == NULL) - goto out; + goto outofmem; - xprt_register(xprt); + if (!xprt_register(xprt)) + goto out; return xprt; -out: + +outofmem: warn("svc_tcp: makefd_xprt"); +out: if (xprt) mem_free(xprt, sizeof(SVCXPRT)); return NULL;