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;

Reply via email to