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 <[email protected]>
.\"
.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;