summaryrefslogtreecommitdiffstats
path: root/lib/libc/rpc/clnt_udp.c
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1997-10-26 18:47:31 +0000
committerwpaul <wpaul@FreeBSD.org>1997-10-26 18:47:31 +0000
commit82b1cd0f1b7bd003fd7721046bca81fccf6fbeec (patch)
tree3293c7d54342ffdc225cd4dccf00f943d52c4173 /lib/libc/rpc/clnt_udp.c
parent137f5fa8c3407e1bb60007d5d8f99ab4b6d3a8b1 (diff)
downloadFreeBSD-src-82b1cd0f1b7bd003fd7721046bca81fccf6fbeec.zip
FreeBSD-src-82b1cd0f1b7bd003fd7721046bca81fccf6fbeec.tar.gz
In clntudp_call(), it is possible that xdr_replymsg() might fail
partway through its attempt to decode the result structure sent by the server. If this happens, it can leave the result partially populated with dynamically allocated memory. In this event, the xdr_replymsg() failure is detected and RPC_CANTDECODERES is returned, but the memory in the partially populated result struct is not free()d. The end result is that memory is leaked when an RPC_CANTDECODERES error occurs. (This condition can occur if a CLIENT * handle is created using clntudp_bufcreate() with a receive buffer size that is too small to handle the result sent by the server.) Fixed by setting reply_xdrs.x_op to XDR_FREE and calling xdr_replymsg() again to free the memory if an RPC_CANTDECODERES error is detected. I suspect that the clnt_tcp.c, clnt_unix.c and clnt_raw.c modules may ha a similar problem, but I haven't duplicated the condition with those yet. Found by: dbmalloc
Diffstat (limited to 'lib/libc/rpc/clnt_udp.c')
-rw-r--r--lib/libc/rpc/clnt_udp.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/libc/rpc/clnt_udp.c b/lib/libc/rpc/clnt_udp.c
index 035ce96..3532849 100644
--- a/lib/libc/rpc/clnt_udp.c
+++ b/lib/libc/rpc/clnt_udp.c
@@ -382,6 +382,20 @@ send_again:
} /* end of unsuccessful completion */
} /* end of valid reply message */
else {
+ /*
+ * It's possible for xdr_replymsg() to fail partway
+ * through its attempt to decode the result from the
+ * server. If this happens, it will leave the reply
+ * structure partially populated with dynamically
+ * allocated memory. (This can happen if someone uses
+ * clntudp_bufcreate() to create a CLIENT handle and
+ * specifies a receive buffer size that is too small.)
+ * This memory must be free()ed to avoid a leak.
+ */
+ int op = reply_xdrs.x_op;
+ reply_xdrs.x_op = XDR_FREE;
+ xdr_replymsg(&reply_xdrs, &reply_msg);
+ reply_xdrs.x_op = op;
cu->cu_error.re_status = RPC_CANTDECODERES;
}
if (fds != &readfds)
OpenPOWER on IntegriCloud