krb5 commit [krb5-1.20]: Fix read overruns in SPNEGO parsing
[email protected] Tue, 11 Jul 2023 18:56:34 -0400 (EDT)
| Newsgroups | gmane.comp.encryption.kerberos.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://github.com/krb5/krb5/commit/eb886f626526769e596443314bcbe4e8bd9d84ee commit eb886f626526769e596443314bcbe4e8bd9d84ee Author: Greg Hudson <[email protected]> Date: Wed Feb 8 12:23:28 2023 -0500 Fix read overruns in SPNEGO parsing Fix three read overruns discovered by the GitHub Security Lab team (GHSL-2023-016, GHSL-2023-017, and GHSL-2023-018) using OSS-Fuzz. In get_mech_set(), error out if gss_add_oid_set_member() fails rather than continue the loop and increment i past the current bound of returned_mechSet. In g_verify_neg_token_init(), check for zero-byte sequences before reading tag bytes, and reduce cur_size by one to account for the tag byte when calling gssint_get_der_length(). (cherry picked from commit 47c2a12830dbd7fb8e13c239ddc0ac74129a91f6) ticket: 9085 version_fixed: 1.20.2 src/lib/gssapi/spnego/spnego_mech.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index ba7765cb4..654964c62 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -3455,7 +3455,7 @@ get_mech_set(OM_uint32 *minor_status, unsigned char **buff_in, unsigned int buff_length) { gss_OID_set returned_mechSet; - OM_uint32 major_status; + OM_uint32 major_status, tmpmin; int length; unsigned int bytes; OM_uint32 set_length; @@ -3485,9 +3485,12 @@ get_mech_set(OM_uint32 *minor_status, unsigned char **buff_in, major_status = gss_add_oid_set_member(minor_status, temp, &returned_mechSet); - if (major_status == GSS_S_COMPLETE) - set_length += returned_mechSet->elements[i].length +2; generic_gss_release_oid(minor_status, &temp); + if (major_status != GSS_S_COMPLETE) { + gss_release_oid_set(&tmpmin, &returned_mechSet); + return (NULL); + } + set_length += returned_mechSet->elements[i].length + 2; } return (returned_mechSet); @@ -4305,7 +4308,8 @@ g_verify_neg_token_init(unsigned char **buf_in, unsigned int cur_size) * - check for a0(context specific identifier) * - get length and verify that enoughd ata exists */ - if (g_get_tag_and_length(&buf, CONTEXT, cur_size, &bytes) < 0) + if (g_get_tag_and_length(&buf, CONTEXT, cur_size, &bytes) < 0 || + bytes == 0) return (G_BAD_TOK_HEADER); cur_size = bytes; /* should indicate bytes remaining */ @@ -4315,7 +4319,7 @@ g_verify_neg_token_init(unsigned char **buf_in, unsigned int cur_size) * a strucure of type NegTokenInit. */ if (*buf++ == SEQUENCE) { - if ((seqsize = gssint_get_der_length(&buf, cur_size, &bytes)) < 0) + if ((seqsize = gssint_get_der_length(&buf, cur_size - 1, &bytes)) <= 0) return (G_BAD_TOK_HEADER); /* * Make sure we have the entire buffer as described @@ -4332,7 +4336,7 @@ g_verify_neg_token_init(unsigned char **buf_in, unsigned int cur_size) * Verify that the first blob is a sequence of mechTypes */ if (*buf++ == CONTEXT) { - if ((seqsize = gssint_get_der_length(&buf, cur_size, &bytes)) < 0) + if ((seqsize = gssint_get_der_length(&buf, cur_size - 1, &bytes)) < 0) return (G_BAD_TOK_HEADER); /* * Make sure we have the entire buffer as described