summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2014-06-19 13:49:16 -0400
committerTom Yu <tlyu@mit.edu>2014-06-26 11:34:42 -0400
commitfb99962cbd063ac04c9a9d2cc7c75eab73f3533d (patch)
tree0314a64e6f02e1c948378adc752ea8bd50dc8953 /src
parent0f46175d632ae03ab7d4cfba5e62534d31e128e0 (diff)
downloadkrb5-fb99962cbd063ac04c9a9d2cc7c75eab73f3533d.tar.gz
krb5-fb99962cbd063ac04c9a9d2cc7c75eab73f3533d.tar.xz
krb5-fb99962cbd063ac04c9a9d2cc7c75eab73f3533d.zip
Handle invalid RFC 1964 tokens [CVE-2014-4341...]
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] ticket: 7949 (new) subject: Handle invalid RFC 1964 tokens [CVE-2014-4341 CVE-2014-4342] taget_version: 1.12.2 tags: pullup
Diffstat (limited to 'src')
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c41
-rw-r--r--src/lib/gssapi/krb5/k5unsealiov.c9
2 files changed, 41 insertions, 9 deletions
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index 30c12b91e..057395878 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -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;
@@ -86,6 +87,7 @@ 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) {
@@ -93,18 +95,23 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
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;
@@ -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,
@@ -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) {
@@ -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;
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
index f7828b89a..b654c66c5 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -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;
}