krb5 commit: Prevent read overruns in GSSRPC svcauth_unix
ghudson at mit.edu
ghudson at mit.edu
Mon Nov 9 11:57:03 EST 2026
https://github.com/krb5/krb5/commit/964fca13050673c620b3ec0b6fb77af1257eacd5
commit 964fca13050673c620b3ec0b6fb77af1257eacd5
Author: Greg Hudson <ghudson at mit.edu>
Date: Wed Sep 2 18:54:43 2026 -0400
Prevent read overruns in GSSRPC svcauth_unix
In gssrpc__svcauth_unix(), msg->rm_call.cb_cred.oa_length is only
validated after msg->rm_call.cb_cred.oa_base is parsed, admitting read
overruns if the message is undersized. Replace the retrospective
validation with checks before parsing and after each interior length
is read. Reported by Cem Onat Karagun.
ticket: 9234 (new)
tags: pullup
target_version: 1.22-next
src/lib/rpc/svc_auth_unix.c | 18 +++++-------------
1 file changed, 5 insertions(+), 13 deletions(-)
diff --git a/src/lib/rpc/svc_auth_unix.c b/src/lib/rpc/svc_auth_unix.c
index ee3057ed9..f703a85fe 100644
--- a/src/lib/rpc/svc_auth_unix.c
+++ b/src/lib/rpc/svc_auth_unix.c
@@ -75,14 +75,15 @@ gssrpc__svcauth_unix(
aup->aup_machname = area->area_machname;
aup->aup_gids = area->area_gids;
auth_len = msg->rm_call.cb_cred.oa_length;
- if (auth_len > INT_MAX)
+ if (auth_len < 5 * BYTES_PER_XDR_UNIT || auth_len > INT_MAX)
return AUTH_BADCRED;
xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
buf = XDR_INLINE(&xdrs, (int)auth_len);
if (buf != NULL) {
aup->aup_time = IXDR_GET_LONG(buf);
str_len = IXDR_GET_U_LONG(buf);
- if (str_len > MAX_MACHINE_NAME) {
+ if (str_len > MAX_MACHINE_NAME ||
+ RNDUP(str_len) > auth_len - 5 * BYTES_PER_XDR_UNIT) {
stat = AUTH_BADCRED;
goto done;
}
@@ -93,7 +94,8 @@ gssrpc__svcauth_unix(
aup->aup_uid = IXDR_GET_LONG(buf);
aup->aup_gid = IXDR_GET_LONG(buf);
gid_len = IXDR_GET_U_LONG(buf);
- if (gid_len > NGRPS) {
+ if (gid_len > NGRPS ||
+ gid_len > (auth_len - str_len) / BYTES_PER_XDR_UNIT - 5) {
stat = AUTH_BADCRED;
goto done;
}
@@ -101,16 +103,6 @@ gssrpc__svcauth_unix(
for (i = 0; i < gid_len; i++) {
aup->aup_gids[i] = IXDR_GET_LONG(buf);
}
- /*
- * five is the smallest unix credentials structure -
- * timestamp, hostname len (0), uid, gid, and gids len (0).
- */
- if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
- (void) printf("bad auth_len gid %u str %u auth %u\n",
- gid_len, str_len, auth_len);
- stat = AUTH_BADCRED;
- goto done;
- }
} else if (! xdr_authunix_parms(&xdrs, aup)) {
xdrs.x_op = XDR_FREE;
(void)xdr_authunix_parms(&xdrs, aup);
More information about the cvs-krb5
mailing list