rpcsec_gss: Fix a stack overflow in svc_rpc_gss_validate()
svc_rpc_gss_validate() copies the input message into a stack buffer
without ensuring that the buffer is large enough. Sure enough,
oa_length may be up to 400 bytes, much larger than the provided space.
This enables an unauthenticated user to trigger an overflow and obtain
remote code execution.
Add a runtime check which verifies that the copy won't overflow.
Approved by: so
Security: FreeBSD-SA-26:08.rpcsec_gss
Security: CVE-2026-4747
Reported by: Nicholas Carlini <npc@anthropic.com>
Reviewed by: rmacklem
Fixes: a9148abd9d
This commit is contained in:
committed by
Gordon Tetlow
parent
6b2d6ccad2
commit
143293c14f
@@ -758,6 +758,14 @@ svc_rpc_gss_validate(struct svc_rpc_gss_client *client, struct rpc_msg *msg,
|
||||
|
||||
memset(rpchdr, 0, sizeof(rpchdr));
|
||||
|
||||
oa = &msg->rm_call.cb_cred;
|
||||
|
||||
if (oa->oa_length > sizeof(rpchdr) - 8 * BYTES_PER_XDR_UNIT) {
|
||||
log_debug("auth length %d exceeds maximum", oa->oa_length);
|
||||
client->cl_state = CLIENT_STALE;
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* Reconstruct RPC header for signing (from xdr_callmsg). */
|
||||
buf = rpchdr;
|
||||
IXDR_PUT_LONG(buf, msg->rm_xid);
|
||||
@@ -766,7 +774,6 @@ svc_rpc_gss_validate(struct svc_rpc_gss_client *client, struct rpc_msg *msg,
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_prog);
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_vers);
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
|
||||
oa = &msg->rm_call.cb_cred;
|
||||
IXDR_PUT_ENUM(buf, oa->oa_flavor);
|
||||
IXDR_PUT_LONG(buf, oa->oa_length);
|
||||
if (oa->oa_length) {
|
||||
|
||||
@@ -1170,6 +1170,15 @@ svc_rpc_gss_validate(struct svc_rpc_gss_client *client, struct rpc_msg *msg,
|
||||
|
||||
memset(rpchdr, 0, sizeof(rpchdr));
|
||||
|
||||
oa = &msg->rm_call.cb_cred;
|
||||
|
||||
if (oa->oa_length > sizeof(rpchdr) - 8 * BYTES_PER_XDR_UNIT) {
|
||||
rpc_gss_log_debug("auth length %d exceeds maximum",
|
||||
oa->oa_length);
|
||||
client->cl_state = CLIENT_STALE;
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* Reconstruct RPC header for signing (from xdr_callmsg). */
|
||||
buf = rpchdr;
|
||||
IXDR_PUT_LONG(buf, msg->rm_xid);
|
||||
@@ -1178,7 +1187,6 @@ svc_rpc_gss_validate(struct svc_rpc_gss_client *client, struct rpc_msg *msg,
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_prog);
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_vers);
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
|
||||
oa = &msg->rm_call.cb_cred;
|
||||
IXDR_PUT_ENUM(buf, oa->oa_flavor);
|
||||
IXDR_PUT_LONG(buf, oa->oa_length);
|
||||
if (oa->oa_length) {
|
||||
|
||||
Reference in New Issue
Block a user