call_arg on error, since svc_getargs should do that now.
* svc_udp.c (svcudp_getargs): Free args on xdr decode error to
avoid leaks.
* svc_tcp.c (svctcp_getargs): Free args on xdr decode error to
avoid leaks.
* svc_raw.c (svcraw_getargs): Free args on xdr decode error to
avoid leaks.
* auth_gssapi.c (auth_gssapi_create): Don't explicitly free
call_res anymore, since clnt_call should deal now.
* clnt_udp.c (clntudp_call): Free stuff on error from
xdr_replymsg() to prevent leaking.
* clnt_tcp.c (clnttcp_call): Free stuff on error from
xdr_replymsg() to avoid leaking.
* clnt_raw.c (clntraw_call): Free stuff on error from
xdr_replymsg() to avoid leaking.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12052
dc483132-0cff-0310-8789-
dd5450dbe970
+2000-02-17 Tom Yu <tlyu@mit.edu>
+
+ * svc_auth_gssapi.c (_svcauth_gssapi): Don't explicitly free
+ call_arg on error, since svc_getargs should do that now.
+
+ * svc_udp.c (svcudp_getargs): Free args on xdr decode error to
+ avoid leaks.
+
+ * svc_tcp.c (svctcp_getargs): Free args on xdr decode error to
+ avoid leaks.
+
+ * svc_raw.c (svcraw_getargs): Free args on xdr decode error to
+ avoid leaks.
+
+ * auth_gssapi.c (auth_gssapi_create): Don't explicitly free
+ call_res anymore, since clnt_call should deal now.
+
+ * clnt_udp.c (clntudp_call): Free stuff on error from
+ xdr_replymsg() to prevent leaking.
+
+ * clnt_tcp.c (clnttcp_call): Free stuff on error from
+ xdr_replymsg() to avoid leaking.
+
+ * clnt_raw.c (clntraw_call): Free stuff on error from
+ xdr_replymsg() to avoid leaking.
+
2000-02-16 Tom Yu <tlyu@mit.edu>
* auth_gssapi.c (auth_gssapi_create): Free call_res because
if (callstat != RPC_SUCCESS) {
struct rpc_err err;
- xdr_free(xdr_authgssapi_init_res, &call_res);
clnt_geterr(clnt, &err);
if (callstat == RPC_AUTHERROR &&
(err.re_why == AUTH_BADCRED || err.re_why == AUTH_FAILED)
msg.acpted_rply.ar_verf = _null_auth;
msg.acpted_rply.ar_results.where = resultsp;
msg.acpted_rply.ar_results.proc = xresults;
- if (! xdr_replymsg(xdrs, &msg))
+ if (! xdr_replymsg(xdrs, &msg)) {
+ /*
+ * 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 = xdrs->x_op;
+ xdrs->x_op = XDR_FREE;
+ xdr_replymsg(xdrs, &msg);
+ xdrs->x_op = op;
return (RPC_CANTDECODERES);
+ }
sunrpc_seterr_reply(&msg, &error);
status = error.re_status;
return (ct->ct_error.re_status);
/* now decode and validate the response header */
if (! xdr_replymsg(xdrs, &reply_msg)) {
+ /*
+ * Free some stuff allocated by xdr_replymsg()
+ * to avoid leaks, since it may allocate
+ * memory from partially successful decodes.
+ */
+ int op = xdrs->x_op;
+ xdrs->x_op = XDR_FREE;
+ xdr_replymsg(xdrs, &reply_msg);
+ xdrs->x_op = op;
if (ct->ct_error.re_status == RPC_SUCCESS)
continue;
return (ct->ct_error.re_status);
}
} /* 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;
+ return (RPC_CANTDECODERES);
cu->cu_error.re_status = RPC_CANTDECODERES;
}
return (cu->cu_error.re_status);
&call_arg)) {
PRINTF(("svcauth_gssapi: cannot decode args\n"));
LOG_MISCERR("protocol error in procedure arguments");
- xdr_free(xdr_authgssapi_init_arg, &call_arg);
ret = AUTH_BADCRED;
goto error;
}
if (srp == 0)
return (FALSE);
- return ((*xdr_args)(&srp->xdr_stream, args_ptr));
+ if (! (*xdr_args)(&srp->xdr_stream, args_ptr)) {
+ (void)svcraw_freeargs(xprt, xdr_args, args_ptr);
+ return FALSE;
+ }
+ return TRUE;
}
static bool_t
xdrproc_t xdr_args;
caddr_t args_ptr;
{
- return (SVCAUTH_UNWRAP(xprt->xp_auth,
- &(((struct tcp_conn *)(xprt->xp_p1))->xdrs),
- xdr_args, args_ptr));
+ if (! SVCAUTH_UNWRAP(xprt->xp_auth,
+ &(((struct tcp_conn *)(xprt->xp_p1))->xdrs),
+ xdr_args, args_ptr)) {
+ (void)svctcp_freeargs(xprt, xdr_args, args_ptr);
+ return FALSE;
+ }
+ return TRUE;
}
static bool_t
xdrproc_t xdr_args;
caddr_t args_ptr;
{
- return (SVCAUTH_UNWRAP(xprt->xp_auth, &(su_data(xprt)->su_xdrs),
- xdr_args, args_ptr));
+ if (! SVCAUTH_UNWRAP(xprt->xp_auth, &(su_data(xprt)->su_xdrs),
+ xdr_args, args_ptr)) {
+ (void)svcudp_freeargs(xprt, xdr_args, args_ptr);
+ return FALSE;
+ }
+ return TRUE;
}
static bool_t