|
| 1 | +From c929e7d18bdd47b9e9316de173359efc76810b29 Mon Sep 17 00:00:00 2001 |
| 2 | +From: ankita <ankitapareek@microsoft.com> |
| 3 | +Date: Mon, 2 Sep 2024 12:34:38 +0530 |
| 4 | +Subject: [PATCH] krb5: Fix CVE-2024-26458 and CVE-2024-26461 |
| 5 | + |
| 6 | +--- |
| 7 | + src/lib/gssapi/krb5/k5sealv3.c | 56 +++++++++++++++------------------- |
| 8 | + src/lib/rpc/pmap_rmt.c | 9 +++--- |
| 9 | + 2 files changed, 29 insertions(+), 36 deletions(-) |
| 10 | + |
| 11 | +diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c |
| 12 | +index 1fcbdfb..d3210c1 100644 |
| 13 | +--- a/src/lib/gssapi/krb5/k5sealv3.c |
| 14 | ++++ b/src/lib/gssapi/krb5/k5sealv3.c |
| 15 | +@@ -65,7 +65,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 16 | + int conf_req_flag, int toktype) |
| 17 | + { |
| 18 | + size_t bufsize = 16; |
| 19 | +- unsigned char *outbuf = 0; |
| 20 | ++ unsigned char *outbuf = NULL; |
| 21 | + krb5_error_code err; |
| 22 | + int key_usage; |
| 23 | + unsigned char acceptor_flag; |
| 24 | +@@ -75,9 +75,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 25 | + #endif |
| 26 | + size_t ec; |
| 27 | + unsigned short tok_id; |
| 28 | +- krb5_checksum sum; |
| 29 | ++ krb5_checksum sum = { 0 }; |
| 30 | + krb5_key key; |
| 31 | + krb5_cksumtype cksumtype; |
| 32 | ++ krb5_data plain = empty_data(); |
| 33 | ++ |
| 34 | ++ token->value = NULL; |
| 35 | ++ token->length = 0; |
| 36 | + |
| 37 | + acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR; |
| 38 | + key_usage = (toktype == KG_TOK_WRAP_MSG |
| 39 | +@@ -107,14 +111,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 40 | + #endif |
| 41 | + |
| 42 | + if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) { |
| 43 | +- krb5_data plain; |
| 44 | + krb5_enc_data cipher; |
| 45 | + size_t ec_max; |
| 46 | + size_t encrypt_size; |
| 47 | + |
| 48 | + /* 300: Adds some slop. */ |
| 49 | +- if (SIZE_MAX - 300 < message->length) |
| 50 | +- return ENOMEM; |
| 51 | ++ if (SIZE_MAX - 300 < message->length) { |
| 52 | ++ err = ENOMEM; |
| 53 | ++ goto cleanup; |
| 54 | ++ } |
| 55 | + ec_max = SIZE_MAX - message->length - 300; |
| 56 | + if (ec_max > 0xffff) |
| 57 | + ec_max = 0xffff; |
| 58 | +@@ -126,20 +131,20 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 59 | + #endif |
| 60 | + err = alloc_data(&plain, message->length + 16 + ec); |
| 61 | + if (err) |
| 62 | +- return err; |
| 63 | ++ goto cleanup; |
| 64 | + |
| 65 | + /* Get size of ciphertext. */ |
| 66 | + encrypt_size = krb5_encrypt_size(plain.length, key->keyblock.enctype); |
| 67 | + if (encrypt_size > SIZE_MAX / 2) { |
| 68 | + err = ENOMEM; |
| 69 | +- goto error; |
| 70 | ++ goto cleanup; |
| 71 | + } |
| 72 | + bufsize = 16 + encrypt_size; |
| 73 | + /* Allocate space for header plus encrypted data. */ |
| 74 | + outbuf = gssalloc_malloc(bufsize); |
| 75 | + if (outbuf == NULL) { |
| 76 | +- free(plain.data); |
| 77 | +- return ENOMEM; |
| 78 | ++ err = ENOMEM; |
| 79 | ++ goto cleanup; |
| 80 | + } |
| 81 | + |
| 82 | + /* TOK_ID */ |
| 83 | +@@ -164,11 +169,8 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 84 | + cipher.ciphertext.length = bufsize - 16; |
| 85 | + cipher.enctype = key->keyblock.enctype; |
| 86 | + err = krb5_k_encrypt(context, key, key_usage, 0, &plain, &cipher); |
| 87 | +- zap(plain.data, plain.length); |
| 88 | +- free(plain.data); |
| 89 | +- plain.data = 0; |
| 90 | + if (err) |
| 91 | +- goto error; |
| 92 | ++ goto cleanup; |
| 93 | + |
| 94 | + /* Now that we know we're returning a valid token.... */ |
| 95 | + ctx->seq_send++; |
| 96 | +@@ -181,7 +183,6 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 97 | + /* If the rotate fails, don't worry about it. */ |
| 98 | + #endif |
| 99 | + } else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) { |
| 100 | +- krb5_data plain; |
| 101 | + size_t cksumsize; |
| 102 | + |
| 103 | + /* Here, message is the application-supplied data; message2 is |
| 104 | +@@ -193,21 +194,19 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 105 | + wrap_with_checksum: |
| 106 | + err = alloc_data(&plain, message->length + 16); |
| 107 | + if (err) |
| 108 | +- return err; |
| 109 | ++ goto cleanup; |
| 110 | + |
| 111 | + err = krb5_c_checksum_length(context, cksumtype, &cksumsize); |
| 112 | + if (err) |
| 113 | +- goto error; |
| 114 | ++ goto cleanup; |
| 115 | + |
| 116 | + assert(cksumsize <= 0xffff); |
| 117 | + |
| 118 | + bufsize = 16 + message2->length + cksumsize; |
| 119 | + outbuf = gssalloc_malloc(bufsize); |
| 120 | + if (outbuf == NULL) { |
| 121 | +- free(plain.data); |
| 122 | +- plain.data = 0; |
| 123 | + err = ENOMEM; |
| 124 | +- goto error; |
| 125 | ++ goto cleanup; |
| 126 | + } |
| 127 | + |
| 128 | + /* TOK_ID */ |
| 129 | +@@ -239,23 +238,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 130 | + if (message2->length) |
| 131 | + memcpy(outbuf + 16, message2->value, message2->length); |
| 132 | + |
| 133 | +- sum.contents = outbuf + 16 + message2->length; |
| 134 | +- sum.length = cksumsize; |
| 135 | +- |
| 136 | + err = krb5_k_make_checksum(context, cksumtype, key, |
| 137 | + key_usage, &plain, &sum); |
| 138 | +- zap(plain.data, plain.length); |
| 139 | +- free(plain.data); |
| 140 | +- plain.data = 0; |
| 141 | + if (err) { |
| 142 | + zap(outbuf,bufsize); |
| 143 | +- goto error; |
| 144 | ++ goto cleanup; |
| 145 | + } |
| 146 | + if (sum.length != cksumsize) |
| 147 | + abort(); |
| 148 | + memcpy(outbuf + 16 + message2->length, sum.contents, cksumsize); |
| 149 | +- krb5_free_checksum_contents(context, &sum); |
| 150 | +- sum.contents = 0; |
| 151 | + /* Now that we know we're actually generating the token... */ |
| 152 | + ctx->seq_send++; |
| 153 | + |
| 154 | +@@ -285,12 +276,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, |
| 155 | + |
| 156 | + token->value = outbuf; |
| 157 | + token->length = bufsize; |
| 158 | +- return 0; |
| 159 | ++ outbuf = NULL; |
| 160 | ++ err = 0; |
| 161 | + |
| 162 | +-error: |
| 163 | ++cleanup: |
| 164 | ++ krb5_free_checksum_contents(context, &sum); |
| 165 | ++ zapfree(plain.data, plain.length); |
| 166 | + gssalloc_free(outbuf); |
| 167 | +- token->value = NULL; |
| 168 | +- token->length = 0; |
| 169 | + return err; |
| 170 | + } |
| 171 | + |
| 172 | +diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c |
| 173 | +index 8c7e30c..115a55a 100644 |
| 174 | +--- a/src/lib/rpc/pmap_rmt.c |
| 175 | ++++ b/src/lib/rpc/pmap_rmt.c |
| 176 | +@@ -160,11 +160,12 @@ xdr_rmtcallres( |
| 177 | + caddr_t port_ptr; |
| 178 | + |
| 179 | + port_ptr = (caddr_t)(void *)crp->port_ptr; |
| 180 | +- if (xdr_reference(xdrs, &port_ptr, sizeof (uint32_t), |
| 181 | +- xdr_u_int32) && xdr_u_int32(xdrs, &crp->resultslen)) { |
| 182 | +- crp->port_ptr = (uint32_t *)(void *)port_ptr; |
| 183 | ++ if (!xdr_reference(xdrs, &port_ptr, sizeof (uint32_t), |
| 184 | ++ xdr_u_int32)) |
| 185 | ++ return (FALSE); |
| 186 | ++ crp->port_ptr = (uint32_t *)(void *)port_ptr; |
| 187 | ++ if (xdr_u_int32(xdrs, &crp->resultslen)) |
| 188 | + return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); |
| 189 | +- } |
| 190 | + return (FALSE); |
| 191 | + } |
| 192 | + |
| 193 | +-- |
| 194 | +2.34.1 |
| 195 | + |
0 commit comments