krb5 commit [krb5-1.22]: Prevent read overruns in GSSRPC svcauth_unix

ghudson at mit.edu ghudson at mit.edu
Mon Nov 9 12:00:54 EST 2026


https://github.com/krb5/krb5/commit/aca0f70145be03d9eb6acf47be8dece3005846b1
commit aca0f70145be03d9eb6acf47be8dece3005846b1
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.
    
    (cherry picked from commit 964fca13050673c620b3ec0b6fb77af1257eacd5)
    
    ticket: 9234
    version_fixed: 1.22.3

 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