| From 4e661f0085ec5f969c76c0896a34322c6c432de4 Mon Sep 17 00:00:00 2001 |
| From: Greg Hudson <ghudson@mit.edu> |
| Date: Mon, 17 Oct 2022 20:25:11 -0400 |
| Subject: [PATCH] Fix integer overflows in PAC parsing |
| |
| In krb5_parse_pac(), check for buffer counts large enough to threaten |
| integer overflow in the header length and memory length calculations. |
| Avoid potential integer overflows when checking the length of each |
| buffer. Credit to OSS-Fuzz for discovering one of the issues. |
| |
| CVE-2022-42898: |
| |
| In MIT krb5 releases 1.8 and later, an authenticated attacker may be |
| able to cause a KDC or kadmind process to crash by reading beyond the |
| bounds of allocated memory, creating a denial of service. A |
| privileged attacker may similarly be able to cause a Kerberos or GSS |
| application service to crash. On 32-bit platforms, an attacker can |
| also cause insufficient memory to be allocated for the result, |
| potentially leading to remote code execution in a KDC, kadmind, or GSS |
| or Kerberos application server process. An attacker with the |
| privileges of a cross-realm KDC may be able to extract secrets from a |
| KDC process's memory by having them copied into the PAC of a new |
| ticket. |
| |
| (cherry picked from commit ea92d2f0fcceb54a70910fa32e9a0d7a5afc3583) |
| |
| ticket: 9074 |
| version_fixed: 1.19.4 |
| |
| Upstream-Status: Backport [https://github.com/krb5/krb5/commit/4e661f0085ec5f969c76c0896a34322c6c432de4] |
| CVE: CVE-2022-42898 |
| Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> |
| --- |
| src/lib/krb5/krb/pac.c | 9 +++++++-- |
| src/lib/krb5/krb/t_pac.c | 18 ++++++++++++++++++ |
| 2 files changed, 25 insertions(+), 2 deletions(-) |
| |
| diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c |
| index cc74f37..70428a1 100644 |
| --- a/src/lib/krb5/krb/pac.c |
| +++ b/src/lib/krb5/krb/pac.c |
| @@ -27,6 +27,8 @@ |
| #include "k5-int.h" |
| #include "authdata.h" |
| |
| +#define MAX_BUFFERS 4096 |
| + |
| /* draft-brezak-win2k-krb-authz-00 */ |
| |
| /* |
| @@ -316,6 +318,9 @@ krb5_pac_parse(krb5_context context, |
| if (version != 0) |
| return EINVAL; |
| |
| + if (cbuffers < 1 || cbuffers > MAX_BUFFERS) |
| + return ERANGE; |
| + |
| header_len = PACTYPE_LENGTH + (cbuffers * PAC_INFO_BUFFER_LENGTH); |
| if (len < header_len) |
| return ERANGE; |
| @@ -348,8 +353,8 @@ krb5_pac_parse(krb5_context context, |
| krb5_pac_free(context, pac); |
| return EINVAL; |
| } |
| - if (buffer->Offset < header_len || |
| - buffer->Offset + buffer->cbBufferSize > len) { |
| + if (buffer->Offset < header_len || buffer->Offset > len || |
| + buffer->cbBufferSize > len - buffer->Offset) { |
| krb5_pac_free(context, pac); |
| return ERANGE; |
| } |
| diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c |
| index 7b756a2..2353e9f 100644 |
| --- a/src/lib/krb5/krb/t_pac.c |
| +++ b/src/lib/krb5/krb/t_pac.c |
| @@ -431,6 +431,16 @@ static const unsigned char s4u_pac_ent_xrealm[] = { |
| 0x8a, 0x81, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x00 |
| }; |
| |
| +static const unsigned char fuzz1[] = { |
| + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, |
| + 0x06, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf5 |
| +}; |
| + |
| +static const unsigned char fuzz2[] = { |
| + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, |
| + 0x20, 0x20 |
| +}; |
| + |
| static const char *s4u_principal = "w2k8u@ACME.COM"; |
| static const char *s4u_enterprise = "w2k8u@abc@ACME.COM"; |
| |
| @@ -646,6 +656,14 @@ main(int argc, char **argv) |
| krb5_free_principal(context, sep); |
| } |
| |
| + /* Check problematic PACs found by fuzzing. */ |
| + ret = krb5_pac_parse(context, fuzz1, sizeof(fuzz1), &pac); |
| + if (!ret) |
| + err(context, ret, "krb5_pac_parse should have failed"); |
| + ret = krb5_pac_parse(context, fuzz2, sizeof(fuzz2), &pac); |
| + if (!ret) |
| + err(context, ret, "krb5_pac_parse should have failed"); |
| + |
| /* |
| * Test empty free |
| */ |
| -- |
| 2.25.1 |
| |