Skip to content

Commit

Permalink
Handle invalid RFC 1964 tokens [CVE-2014-4341...]
Browse files Browse the repository at this point in the history
Detect the following cases which would otherwise cause invalid memory
accesses and/or integer underflow:

* An RFC 1964 token being processed by an RFC 4121-only context
  [CVE-2014-4342]

* A header with fewer than 22 bytes after the token ID or an
  incomplete checksum [CVE-2014-4341 CVE-2014-4342]

* A ciphertext shorter than the confounder [CVE-2014-4341]

* A declared padding length longer than the plaintext [CVE-2014-4341]

If we detect a bad pad byte, continue on to compute the checksum to
avoid creating a padding oracle, but treat the checksum as invalid
even if it compares equal.

CVE-2014-4341:

In MIT krb5, an unauthenticated remote attacker with the ability to
inject packets into a legitimately established GSSAPI application
session can cause a program crash due to invalid memory references
when attempting to read beyond the end of a buffer.

    CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C

CVE-2014-4342:

In MIT krb5 releases krb5-1.7 and later, an unauthenticated remote
attacker with the ability to inject packets into a legitimately
established GSSAPI application session can cause a program crash due
to invalid memory references when reading beyond the end of a buffer
or by causing a null pointer dereference.

    CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C

[tlyu@mit.edu: CVE summaries, CVSS]

(cherry picked from commit fb99962)

ticket: 7949
version_fixed: 1.12.2
status: resolved
  • Loading branch information
greghudson authored and tlyu committed Jun 27, 2014
1 parent e5bb07c commit e6ae703
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 9 deletions.
41 changes: 33 additions & 8 deletions src/lib/gssapi/krb5/k5unseal.c
Expand Up @@ -74,6 +74,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
int conflen = 0;
int signalg;
int sealalg;
int bad_pad = 0;
gss_buffer_desc token;
krb5_checksum cksum;
krb5_checksum md5cksum;
Expand All @@ -86,25 +87,31 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
krb5_ui_4 seqnum;
OM_uint32 retval;
size_t sumlen;
size_t padlen;
krb5_keyusage sign_usage = KG_USAGE_SIGN;

if (toktype == KG_TOK_SEAL_MSG) {
message_buffer->length = 0;
message_buffer->value = NULL;
}

/* get the sign and seal algorithms */

signalg = ptr[0] + (ptr[1]<<8);
sealalg = ptr[2] + (ptr[3]<<8);

/* Sanity checks */

if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
if (ctx->seq == NULL) {
/* ctx was established using a newer enctype, and cannot process RFC
* 1964 tokens. */
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}

if ((bodysize < 22) || (ptr[4] != 0xff) || (ptr[5] != 0xff)) {
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}

signalg = ptr[0] + (ptr[1]<<8);
sealalg = ptr[2] + (ptr[3]<<8);

if ((toktype != KG_TOK_SEAL_MSG) &&
(sealalg != 0xffff)) {
*minor_status = 0;
Expand Down Expand Up @@ -153,6 +160,11 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
return GSS_S_DEFECTIVE_TOKEN;
}

if ((size_t)bodysize < 14 + cksum_len) {
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}

/* get the token parameters */

if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
Expand Down Expand Up @@ -207,7 +219,20 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
plainlen = tmsglen;

conflen = kg_confounder_size(context, ctx->enc->keyblock.enctype);
token.length = tmsglen - conflen - plain[tmsglen-1];
if (tmsglen < conflen) {
if (sealalg != 0xffff)
xfree(plain);
*minor_status = 0;
return(GSS_S_DEFECTIVE_TOKEN);
}
padlen = plain[tmsglen - 1];
if (tmsglen - conflen < padlen) {
/* Don't error out yet, to avoid padding oracle attacks. We will
* treat this as a checksum failure later on. */
padlen = 0;
bad_pad = 1;
}
token.length = tmsglen - conflen - padlen;

if (token.length) {
if ((token.value = (void *) gssalloc_malloc(token.length)) == NULL) {
Expand Down Expand Up @@ -403,7 +428,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,

/* compare the computed checksum against the transmitted checksum */

if (code) {
if (code || bad_pad) {
if (toktype == KG_TOK_SEAL_MSG)
gssalloc_free(token.value);
*minor_status = 0;
Expand Down
9 changes: 8 additions & 1 deletion src/lib/gssapi/krb5/k5unsealiov.c
Expand Up @@ -69,7 +69,14 @@ kg_unseal_v1_iov(krb5_context context,
return GSS_S_DEFECTIVE_TOKEN;
}

if (header->buffer.length < token_wrapper_len + 14) {
if (ctx->seq == NULL) {
/* ctx was established using a newer enctype, and cannot process RFC
* 1964 tokens. */
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}

if (header->buffer.length < token_wrapper_len + 22) {
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
Expand Down

0 comments on commit e6ae703

Please sign in to comment.