Skip to content

Commit e6ae703

Browse files
greghudsontlyu
authored andcommitted
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] (cherry picked from commit fb99962) ticket: 7949 version_fixed: 1.12.2 status: resolved
1 parent e5bb07c commit e6ae703

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

Diff for: src/lib/gssapi/krb5/k5unseal.c

+33-8
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
7474
int conflen = 0;
7575
int signalg;
7676
int sealalg;
77+
int bad_pad = 0;
7778
gss_buffer_desc token;
7879
krb5_checksum cksum;
7980
krb5_checksum md5cksum;
@@ -86,25 +87,31 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
8687
krb5_ui_4 seqnum;
8788
OM_uint32 retval;
8889
size_t sumlen;
90+
size_t padlen;
8991
krb5_keyusage sign_usage = KG_USAGE_SIGN;
9092

9193
if (toktype == KG_TOK_SEAL_MSG) {
9294
message_buffer->length = 0;
9395
message_buffer->value = NULL;
9496
}
9597

96-
/* get the sign and seal algorithms */
97-
98-
signalg = ptr[0] + (ptr[1]<<8);
99-
sealalg = ptr[2] + (ptr[3]<<8);
100-
10198
/* Sanity checks */
10299

103-
if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
100+
if (ctx->seq == NULL) {
101+
/* ctx was established using a newer enctype, and cannot process RFC
102+
* 1964 tokens. */
103+
*minor_status = 0;
104+
return GSS_S_DEFECTIVE_TOKEN;
105+
}
106+
107+
if ((bodysize < 22) || (ptr[4] != 0xff) || (ptr[5] != 0xff)) {
104108
*minor_status = 0;
105109
return GSS_S_DEFECTIVE_TOKEN;
106110
}
107111

112+
signalg = ptr[0] + (ptr[1]<<8);
113+
sealalg = ptr[2] + (ptr[3]<<8);
114+
108115
if ((toktype != KG_TOK_SEAL_MSG) &&
109116
(sealalg != 0xffff)) {
110117
*minor_status = 0;
@@ -153,6 +160,11 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
153160
return GSS_S_DEFECTIVE_TOKEN;
154161
}
155162

163+
if ((size_t)bodysize < 14 + cksum_len) {
164+
*minor_status = 0;
165+
return GSS_S_DEFECTIVE_TOKEN;
166+
}
167+
156168
/* get the token parameters */
157169

158170
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,
207219
plainlen = tmsglen;
208220

209221
conflen = kg_confounder_size(context, ctx->enc->keyblock.enctype);
210-
token.length = tmsglen - conflen - plain[tmsglen-1];
222+
if (tmsglen < conflen) {
223+
if (sealalg != 0xffff)
224+
xfree(plain);
225+
*minor_status = 0;
226+
return(GSS_S_DEFECTIVE_TOKEN);
227+
}
228+
padlen = plain[tmsglen - 1];
229+
if (tmsglen - conflen < padlen) {
230+
/* Don't error out yet, to avoid padding oracle attacks. We will
231+
* treat this as a checksum failure later on. */
232+
padlen = 0;
233+
bad_pad = 1;
234+
}
235+
token.length = tmsglen - conflen - padlen;
211236

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

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

406-
if (code) {
431+
if (code || bad_pad) {
407432
if (toktype == KG_TOK_SEAL_MSG)
408433
gssalloc_free(token.value);
409434
*minor_status = 0;

Diff for: src/lib/gssapi/krb5/k5unsealiov.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,14 @@ kg_unseal_v1_iov(krb5_context context,
6969
return GSS_S_DEFECTIVE_TOKEN;
7070
}
7171

72-
if (header->buffer.length < token_wrapper_len + 14) {
72+
if (ctx->seq == NULL) {
73+
/* ctx was established using a newer enctype, and cannot process RFC
74+
* 1964 tokens. */
75+
*minor_status = 0;
76+
return GSS_S_DEFECTIVE_TOKEN;
77+
}
78+
79+
if (header->buffer.length < token_wrapper_len + 22) {
7380
*minor_status = 0;
7481
return GSS_S_DEFECTIVE_TOKEN;
7582
}

0 commit comments

Comments
 (0)