Date: Thu, 26 Mar 2026 01:13:36 +0000 From: Gordon Tetlow <gordon@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Mark Johnston <markj@FreeBSD.org> Subject: git: 143293c14f8d - main - rpcsec_gss: Fix a stack overflow in svc_rpc_gss_validate() Message-ID: <69c48840.196b8.4cad278a@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by gordon: URL: https://cgit.FreeBSD.org/src/commit/?id=143293c14f8de00c6d3de88cd23fc224e7014206 commit 143293c14f8de00c6d3de88cd23fc224e7014206 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2026-03-24 02:12:42 +0000 Commit: Gordon Tetlow <gordon@FreeBSD.org> CommitDate: 2026-03-26 01:11:54 +0000 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: a9148abd9da5d --- lib/librpcsec_gss/svc_rpcsec_gss.c | 9 ++++++++- sys/rpc/rpcsec_gss/svc_rpcsec_gss.c | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/librpcsec_gss/svc_rpcsec_gss.c b/lib/librpcsec_gss/svc_rpcsec_gss.c index e9d39a813f86..73b92371e6d0 100644 --- a/lib/librpcsec_gss/svc_rpcsec_gss.c +++ b/lib/librpcsec_gss/svc_rpcsec_gss.c @@ -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) { diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c index 35c904560836..528112d5642a 100644 --- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c @@ -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) {home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69c48840.196b8.4cad278a>
