From 8857a1c4c960824ea95ac06232b417de2827d0db Mon Sep 17 00:00:00 2001 From: xuraoqing Date: Wed, 3 Jul 2024 10:50:11 +0800 Subject: [PATCH] backport patches to fix bugs and CVE-2024-37370 CVE-2024-37371 Signed-off-by: xuraoqing --- ...port-Add-a-simple-DER-support-header.patch | 171 ++++ ...lities-in-GSS-message-token-handling.patch | 536 +++++++++++ backport-Fix-Python-regexp-literals.patch | 44 + ...ort-Fix-more-non-prototype-functions.patch | 866 ++++++++++++++++++ ...y-initial-buffer-in-IAKERB-initiator.patch | 38 + krb5.spec | 10 +- 6 files changed, 1664 insertions(+), 1 deletion(-) create mode 100644 backport-Add-a-simple-DER-support-header.patch create mode 100644 backport-CVE-2024-37370-CVE-2024-37371-Fix-vulnerabilities-in-GSS-message-token-handling.patch create mode 100644 backport-Fix-Python-regexp-literals.patch create mode 100644 backport-Fix-more-non-prototype-functions.patch create mode 100644 backport-Handle-empty-initial-buffer-in-IAKERB-initiator.patch diff --git a/backport-Add-a-simple-DER-support-header.patch b/backport-Add-a-simple-DER-support-header.patch new file mode 100644 index 0000000..d90c866 --- /dev/null +++ b/backport-Add-a-simple-DER-support-header.patch @@ -0,0 +1,171 @@ +From 548da160b52b25a106e9f6077d6a42c2c049586c Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 7 Mar 2023 00:19:33 -0500 +Subject: [PATCH] Add a simple DER support header + +Reference: https://github.com/krb5/krb5/commit/548da160b52b25a106e9f6077d6a42c2c049586c +Conflict: NA + +--- + src/include/k5-der.h | 149 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 149 insertions(+) + create mode 100644 src/include/k5-der.h + +diff --git a/src/include/k5-der.h b/src/include/k5-der.h +new file mode 100644 +index 0000000..b8371d9 +--- /dev/null ++++ b/src/include/k5-der.h +@@ -0,0 +1,149 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/k5-der.h - Distinguished Encoding Rules (DER) declarations */ ++/* ++ * Copyright (C) 2023 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * Most ASN.1 encoding and decoding is done using the table-driven framework in ++ * libkrb5. When that is not an option, these helpers can be used to encode ++ * and decode simple types. ++ */ ++ ++#ifndef K5_DER_H ++#define K5_DER_H ++ ++#include ++#include ++#include "k5-buf.h" ++#include "k5-input.h" ++ ++/* Return the number of bytes needed to encode len as a DER encoding length. */ ++static inline size_t ++k5_der_len_len(size_t len) ++{ ++ size_t llen; ++ ++ if (len < 128) ++ return 1; ++ llen = 1; ++ while (len > 0) { ++ len >>= 8; ++ llen++; ++ } ++ return llen; ++} ++ ++/* Return the number of bytes needed to encode a DER value (with identifier ++ * byte and length) for a given contents length. */ ++static inline size_t ++k5_der_value_len(size_t contents_len) ++{ ++ return 1 + k5_der_len_len(contents_len) + contents_len; ++} ++ ++/* Add a DER identifier byte (composed by the caller, including the ASN.1 ++ * class, tag, and constructed bit) and length. */ ++static inline void ++k5_der_add_taglen(struct k5buf *buf, uint8_t idbyte, size_t len) ++{ ++ uint8_t *p; ++ size_t llen = k5_der_len_len(len); ++ ++ p = k5_buf_get_space(buf, 1 + llen); ++ if (p == NULL) ++ return; ++ *p++ = idbyte; ++ if (len < 128) { ++ *p = len; ++ } else { ++ *p = 0x80 | (llen - 1); ++ /* Encode the length bytes backwards so the most significant byte is ++ * first. */ ++ p += llen; ++ while (len > 0) { ++ *--p = len & 0xFF; ++ len >>= 8; ++ } ++ } ++} ++ ++/* Add a DER value (identifier byte, length, and contents). */ ++static inline void ++k5_der_add_value(struct k5buf *buf, uint8_t idbyte, const void *contents, ++ size_t len) ++{ ++ k5_der_add_taglen(buf, idbyte, len); ++ k5_buf_add_len(buf, contents, len); ++} ++ ++/* ++ * If the next byte in in matches idbyte and the subsequent DER length is ++ * valid, advance in past the value, set *contents_out to the value contents, ++ * and return true. Otherwise return false. Only set an error on in if the ++ * next bytes matches idbyte but the ensuing length is invalid. contents_out ++ * may be aliased to in; it will only be written to on successful decoding of a ++ * value. ++ */ ++static inline bool ++k5_der_get_value(struct k5input *in, uint8_t idbyte, ++ struct k5input *contents_out) ++{ ++ uint8_t lenbyte, i; ++ size_t len; ++ const void *bytes; ++ ++ /* Do nothing if in is empty or the next byte doesn't match idbyte. */ ++ if (in->status || in->len == 0 || *in->ptr != idbyte) ++ return false; ++ ++ /* Advance past the identifier byte and decode the length. */ ++ (void)k5_input_get_byte(in); ++ lenbyte = k5_input_get_byte(in); ++ if (lenbyte < 128) { ++ len = lenbyte; ++ } else { ++ len = 0; ++ for (i = 0; i < (lenbyte & 0x7F); i++) { ++ if (len > (SIZE_MAX >> 8)) { ++ k5_input_set_status(in, EOVERFLOW); ++ return false; ++ } ++ len = (len << 8) | k5_input_get_byte(in); ++ } ++ } ++ ++ bytes = k5_input_get_bytes(in, len); ++ if (bytes == NULL) ++ return false; ++ k5_input_init(contents_out, bytes, len); ++ return true; ++} ++ ++#endif /* K5_DER_H */ +-- +2.33.0 + diff --git a/backport-CVE-2024-37370-CVE-2024-37371-Fix-vulnerabilities-in-GSS-message-token-handling.patch b/backport-CVE-2024-37370-CVE-2024-37371-Fix-vulnerabilities-in-GSS-message-token-handling.patch new file mode 100644 index 0000000..8687020 --- /dev/null +++ b/backport-CVE-2024-37370-CVE-2024-37371-Fix-vulnerabilities-in-GSS-message-token-handling.patch @@ -0,0 +1,536 @@ +From b0a2f8a5365f2eec3e27d78907de9f9d2c80505a Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 14 Jun 2024 10:56:12 -0400 +Subject: [PATCH] Fix vulnerabilities in GSS message token handling + +In gss_krb5int_unseal_token_v3() and gss_krb5int_unseal_v3_iov(), +verify the Extra Count field of CFX wrap tokens against the encrypted +header. Reported by Jacob Champion. + +In gss_krb5int_unseal_token_v3(), check for a decrypted plaintext +length too short to contain the encrypted header and extra count +bytes. Reported by Jacob Champion. + +In kg_unseal_iov_token(), separately track the header IOV length and +complete token length when parsing the token's ASN.1 wrapper. This +fix contains modified versions of functions from k5-der.h and +util_token.c; this duplication will be cleaned up in a future commit. + +CVE-2024-37370: + +In MIT krb5 release 1.3 and later, an attacker can modify the +plaintext Extra Count field of a confidential GSS krb5 wrap token, +causing the unwrapped token to appear truncated to the application. + +CVE-2024-37371: + +In MIT krb5 release 1.3 and later, an attacker can cause invalid +memory reads by sending message tokens with invalid length fields. + +ticket: 9128 (new) +tags: pullup +target_version: 1.21-next + +Reference: https://github.com/krb5/krb5/commit/b0a2f8a5365f2eec3e27d78907de9f9d2c80505a +Conflict: src/tests/gssapi/t_invalid.c + +--- + src/lib/gssapi/krb5/k5sealv3.c | 5 + + src/lib/gssapi/krb5/k5sealv3iov.c | 3 +- + src/lib/gssapi/krb5/k5unsealiov.c | 80 +++++++++- + src/tests/gssapi/t_invalid.c | 233 +++++++++++++++++++++++++----- + 4 files changed, 275 insertions(+), 46 deletions(-) + +diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c +index e881eee..d3210c1 100644 +--- a/src/lib/gssapi/krb5/k5sealv3.c ++++ b/src/lib/gssapi/krb5/k5sealv3.c +@@ -400,10 +400,15 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, + /* Don't use bodysize here! Use the fact that + cipher.ciphertext.length has been adjusted to the + correct length. */ ++ if (plain.length < 16 + ec) { ++ free(plain.data); ++ goto defective; ++ } + althdr = (unsigned char *)plain.data + plain.length - 16; + if (load_16_be(althdr) != KG2_TOK_WRAP_MSG + || althdr[2] != ptr[2] + || althdr[3] != ptr[3] ++ || load_16_be(althdr+4) != ec + || memcmp(althdr+8, ptr+8, 8)) { + free(plain.data); + goto defective; +diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c +index 333ee12..f8e90c3 100644 +--- a/src/lib/gssapi/krb5/k5sealv3iov.c ++++ b/src/lib/gssapi/krb5/k5sealv3iov.c +@@ -402,9 +402,10 @@ gss_krb5int_unseal_v3_iov(krb5_context context, + if (load_16_be(althdr) != KG2_TOK_WRAP_MSG + || althdr[2] != ptr[2] + || althdr[3] != ptr[3] ++ || load_16_be(althdr + 4) != ec + || memcmp(althdr + 8, ptr + 8, 8) != 0) { + *minor_status = 0; +- return GSS_S_BAD_SIG; ++ return GSS_S_DEFECTIVE_TOKEN; + } + } else { + /* Verify checksum: note EC is checksum size here, not padding */ +diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c +index 3ce2a90..6a6585d 100644 +--- a/src/lib/gssapi/krb5/k5unsealiov.c ++++ b/src/lib/gssapi/krb5/k5unsealiov.c +@@ -25,6 +25,7 @@ + */ + + #include "k5-int.h" ++#include "k5-der.h" + #include "gssapiP_krb5.h" + + static OM_uint32 +@@ -247,6 +248,73 @@ cleanup: + return retval; + } + ++/* Similar to k5_der_get_value(), but output an unchecked content length ++ * instead of a k5input containing the contents. */ ++static inline bool ++get_der_tag(struct k5input *in, uint8_t idbyte, size_t *len_out) ++{ ++ uint8_t lenbyte, i; ++ size_t len; ++ ++ /* Do nothing if in is empty or the next byte doesn't match idbyte. */ ++ if (in->status || in->len == 0 || *in->ptr != idbyte) ++ return false; ++ ++ /* Advance past the identifier byte and decode the length. */ ++ (void)k5_input_get_byte(in); ++ lenbyte = k5_input_get_byte(in); ++ if (lenbyte < 128) { ++ len = lenbyte; ++ } else { ++ len = 0; ++ for (i = 0; i < (lenbyte & 0x7F); i++) { ++ if (len > (SIZE_MAX >> 8)) { ++ k5_input_set_status(in, EOVERFLOW); ++ return false; ++ } ++ len = (len << 8) | k5_input_get_byte(in); ++ } ++ } ++ ++ if (in->status) ++ return false; ++ ++ *len_out = len; ++ return true; ++} ++ ++/* ++ * Similar to g_verify_token_header() without toktype or flags, but do not read ++ * more than *header_len bytes of ASN.1 wrapper, and on output set *header_len ++ * to the remaining number of header bytes. Verify the outer DER tag's length ++ * against token_len, which may be larger (but not smaller) than *header_len. ++ */ ++static gss_int32 ++verify_detached_wrapper(const gss_OID_desc *mech, size_t *header_len, ++ uint8_t **header_in, size_t token_len) ++{ ++ struct k5input in, mech_der; ++ gss_OID_desc toid; ++ size_t len; ++ ++ k5_input_init(&in, *header_in, *header_len); ++ ++ if (get_der_tag(&in, 0x60, &len)) { ++ if (len != token_len - (in.ptr - *header_in)) ++ return G_BAD_TOK_HEADER; ++ if (!k5_der_get_value(&in, 0x06, &mech_der)) ++ return G_BAD_TOK_HEADER; ++ toid.elements = (uint8_t *)mech_der.ptr; ++ toid.length = mech_der.len; ++ if (!g_OID_equal(&toid, mech)) ++ return G_WRONG_MECH; ++ } ++ ++ *header_in = (uint8_t *)in.ptr; ++ *header_len = in.len; ++ return 0; ++} ++ + /* + * Caller must provide TOKEN | DATA | PADDING | TRAILER, except + * for DCE in which case it can just provide TOKEN | DATA (must +@@ -267,8 +335,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status, + gss_iov_buffer_t header; + gss_iov_buffer_t padding; + gss_iov_buffer_t trailer; +- size_t input_length; +- unsigned int bodysize; ++ size_t input_length, hlen; + int toktype2; + + header = kg_locate_header_iov(iov, iov_count, toktype); +@@ -298,15 +365,14 @@ kg_unseal_iov_token(OM_uint32 *minor_status, + input_length += trailer->buffer.length; + } + +- code = g_verify_token_header(ctx->mech_used, +- &bodysize, &ptr, -1, +- input_length, 0); ++ hlen = header->buffer.length; ++ code = verify_detached_wrapper(ctx->mech_used, &hlen, &ptr, input_length); + if (code != 0) { + *minor_status = code; + return GSS_S_DEFECTIVE_TOKEN; + } + +- if (bodysize < 2) { ++ if (hlen < 2) { + *minor_status = (OM_uint32)G_BAD_TOK_HEADER; + return GSS_S_DEFECTIVE_TOKEN; + } +@@ -314,7 +380,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status, + toktype2 = load_16_be(ptr); + + ptr += 2; +- bodysize -= 2; ++ hlen -= 2; + + switch (toktype2) { + case KG2_TOK_MIC_MSG: +diff --git a/src/tests/gssapi/t_invalid.c b/src/tests/gssapi/t_invalid.c +index fb8fe55..d1f019f 100644 +--- a/src/tests/gssapi/t_invalid.c ++++ b/src/tests/gssapi/t_invalid.c +@@ -36,31 +36,41 @@ + * + * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a + * null pointer dereference. (The token must use SEAL_ALG_NONE or it will +- * be rejected.) ++ * be rejected.) This vulnerability also applies to IOV unwrap. + * +- * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1 ++ * 2. A CFX wrap token with a different value of EC between the plaintext and ++ * encrypted copies will be erroneously accepted, which allows a message ++ * truncation attack. This vulnerability also applies to IOV unwrap. ++ * ++ * 3. A CFX wrap token with a plaintext length fewer than 16 bytes causes an ++ * access before the beginning of the input buffer, possibly leading to a ++ * crash. ++ * ++ * 4. A CFX wrap token with a plaintext EC value greater than the plaintext ++ * length - 16 causes an integer underflow when computing the result length, ++ * likely causing a crash. ++ * ++ * 5. An IOV unwrap operation will overrun the header buffer if an ASN.1 ++ * wrapper longer than the header buffer is present. ++ * ++ * 6. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1 + * header causes an input buffer overrun, usually leading to either a segv + * or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or +- * sequence number values. ++ * sequence number values. This vulnerability also applies to IOV unwrap. + * +- * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1 ++ * 7. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1 + * header causes an integer underflow when computing the ciphertext length, + * leading to an allocation error on 32-bit platforms or a segv on 64-bit + * platforms. A pre-CFX MIC token of this size causes an input buffer + * overrun when comparing the checksum, perhaps leading to a segv. + * +- * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the ++ * 8. A pre-CFX wrap token with fewer than conflen + padlen bytes in the + * ciphertext (where padlen is the last byte of the decrypted ciphertext) + * causes an integer underflow when computing the original message length, + * leading to an allocation error. + * +- * 5. In the mechglue, truncated encapsulation in the initial context token can ++ * 9. In the mechglue, truncated encapsulation in the initial context token can + * cause input buffer overruns in gss_accept_sec_context(). +- * +- * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with +- * fewer than 16 bytes after the ASN.1 header will be rejected. +- * Vulnerabilities #2 and #5 can only be robustly detected using a +- * memory-checking environment such as valgrind. + */ + + #include "k5-int.h" +@@ -98,16 +108,24 @@ struct test { + }; + + /* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */ ++static void * ++ealloc(size_t len) ++{ ++ void *ptr = calloc(len, 1); ++ ++ if (ptr == NULL) ++ abort(); ++ return ptr; ++} ++ ++/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. ++ * The context takes ownership of subkey. */ + static gss_ctx_id_t +-make_fake_cfx_context() ++make_fake_cfx_context(krb5_key subkey) + { + gss_union_ctx_id_t uctx; + krb5_gss_ctx_id_t kgctx; +- krb5_keyblock kb; +- +- kgctx = calloc(1, sizeof(*kgctx)); +- if (kgctx == NULL) +- abort(); ++ kgctx = ealloc(sizeof(*kgctx)); + kgctx->established = 1; + kgctx->proto = 1; + if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) +@@ -116,15 +134,10 @@ make_fake_cfx_context() + kgctx->sealalg = -1; + kgctx->signalg = -1; + +- kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; +- kb.length = 16; +- kb.contents = (unsigned char *)"1234567887654321"; +- if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0) +- abort(); ++ kgctx->subkey = subkey; ++ kgctx->cksumtype = CKSUMTYPE_HMAC_SHA1_96_AES128; + +- uctx = calloc(1, sizeof(*uctx)); +- if (uctx == NULL) +- abort(); ++ uctx = ealloc(sizeof(*uctx)); + uctx->mech_type = &mech_krb5; + uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; + return (gss_ctx_id_t)uctx; +@@ -138,9 +151,7 @@ make_fake_context(const struct test *test) + krb5_gss_ctx_id_t kgctx; + krb5_keyblock kb; + +- kgctx = calloc(1, sizeof(*kgctx)); +- if (kgctx == NULL) +- abort(); ++ kgctx = ealloc(sizeof(*kgctx)); + kgctx->established = 1; + if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) + abort(); +@@ -162,9 +173,7 @@ make_fake_context(const struct test *test) + if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0) + abort(); + +- uctx = calloc(1, sizeof(*uctx)); +- if (uctx == NULL) +- abort(); ++ uctx = ealloc(sizeof(*uctx)); + uctx->mech_type = &mech_krb5; + uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; + return (gss_ctx_id_t)uctx; +@@ -194,9 +203,7 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out) + + assert(mech_krb5.length == 9); + assert(len + 11 < 128); +- wrapped = malloc(len + 13); +- if (wrapped == NULL) +- abort(); ++ wrapped = ealloc(len + 13); + wrapped[0] = 0x60; + wrapped[1] = len + 11; + wrapped[2] = 0x06; +@@ -207,6 +214,18 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out) + out->value = wrapped; + } + ++/* Create a 16-byte header for a CFX confidential wrap token to be processed by ++ * the fake CFX context. */ ++static void ++write_cfx_header(uint16_t ec, uint8_t *out) ++{ ++ memset(out, 0, 16); ++ store_16_be(KG2_TOK_WRAP_MSG, out); ++ out[2] = FLAG_WRAP_CONFIDENTIAL; ++ out[3] = 0xFF; ++ store_16_be(ec, out + 4); ++} ++ + /* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with + * regular and IOV unwrap. */ + static void +@@ -238,6 +257,134 @@ test_bogus_1964_token(gss_ctx_id_t ctx) + free(in.value); + } + ++static void ++test_cfx_altered_ec(gss_ctx_id_t ctx, krb5_key subkey) ++{ ++ OM_uint32 major, minor; ++ uint8_t tokbuf[128], plainbuf[24]; ++ krb5_data plain; ++ krb5_enc_data cipher; ++ gss_buffer_desc in, out; ++ gss_iov_buffer_desc iov[2]; ++ ++ /* Construct a header with a plaintext EC value of 3. */ ++ write_cfx_header(3, tokbuf); ++ ++ /* Encrypt a plaintext and a copy of the header with the EC value 0. */ ++ memcpy(plainbuf, "truncate", 8); ++ memcpy(plainbuf + 8, tokbuf, 16); ++ store_16_be(0, plainbuf + 12); ++ plain = make_data(plainbuf, 24); ++ cipher.ciphertext.data = (char *)tokbuf + 16; ++ cipher.ciphertext.length = sizeof(tokbuf) - 16; ++ cipher.enctype = subkey->keyblock.enctype; ++ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL, ++ &plain, &cipher) != 0) ++ abort(); ++ ++ /* Verify that the token is rejected by gss_unwrap(). */ ++ in.value = tokbuf; ++ in.length = 16 + cipher.ciphertext.length; ++ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); ++ if (major != GSS_S_DEFECTIVE_TOKEN) ++ abort(); ++ (void)gss_release_buffer(&minor, &out); ++ ++ /* Verify that the token is rejected by gss_unwrap_iov(). */ ++ iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; ++ iov[0].buffer = in; ++ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; ++ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2); ++ if (major != GSS_S_DEFECTIVE_TOKEN) ++ abort(); ++} ++ ++static void ++test_cfx_short_plaintext(gss_ctx_id_t ctx, krb5_key subkey) ++{ ++ OM_uint32 major, minor; ++ uint8_t tokbuf[128], zerobyte = 0; ++ krb5_data plain; ++ krb5_enc_data cipher; ++ gss_buffer_desc in, out; ++ ++ write_cfx_header(0, tokbuf); ++ ++ /* Encrypt a single byte, with no copy of the header. */ ++ plain = make_data(&zerobyte, 1); ++ cipher.ciphertext.data = (char *)tokbuf + 16; ++ cipher.ciphertext.length = sizeof(tokbuf) - 16; ++ cipher.enctype = subkey->keyblock.enctype; ++ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL, ++ &plain, &cipher) != 0) ++ abort(); ++ ++ /* Verify that the token is rejected by gss_unwrap(). */ ++ in.value = tokbuf; ++ in.length = 16 + cipher.ciphertext.length; ++ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); ++ if (major != GSS_S_DEFECTIVE_TOKEN) ++ abort(); ++ (void)gss_release_buffer(&minor, &out); ++} ++ ++static void ++test_cfx_large_ec(gss_ctx_id_t ctx, krb5_key subkey) ++{ ++ OM_uint32 major, minor; ++ uint8_t tokbuf[128] = { 0 }, plainbuf[20]; ++ krb5_data plain; ++ krb5_enc_data cipher; ++ gss_buffer_desc in, out; ++ ++ /* Construct a header with an EC value of 5. */ ++ write_cfx_header(5, tokbuf); ++ ++ /* Encrypt a 4-byte plaintext plus the header. */ ++ memcpy(plainbuf, "abcd", 4); ++ memcpy(plainbuf + 4, tokbuf, 16); ++ plain = make_data(plainbuf, 20); ++ cipher.ciphertext.data = (char *)tokbuf + 16; ++ cipher.ciphertext.length = sizeof(tokbuf) - 16; ++ cipher.enctype = subkey->keyblock.enctype; ++ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL, ++ &plain, &cipher) != 0) ++ abort(); ++ ++ /* Verify that the token is rejected by gss_unwrap(). */ ++ in.value = tokbuf; ++ in.length = 16 + cipher.ciphertext.length; ++ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); ++ if (major != GSS_S_DEFECTIVE_TOKEN) ++ abort(); ++ (void)gss_release_buffer(&minor, &out); ++} ++ ++static void ++test_iov_large_asn1_wrapper(gss_ctx_id_t ctx) ++{ ++ OM_uint32 minor, major; ++ uint8_t databuf[10] = { 0 }; ++ gss_iov_buffer_desc iov[2]; ++ ++ /* ++ * In this IOV array, the header contains a DER tag with a dangling eight ++ * bytes of length field. The data IOV indicates a total token length ++ * sufficient to contain the length bytes. ++ */ ++ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; ++ iov[0].buffer.value = ealloc(2); ++ iov[0].buffer.length = 2; ++ memcpy(iov[0].buffer.value, "\x60\x88", 2); ++ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; ++ iov[1].buffer.value = databuf; ++ iov[1].buffer.length = 10; ++ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2); ++ if (major != GSS_S_DEFECTIVE_TOKEN) ++ abort(); ++ free(iov[0].buffer.value); ++} ++ + /* Process wrap and MIC tokens with incomplete headers. */ + static void + test_short_header(gss_ctx_id_t ctx) +@@ -387,9 +534,7 @@ try_accept(void *value, size_t len) + gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; + + /* Copy the provided value to make input overruns more obvious. */ +- in.value = malloc(len); +- if (in.value == NULL) +- abort(); ++ in.value = ealloc(len); + memcpy(in.value, value, len); + in.length = len; + (void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in, +@@ -424,11 +569,23 @@ test_short_encapsulation() + int + main(int argc, char **argv) + { ++ krb5_keyblock kb; ++ krb5_key cfx_subkey; + gss_ctx_id_t ctx; + size_t i; + +- ctx = make_fake_cfx_context(); ++ kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; ++ kb.length = 16; ++ kb.contents = (unsigned char *)"1234567887654321"; ++ if (krb5_k_create_key(NULL, &kb, &cfx_subkey) != 0) ++ abort(); ++ ++ ctx = make_fake_cfx_context(cfx_subkey); + test_bogus_1964_token(ctx); ++ test_cfx_altered_ec(ctx, cfx_subkey); ++ test_cfx_short_plaintext(ctx, cfx_subkey); ++ test_cfx_large_ec(ctx, cfx_subkey); ++ test_iov_large_asn1_wrapper(ctx); + free_fake_context(ctx); + + for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { +-- +2.33.0 + diff --git a/backport-Fix-Python-regexp-literals.patch b/backport-Fix-Python-regexp-literals.patch new file mode 100644 index 0000000..d6debf5 --- /dev/null +++ b/backport-Fix-Python-regexp-literals.patch @@ -0,0 +1,44 @@ +From 4b21b2e2821d3cb91042be09e0ebe09707a57d72 Mon Sep 17 00:00:00 2001 +From: Arjun +Date: Thu, 9 May 2024 20:47:08 +0530 +Subject: [PATCH] Fix Python regexp literals + +Add missing "r" prefixes before literals using regexp escape +sequences. + +[ghudson@mit.edu: split into separate commit; rewrote commit message] + +Reference: https://github.com/krb5/krb5/commit/4b21b2e2821d3cb91042be09e0ebe09707a57d72 +Conflict: NA + +--- + src/util/cstyle-file.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/util/cstyle-file.py b/src/util/cstyle-file.py +index 837fa05..56b1e32 100644 +--- a/src/util/cstyle-file.py ++++ b/src/util/cstyle-file.py +@@ -208,7 +208,7 @@ def check_assignment_in_conditional(line, ln): + + + def indent(line): +- return len(re.match('\s*', line).group(0).expandtabs()) ++ return len(re.match(r'\s*', line).group(0).expandtabs()) + + + def check_unbraced_flow_body(line, ln, lines): +@@ -220,8 +220,8 @@ def check_unbraced_flow_body(line, ln, lines): + if m and (m.group(1) is None) != (m.group(3) is None): + warn(ln, 'One arm of if/else statement braced but not the other') + +- if (re.match('\s*(if|else if|for|while)\s*\(.*\)$', line) or +- re.match('\s*else$', line)): ++ if (re.match(r'\s*(if|else if|for|while)\s*\(.*\)$', line) or ++ re.match(r'\s*else$', line)): + base = indent(line) + # Look at the next two lines (ln is 1-based so lines[ln] is next). + if indent(lines[ln]) > base and indent(lines[ln + 1]) > base: +-- +2.33.0 + diff --git a/backport-Fix-more-non-prototype-functions.patch b/backport-Fix-more-non-prototype-functions.patch new file mode 100644 index 0000000..067e545 --- /dev/null +++ b/backport-Fix-more-non-prototype-functions.patch @@ -0,0 +1,866 @@ +From 623d649ba852839ba4822934bad9f97c184bf3ab Mon Sep 17 00:00:00 2001 +From: Arjun +Date: Thu, 9 May 2024 20:47:08 +0530 +Subject: [PATCH] Fix more non-prototype functions + +Add "void" designations to more function declarations and definitions +not changed by commits 3ae9244cd021a75eba909d872a92c25db490714d and +4b9d7f7c107f01a61600fddcd8cde3812d0366a2. + +[ghudson@mit.edu: change additional functions; split into two commits; +rewrote commit message] + +Reference: https://github.com/krb5/krb5/commit/623d649ba852839ba4822934bad9f97c184bf3ab +Conflict: NA + +--- + src/ccapi/common/win/OldCC/ccutils.c | 2 +- + src/ccapi/common/win/OldCC/ccutils.h | 2 +- + src/ccapi/common/win/OldCC/util.h | 2 +- + src/ccapi/common/win/win-utils.c | 2 +- + src/ccapi/common/win/win-utils.h | 4 +- + src/ccapi/lib/ccapi_context.h | 2 +- + src/ccapi/lib/win/dllmain.h | 2 +- + src/ccapi/server/ccs_server.c | 2 +- + src/ccapi/server/ccs_server.h | 2 +- + src/ccapi/server/win/WorkQueue.h | 8 +-- + src/ccapi/test/pingtest.c | 2 +- + src/include/gssrpc/netdb.h | 4 +- + src/include/port-sockets.h | 2 +- + src/kadmin/cli/getdate.y | 2 +- + src/kadmin/dbutil/kdb5_util.c | 2 +- + src/kprop/kprop.c | 2 +- + src/lib/crypto/crypto_tests/t_pkcs5.c | 4 +- + src/lib/crypto/crypto_tests/vectors.c | 10 ++-- + src/lib/gssapi/generic/maptest.c | 2 +- + src/lib/krb5/ccache/ccapi/stdcc.c | 6 +- + src/lib/krb5/ccache/ccapi/winccld.c | 9 ++- + src/lib/krb5/ccache/ccbase.c | 2 +- + src/lib/krb5/krb/bld_princ.c | 4 +- + src/lib/krb5/krb/conv_creds.c | 2 +- + src/lib/krb5/krb/init_ctx.c | 2 +- + src/lib/krb5/os/dnsglue.c | 4 +- + src/lib/krb5/os/localaddr.c | 6 +- + src/lib/rpc/getrpcent.c | 6 +- + src/lib/win_glue.c | 8 +-- + src/plugins/kdb/db2/kdb_db2.c | 4 +- + src/plugins/kdb/db2/libdb2/hash/dbm.c | 2 +- + .../kdb/ldap/libkdb_ldap/kdb_ldap_conn.c | 4 +- + src/tests/threads/gss-perf.c | 4 +- + src/tests/threads/init_ctx.c | 2 +- + src/tests/threads/profread.c | 2 +- + src/tests/threads/t_rcache.c | 2 +- + src/util/et/com_err.c | 4 +- + src/util/et/error_message.c | 2 +- + src/util/profile/prof_file.c | 4 +- + src/util/support/secure_getenv.c | 2 +- + src/windows/include/leashwin.h | 60 +++++++++---------- + 41 files changed, 100 insertions(+), 99 deletions(-) + +diff --git a/src/ccapi/common/win/OldCC/ccutils.c b/src/ccapi/common/win/OldCC/ccutils.c +index 403c67e..7abaefa 100644 +--- a/src/ccapi/common/win/OldCC/ccutils.c ++++ b/src/ccapi/common/win/OldCC/ccutils.c +@@ -30,7 +30,7 @@ + #include "cci_debugging.h" + #include "util.h" + +-BOOL isNT() { ++BOOL isNT(void) { + OSVERSIONINFO osvi; + DWORD status = 0; + BOOL bSupportedVersion = FALSE; +diff --git a/src/ccapi/common/win/OldCC/ccutils.h b/src/ccapi/common/win/OldCC/ccutils.h +index 9da3d87..0fb7e14 100644 +--- a/src/ccapi/common/win/OldCC/ccutils.h ++++ b/src/ccapi/common/win/OldCC/ccutils.h +@@ -33,7 +33,7 @@ extern "C" { + #define REPLY_SUFFIX (char*)"reply" + #define LISTEN_SUFFIX (char*)"listen" + +-BOOL isNT(); ++BOOL isNT(void); + char* allocEventName (char* uuid, char* suffix); + HANDLE createThreadEvent(char* uuid, char* suffix); + HANDLE openThreadEvent (char* uuid, char* suffix); +diff --git a/src/ccapi/common/win/OldCC/util.h b/src/ccapi/common/win/OldCC/util.h +index 45e069a..7ee5319 100644 +--- a/src/ccapi/common/win/OldCC/util.h ++++ b/src/ccapi/common/win/OldCC/util.h +@@ -30,7 +30,7 @@ + extern "C" { + #endif + +-BOOL isNT(); ++BOOL isNT(void); + + void* + user_allocate( +diff --git a/src/ccapi/common/win/win-utils.c b/src/ccapi/common/win/win-utils.c +index b49cca8..d9018a6 100644 +--- a/src/ccapi/common/win/win-utils.c ++++ b/src/ccapi/common/win/win-utils.c +@@ -60,7 +60,7 @@ char* serverEndpoint(const char* user) { + return _serverEndpoint; + } + +-char* timestamp() { ++char* timestamp(void) { + SYSTEMTIME _stime; + GetSystemTime(&_stime); + GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &_stime, "HH:mm:ss", _ts, sizeof(_ts)-1); +diff --git a/src/ccapi/common/win/win-utils.h b/src/ccapi/common/win/win-utils.h +index 41cab24..94d0a9f 100644 +--- a/src/ccapi/common/win/win-utils.h ++++ b/src/ccapi/common/win/win-utils.h +@@ -50,6 +50,6 @@ char* clientEndpoint(const char* UUID); + char* serverEndpoint(const char* UUID); + extern unsigned char* pszProtocolSequence; + +-char* timestamp(); ++char* timestamp(void); + +-#endif // _win_utils_h +\ No newline at end of file ++#endif // _win_utils_h +diff --git a/src/ccapi/lib/ccapi_context.h b/src/ccapi/lib/ccapi_context.h +index 51b8982..88f0ee8 100644 +--- a/src/ccapi/lib/ccapi_context.h ++++ b/src/ccapi/lib/ccapi_context.h +@@ -79,7 +79,7 @@ cc_int32 ccapi_context_compare (cc_context_t in_context, + cc_uint32 *out_equal); + + #ifdef WIN32 +-void cci_thread_init__auxinit(); ++void cci_thread_init__auxinit(void); + #endif + + +diff --git a/src/ccapi/lib/win/dllmain.h b/src/ccapi/lib/win/dllmain.h +index 8238566..28ca34e 100644 +--- a/src/ccapi/lib/win/dllmain.h ++++ b/src/ccapi/lib/win/dllmain.h +@@ -32,7 +32,7 @@ + extern "C" { // we need to export the C interface + #endif + +-DWORD GetTlsIndex(); ++DWORD GetTlsIndex(void); + + #ifdef __cplusplus + } +diff --git a/src/ccapi/server/ccs_server.c b/src/ccapi/server/ccs_server.c +index 1fc8d2c..de74b71 100644 +--- a/src/ccapi/server/ccs_server.c ++++ b/src/ccapi/server/ccs_server.c +@@ -402,7 +402,7 @@ cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, + + /* ------------------------------------------------------------------------ */ + +-cc_uint64 ccs_server_client_count () ++cc_uint64 ccs_server_client_count (void) + { + return ccs_client_array_count (g_client_array); + } +diff --git a/src/ccapi/server/ccs_server.h b/src/ccapi/server/ccs_server.h +index e920ad9..f71ab06 100644 +--- a/src/ccapi/server/ccs_server.h ++++ b/src/ccapi/server/ccs_server.h +@@ -48,6 +48,6 @@ cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, + cc_int32 in_reply_err, + k5_ipc_stream in_reply_data); + +-cc_uint64 ccs_server_client_count (); ++cc_uint64 ccs_server_client_count (void); + + #endif /* CCS_SERVER_H */ +diff --git a/src/ccapi/server/win/WorkQueue.h b/src/ccapi/server/win/WorkQueue.h +index 68aa8b1..66a2960 100644 +--- a/src/ccapi/server/win/WorkQueue.h ++++ b/src/ccapi/server/win/WorkQueue.h +@@ -29,14 +29,14 @@ + #include "windows.h" + #include "ccs_pipe.h" + +-EXTERN_C int worklist_initialize(); ++EXTERN_C int worklist_initialize(void); + +-EXTERN_C int worklist_cleanup(); ++EXTERN_C int worklist_cleanup(void); + + /* Wait for work to be added to the list (via worklist_add) from another thread */ +-EXTERN_C void worklist_wait(); ++EXTERN_C void worklist_wait(void); + +-EXTERN_C BOOL worklist_isEmpty(); ++EXTERN_C BOOL worklist_isEmpty(void); + + EXTERN_C int worklist_add( const long rpcmsg, + const ccs_pipe_t pipe, +diff --git a/src/ccapi/test/pingtest.c b/src/ccapi/test/pingtest.c +index 0ffc15e..24327c2 100644 +--- a/src/ccapi/test/pingtest.c ++++ b/src/ccapi/test/pingtest.c +@@ -23,7 +23,7 @@ extern cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, + + static DWORD dwTlsIndex; + +-DWORD GetTlsIndex() {return dwTlsIndex;} ++DWORD GetTlsIndex(void) {return dwTlsIndex;} + + RPC_STATUS send_test(char* endpoint) { + unsigned char* pszNetworkAddress = NULL; +diff --git a/src/include/gssrpc/netdb.h b/src/include/gssrpc/netdb.h +index f933fbb..2f62edf 100644 +--- a/src/include/gssrpc/netdb.h ++++ b/src/include/gssrpc/netdb.h +@@ -53,6 +53,8 @@ struct rpcent { + }; + #endif /*STRUCT_RPCENT_IN_RPC_NETDB_H*/ + +-struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent(); ++struct rpcent *getrpcbyname(const char *name); ++struct rpcent *getrpcbynumber(int number); ++struct rpcent *getrpcent(void); + + #endif +diff --git a/src/include/port-sockets.h b/src/include/port-sockets.h +index 57e5d1d..228e4cf 100644 +--- a/src/include/port-sockets.h ++++ b/src/include/port-sockets.h +@@ -111,7 +111,7 @@ static __inline void TranslatedWSASetLastError(int posix_error) + * Translate Winsock errors to their POSIX counterparts. This is necessary for + * MSVC 2010+, where both Winsock and POSIX errors are defined. + */ +-static __inline int TranslatedWSAGetLastError() ++static __inline int TranslatedWSAGetLastError(void) + { + int err = WSAGetLastError(); + switch (err) { +diff --git a/src/kadmin/cli/getdate.y b/src/kadmin/cli/getdate.y +index 2b8dbcd..2ab6fc7 100644 +--- a/src/kadmin/cli/getdate.y ++++ b/src/kadmin/cli/getdate.y +@@ -783,7 +783,7 @@ LookupWord(char *buff) + + + static int +-yylex() ++yylex(void) + { + char c; + char *p; +diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c +index 19a5925..12c6d32 100644 +--- a/src/kadmin/dbutil/kdb5_util.c ++++ b/src/kadmin/dbutil/kdb5_util.c +@@ -74,7 +74,7 @@ int exit_status = 0; + krb5_context util_context; + kadm5_config_params global_params; + +-void usage() ++void usage(void) + { + fprintf(stderr, + _("Usage: kdb5_util [-r realm] [-d dbname] " +diff --git a/src/kprop/kprop.c b/src/kprop/kprop.c +index 0b53aae..1a0cb78 100644 +--- a/src/kprop/kprop.c ++++ b/src/kprop/kprop.c +@@ -80,7 +80,7 @@ static void send_error(krb5_context context, krb5_creds *my_creds, int fd, + char *err_text, krb5_error_code err_code); + static void update_last_prop_file(char *hostname, char *file_name); + +-static void usage() ++static void usage(void) + { + fprintf(stderr, _("\nUsage: %s [-r realm] [-f file] [-d] [-P port] " + "[-s keytab] replica_host\n\n"), progname); +diff --git a/src/lib/crypto/crypto_tests/t_pkcs5.c b/src/lib/crypto/crypto_tests/t_pkcs5.c +index 8e87a80..f4bb33e 100644 +--- a/src/lib/crypto/crypto_tests/t_pkcs5.c ++++ b/src/lib/crypto/crypto_tests/t_pkcs5.c +@@ -38,7 +38,7 @@ static void printdata (krb5_data *d) { + printhex (d->length, d->data); + } + +-static void test_pbkdf2_rfc3211() ++static void test_pbkdf2_rfc3211(void) + { + char x[100]; + krb5_error_code err; +@@ -92,7 +92,7 @@ static void test_pbkdf2_rfc3211() + } + } + +-int main () ++int main(void) + { + test_pbkdf2_rfc3211(); + return 0; +diff --git a/src/lib/crypto/crypto_tests/vectors.c b/src/lib/crypto/crypto_tests/vectors.c +index bcf5c91..314d5c7 100644 +--- a/src/lib/crypto/crypto_tests/vectors.c ++++ b/src/lib/crypto/crypto_tests/vectors.c +@@ -56,7 +56,7 @@ static void printdata (krb5_data *d) { printhex (d->length, d->data); } + + static void printkey (krb5_keyblock *k) { printhex (k->length, k->contents); } + +-static void test_nfold () ++static void test_nfold (void) + { + int i; + static const struct { +@@ -96,7 +96,7 @@ static void test_nfold () + so try to generate them. */ + + static void +-test_mit_des_s2k () ++test_mit_des_s2k (void) + { + static const struct { + const char *pass; +@@ -190,7 +190,7 @@ test_s2k (krb5_enctype enctype) + } + } + +-static void test_des3_s2k () { test_s2k (ENCTYPE_DES3_CBC_SHA1); } ++static void test_des3_s2k (void) { test_s2k (ENCTYPE_DES3_CBC_SHA1); } + + static void + keyToData (krb5_keyblock *k, krb5_data *d) +@@ -227,7 +227,7 @@ void DR (krb5_data *out, krb5_keyblock *in, const krb5_data *usage) { + #define KEYBYTES 21 + #define KEYLENGTH 24 + +-void test_dr_dk () ++void test_dr_dk (void) + { + static const struct { + unsigned char keydata[KEYLENGTH]; +@@ -371,7 +371,7 @@ static void printk(const char *descr, krb5_keyblock *k) { + + + static void +-test_pbkdf2() ++test_pbkdf2(void) + { + static struct { + int count; +diff --git a/src/lib/gssapi/generic/maptest.c b/src/lib/gssapi/generic/maptest.c +index 566d88c..ab3ed90 100644 +--- a/src/lib/gssapi/generic/maptest.c ++++ b/src/lib/gssapi/generic/maptest.c +@@ -42,7 +42,7 @@ static void intprt(int v, FILE *f) + + foo foo1; + +-int main () ++int main (void) + { + elt v1 = { 1, 2 }, v2 = { 3, 4 }; + const elt *vp; +diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c +index 0dc5259..d6eecb5 100644 +--- a/src/lib/krb5/ccache/ccapi/stdcc.c ++++ b/src/lib/krb5/ccache/ccapi/stdcc.c +@@ -128,7 +128,7 @@ krb5_cc_ops krb5_cc_stdcc_ops = { + * changes made. We register a unique message type with which + * we'll communicate to all other processes. + */ +-static void cache_changed() ++static void cache_changed(void) + { + static unsigned int message = 0; + +@@ -139,7 +139,7 @@ static void cache_changed() + } + #else /* _WIN32 */ + +-static void cache_changed() ++static void cache_changed(void) + { + return; + } +@@ -296,7 +296,7 @@ static krb5_error_code stdccv3_setup (krb5_context context, + } + + /* krb5_stdcc_shutdown is exported; use the old name */ +-void krb5_stdcc_shutdown() ++void krb5_stdcc_shutdown(void) + { + if (gCntrlBlock) { cc_context_release(gCntrlBlock); } + gCntrlBlock = NULL; +diff --git a/src/lib/krb5/ccache/ccapi/winccld.c b/src/lib/krb5/ccache/ccapi/winccld.c +index 8b2e90c..62b1bd7 100644 +--- a/src/lib/krb5/ccache/ccapi/winccld.c ++++ b/src/lib/krb5/ccache/ccapi/winccld.c +@@ -18,8 +18,8 @@ extern const krb5_cc_ops krb5_fcc_ops; + + static int krb5_win_ccdll_loaded = 0; + +-extern void krb5_win_ccdll_load(); +-extern int krb5_is_ccdll_loaded(); ++extern void krb5_win_ccdll_load(krb5_context context); ++extern int krb5_is_ccdll_loaded(void); + + /* + * return codes +@@ -81,8 +81,7 @@ static int LoadFuncs(const char* dll_name, FUNC_INFO fi[], + return LF_OK; + } + +-void krb5_win_ccdll_load(context) +- krb5_context context; ++void krb5_win_ccdll_load(krb5_context context) + { + krb5_cc_register(context, &krb5_fcc_ops, 0); + if (krb5_win_ccdll_loaded) +@@ -93,7 +92,7 @@ void krb5_win_ccdll_load(context) + krb5_cc_dfl_ops = &krb5_cc_stdcc_ops; /* Use stdcc! */ + } + +-int krb5_is_ccdll_loaded() ++int krb5_is_ccdll_loaded(void) + { + return krb5_win_ccdll_loaded; + } +diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c +index f53ba50..ebdece6 100644 +--- a/src/lib/krb5/ccache/ccbase.c ++++ b/src/lib/krb5/ccache/ccbase.c +@@ -555,7 +555,7 @@ k5_cccol_unlock(krb5_context context) + + /* necessary to make reentrant locks play nice with krb5int_cc_finalize */ + void +-k5_cccol_force_unlock() ++k5_cccol_force_unlock(void) + { + /* sanity check */ + if ((&cccol_lock)->refcount == 0) { +diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c +index 8604268..a1635f0 100644 +--- a/src/lib/krb5/krb/bld_princ.c ++++ b/src/lib/krb5/krb/bld_princ.c +@@ -154,13 +154,13 @@ const krb5_principal_data anon_princ = { + }; + + const krb5_data * KRB5_CALLCONV +-krb5_anonymous_realm() ++krb5_anonymous_realm(void) + { + return &anon_realm_data; + } + + krb5_const_principal KRB5_CALLCONV +-krb5_anonymous_principal() ++krb5_anonymous_principal(void) + { + return &anon_princ; + } +diff --git a/src/lib/krb5/krb/conv_creds.c b/src/lib/krb5/krb/conv_creds.c +index 6f46088..8d0a317 100644 +--- a/src/lib/krb5/krb/conv_creds.c ++++ b/src/lib/krb5/krb/conv_creds.c +@@ -55,7 +55,7 @@ krb524_convert_creds_kdc(krb5_context context, krb5_creds *v5creds, + return KRB524_KRB4_DISABLED; + } + +-void KRB5_CALLCONV krb524_init_ets () ++void KRB5_CALLCONV krb524_init_ets (void) + { + } + #endif +diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c +index bfa99d9..272015a 100644 +--- a/src/lib/krb5/krb/init_ctx.c ++++ b/src/lib/krb5/krb/init_ctx.c +@@ -65,7 +65,7 @@ static krb5_enctype default_enctype_list[] = { + }; + + #if (defined(_WIN32)) +-extern krb5_error_code krb5_vercheck(); ++extern krb5_error_code krb5_vercheck(void); + extern void krb5_win_ccdll_load(krb5_context context); + #endif + +diff --git a/src/lib/krb5/os/dnsglue.c b/src/lib/krb5/os/dnsglue.c +index 0cd213f..b690ab3 100644 +--- a/src/lib/krb5/os/dnsglue.c ++++ b/src/lib/krb5/os/dnsglue.c +@@ -439,7 +439,7 @@ cleanup: + } + + char * +-k5_primary_domain() ++k5_primary_domain(void) + { + return NULL; + } +@@ -497,7 +497,7 @@ errout: + } + + char * +-k5_primary_domain() ++k5_primary_domain(void) + { + char *domain; + DECLARE_HANDLE(h); +diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c +index 92d765f..4e9d07f 100644 +--- a/src/lib/krb5/os/localaddr.c ++++ b/src/lib/krb5/os/localaddr.c +@@ -363,7 +363,7 @@ struct linux_ipv6_addr_list { + struct linux_ipv6_addr_list *next; + }; + static struct linux_ipv6_addr_list * +-get_linux_ipv6_addrs () ++get_linux_ipv6_addrs (void) + { + struct linux_ipv6_addr_list *lst = 0; + FILE *f; +@@ -1082,7 +1082,7 @@ static int print_addr (/*@unused@*/ void *dataptr, struct sockaddr *sa) + return 0; + } + +-int main () ++int main (void) + { + int r; + +@@ -1417,7 +1417,7 @@ get_localaddrs (krb5_context context, krb5_address ***addr, int use_profile) + * by Robert Quinn + */ + #if defined(_WIN32) +-static struct hostent *local_addr_fallback_kludge() ++static struct hostent *local_addr_fallback_kludge(void) + { + static struct hostent host; + static SOCKADDR_IN addr; +diff --git a/src/lib/rpc/getrpcent.c b/src/lib/rpc/getrpcent.c +index ad6793f..b3d94bc 100644 +--- a/src/lib/rpc/getrpcent.c ++++ b/src/lib/rpc/getrpcent.c +@@ -56,10 +56,10 @@ struct rpcdata { + char line[BUFSIZ+1]; + char *domain; + } *rpcdata; +-static struct rpcdata *get_rpcdata(); ++static struct rpcdata *get_rpcdata(void); + +-static struct rpcent *interpret(); +-struct hostent *gethostent(); ++static struct rpcent *interpret(void); ++struct hostent *gethostent(void); + + static char RPCDB[] = "/etc/rpc"; + +diff --git a/src/lib/win_glue.c b/src/lib/win_glue.c +index e149a12..760f886 100644 +--- a/src/lib/win_glue.c ++++ b/src/lib/win_glue.c +@@ -6,7 +6,7 @@ + #include "asn1_err.h" + #include "kdb5_err.h" + #include "profile.h" +-extern void krb5_stdcc_shutdown(); ++extern void krb5_stdcc_shutdown(void); + #endif + #ifdef GSSAPI + #include "gssapi/generic/gssapi_err_generic.h" +@@ -233,7 +233,7 @@ static int CallVersionServer(app_title, app_version, app_ini, code_cover) + #endif + + #ifdef TIMEBOMB +-static krb5_error_code do_timebomb() ++static krb5_error_code do_timebomb(void) + { + char buf[1024]; + long timeleft; +@@ -276,7 +276,7 @@ static krb5_error_code do_timebomb() + * doesn't allow you to make messaging calls from LibMain. So, we now + * do the timebomb/version server stuff from krb5_init_context(). + */ +-krb5_error_code krb5_vercheck() ++krb5_error_code krb5_vercheck(void) + { + static int verchecked = 0; + if (verchecked) +@@ -314,7 +314,7 @@ krb5_error_code krb5_vercheck() + + static HINSTANCE hlibinstance; + +-HINSTANCE get_lib_instance() ++HINSTANCE get_lib_instance(void) + { + return hlibinstance; + } +diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c +index dc4a839..640ed33 100644 +--- a/src/plugins/kdb/db2/kdb_db2.c ++++ b/src/plugins/kdb/db2/kdb_db2.c +@@ -1169,13 +1169,13 @@ krb5_db2_set_lockmode(krb5_context context, krb5_boolean mode) + * DAL API functions + */ + krb5_error_code +-krb5_db2_lib_init() ++krb5_db2_lib_init(void) + { + return 0; + } + + krb5_error_code +-krb5_db2_lib_cleanup() ++krb5_db2_lib_cleanup(void) + { + /* right now, no cleanup required */ + return 0; +diff --git a/src/plugins/kdb/db2/libdb2/hash/dbm.c b/src/plugins/kdb/db2/libdb2/hash/dbm.c +index 4878cbc..3e46778 100644 +--- a/src/plugins/kdb/db2/libdb2/hash/dbm.c ++++ b/src/plugins/kdb/db2/libdb2/hash/dbm.c +@@ -97,7 +97,7 @@ kdb2_fetch(key) + } + + datum +-kdb2_firstkey() ++kdb2_firstkey(void) + { + datum item; + +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c +index cee4b7b..5e77d5e 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c +@@ -314,13 +314,13 @@ krb5_ldap_rebind(krb5_ldap_context *ldap_context, + * DAL API functions + */ + krb5_error_code +-krb5_ldap_lib_init() ++krb5_ldap_lib_init(void) + { + return 0; + } + + krb5_error_code +-krb5_ldap_lib_cleanup() ++krb5_ldap_lib_cleanup(void) + { + /* right now, no cleanup required */ + return 0; +diff --git a/src/tests/threads/gss-perf.c b/src/tests/threads/gss-perf.c +index f3630c2..0ca6d84 100644 +--- a/src/tests/threads/gss-perf.c ++++ b/src/tests/threads/gss-perf.c +@@ -78,7 +78,7 @@ static void usage (void) __attribute__((noreturn)); + static void set_target (char *); + + static void +-usage () ++usage (void) + { + fprintf (stderr, "usage: %s [ options ] service-name\n", prog); + fprintf (stderr, " service-name\tGSSAPI host-based service name (e.g., 'host@FQDN')\n"); +@@ -249,7 +249,7 @@ do_accept (gss_buffer_desc *msg, int iter) + } + + static gss_buffer_desc +-do_init () ++do_init (void) + { + OM_uint32 maj_stat, min_stat; + gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; +diff --git a/src/tests/threads/init_ctx.c b/src/tests/threads/init_ctx.c +index 42619a9..dc3d417 100644 +--- a/src/tests/threads/init_ctx.c ++++ b/src/tests/threads/init_ctx.c +@@ -57,7 +57,7 @@ static int do_pause; + static void usage (void) __attribute__((noreturn)); + + static void +-usage () ++usage (void) + { + fprintf (stderr, "usage: %s [ options ]\n", prog); + fprintf (stderr, "options:\n"); +diff --git a/src/tests/threads/profread.c b/src/tests/threads/profread.c +index be28ba4..69bdb05 100644 +--- a/src/tests/threads/profread.c ++++ b/src/tests/threads/profread.c +@@ -59,7 +59,7 @@ static int do_pause; + static void usage (void) __attribute__((noreturn)); + + static void +-usage () ++usage (void) + { + fprintf (stderr, "usage: %s [ options ]\n", prog); + fprintf (stderr, "options:\n"); +diff --git a/src/tests/threads/t_rcache.c b/src/tests/threads/t_rcache.c +index 6aa773a..f7813ae 100644 +--- a/src/tests/threads/t_rcache.c ++++ b/src/tests/threads/t_rcache.c +@@ -51,7 +51,7 @@ int n_threads = DEFAULT_N_THREADS; + int interval = DEFAULT_INTERVAL; + int *ip; + +-static void wait_for_tick () ++static void wait_for_tick (void) + { + time_t now, next; + now = time(0); +diff --git a/src/util/et/com_err.c b/src/util/et/com_err.c +index c1e3be7..2e74a4f 100644 +--- a/src/util/et/com_err.c ++++ b/src/util/et/com_err.c +@@ -35,7 +35,7 @@ static /*@null@*/ et_old_error_hook_func com_err_hook = 0; + k5_mutex_t com_err_hook_lock = K5_MUTEX_PARTIAL_INITIALIZER; + + #if defined(_WIN32) +-BOOL isGuiApp() { ++BOOL isGuiApp(void) { + DWORD mypid; + HANDLE myprocess; + mypid = GetCurrentProcessId(); +@@ -161,7 +161,7 @@ et_old_error_hook_func set_com_err_hook (et_old_error_hook_func new_proc) + return x; + } + +-et_old_error_hook_func reset_com_err_hook () ++et_old_error_hook_func reset_com_err_hook (void) + { + et_old_error_hook_func x; + +diff --git a/src/util/et/error_message.c b/src/util/et/error_message.c +index 7dc02a3..460f18c 100644 +--- a/src/util/et/error_message.c ++++ b/src/util/et/error_message.c +@@ -303,7 +303,7 @@ remove_error_table(const struct error_table *et) + return ENOENT; + } + +-int com_err_finish_init() ++int com_err_finish_init(void) + { + return CALL_INIT_FUNCTION(com_err_initialize); + } +diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c +index 78d7f94..96001d5 100644 +--- a/src/util/profile/prof_file.c ++++ b/src/util/profile/prof_file.c +@@ -546,11 +546,11 @@ void profile_dereference_data_locked(prf_data_t data) + profile_free_file_data(data); + } + +-void profile_lock_global() ++void profile_lock_global(void) + { + k5_mutex_lock(&g_shared_trees_mutex); + } +-void profile_unlock_global() ++void profile_unlock_global(void) + { + k5_mutex_unlock(&g_shared_trees_mutex); + } +diff --git a/src/util/support/secure_getenv.c b/src/util/support/secure_getenv.c +index 6df0591..c9b34b6 100644 +--- a/src/util/support/secure_getenv.c ++++ b/src/util/support/secure_getenv.c +@@ -68,7 +68,7 @@ static int elevated_privilege = 0; + MAKE_INIT_FUNCTION(k5_secure_getenv_init); + + int +-k5_secure_getenv_init() ++k5_secure_getenv_init(void) + { + int saved_errno = errno; + +diff --git a/src/windows/include/leashwin.h b/src/windows/include/leashwin.h +index 08b9c7d..c85e6df 100644 +--- a/src/windows/include/leashwin.h ++++ b/src/windows/include/leashwin.h +@@ -160,51 +160,51 @@ void Leash_reset_defaults(void); + #define GOOD_TICKETS 1 + + /* Leash Configuration functions - alters Current User Registry */ +-DWORD Leash_get_default_lifetime(); ++DWORD Leash_get_default_lifetime(void); + DWORD Leash_set_default_lifetime(DWORD minutes); +-DWORD Leash_reset_default_lifetime(); +-DWORD Leash_get_default_renew_till(); ++DWORD Leash_reset_default_lifetime(void); ++DWORD Leash_get_default_renew_till(void); + DWORD Leash_set_default_renew_till(DWORD minutes); +-DWORD Leash_reset_default_renew_till(); +-DWORD Leash_get_default_renewable(); ++DWORD Leash_reset_default_renew_till(void); ++DWORD Leash_get_default_renewable(void); + DWORD Leash_set_default_renewable(DWORD onoff); +-DWORD Leash_reset_default_renewable(); +-DWORD Leash_get_default_forwardable(); ++DWORD Leash_reset_default_renewable(void); ++DWORD Leash_get_default_forwardable(void); + DWORD Leash_set_default_forwardable(DWORD onoff); +-DWORD Leash_reset_default_forwardable(); +-DWORD Leash_get_default_noaddresses(); ++DWORD Leash_reset_default_forwardable(void); ++DWORD Leash_get_default_noaddresses(void); + DWORD Leash_set_default_noaddresses(DWORD onoff); +-DWORD Leash_reset_default_noaddresses(); +-DWORD Leash_get_default_proxiable(); ++DWORD Leash_reset_default_noaddresses(void); ++DWORD Leash_get_default_proxiable(void); + DWORD Leash_set_default_proxiable(DWORD onoff); +-DWORD Leash_reset_default_proxiable(); +-DWORD Leash_get_default_publicip(); ++DWORD Leash_reset_default_proxiable(void); ++DWORD Leash_get_default_publicip(void); + DWORD Leash_set_default_publicip(DWORD ipv4addr); +-DWORD Leash_reset_default_publicip(); +-DWORD Leash_get_hide_kinit_options(); ++DWORD Leash_reset_default_publicip(void); ++DWORD Leash_get_hide_kinit_options(void); + DWORD Leash_set_hide_kinit_options(DWORD onoff); +-DWORD Leash_reset_hide_kinit_options(); +-DWORD Leash_get_default_life_min(); ++DWORD Leash_reset_hide_kinit_options(void); ++DWORD Leash_get_default_life_min(void); + DWORD Leash_set_default_life_min(DWORD minutes); +-DWORD Leash_reset_default_life_min(); +-DWORD Leash_get_default_life_max(); ++DWORD Leash_reset_default_life_min(void); ++DWORD Leash_get_default_life_max(void); + DWORD Leash_set_default_life_max(DWORD minutes); +-DWORD Leash_reset_default_life_max(); +-DWORD Leash_get_default_renew_min(); ++DWORD Leash_reset_default_life_max(void); ++DWORD Leash_get_default_renew_min(void); + DWORD Leash_set_default_renew_min(DWORD minutes); +-DWORD Leash_reset_default_renew_min(); +-DWORD Leash_get_default_renew_max(); ++DWORD Leash_reset_default_renew_min(void); ++DWORD Leash_get_default_renew_max(void); + DWORD Leash_set_default_renew_max(DWORD minutes); +-DWORD Leash_reset_default_renew_max(); +-DWORD Leash_get_default_uppercaserealm(); ++DWORD Leash_reset_default_renew_max(void); ++DWORD Leash_get_default_uppercaserealm(void); + DWORD Leash_set_default_uppercaserealm(DWORD onoff); +-DWORD Leash_reset_default_uppercaserealm(); +-DWORD Leash_get_default_mslsa_import(); ++DWORD Leash_reset_default_uppercaserealm(void); ++DWORD Leash_get_default_mslsa_import(void); + DWORD Leash_set_default_mslsa_import(DWORD onoffmatch); +-DWORD Leash_reset_default_mslsa_import(); +-DWORD Leash_get_default_preserve_kinit_settings(); ++DWORD Leash_reset_default_mslsa_import(void); ++DWORD Leash_get_default_preserve_kinit_settings(void); + DWORD Leash_set_default_preserve_kinit_settings(DWORD onoff); +-DWORD Leash_reset_default_preserve_kinit_settings(); ++DWORD Leash_reset_default_preserve_kinit_settings(void); + #ifdef __cplusplus + } + #endif +-- +2.33.0 + diff --git a/backport-Handle-empty-initial-buffer-in-IAKERB-initiator.patch b/backport-Handle-empty-initial-buffer-in-IAKERB-initiator.patch new file mode 100644 index 0000000..c98e9fa --- /dev/null +++ b/backport-Handle-empty-initial-buffer-in-IAKERB-initiator.patch @@ -0,0 +1,38 @@ +From 5f0023d5f05e95021a7caa1193f76f86871222ce Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 8 May 2024 10:10:56 +0200 +Subject: [PATCH] Handle empty initial buffer in IAKERB initiator + +Section 5.19 of RFC 2744 (about gss_init_sec_context) states, +"Initially, the input_token parameter should be specified either as +GSS_C_NO_BUFFER, or as a pointer to a gss_buffer_desc object whose +length field contains the value zero." In iakerb_initiator_step(), +handle both cases when deciding whether to parse an acceptor message. + +[ghudson@mit.edu: edited commit message] + +ticket: 9126 (new) + +Reference: https://github.com/krb5/krb5/commit/5f0023d5f05e95021a7caa1193f76f86871222ce +Conflict: NA + +--- + src/lib/gssapi/krb5/iakerb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c +index b0d0ede..7a3ad1c 100644 +--- a/src/lib/gssapi/krb5/iakerb.c ++++ b/src/lib/gssapi/krb5/iakerb.c +@@ -539,7 +539,7 @@ iakerb_initiator_step(iakerb_ctx_id_t ctx, + output_token->length = 0; + output_token->value = NULL; + +- if (input_token != GSS_C_NO_BUFFER) { ++ if (input_token != GSS_C_NO_BUFFER && input_token->length > 0) { + code = iakerb_parse_token(ctx, 0, input_token, NULL, &cookie, &in); + if (code != 0) + goto cleanup; +-- +2.33.0 + diff --git a/krb5.spec b/krb5.spec index 439cd2b..e17fbbf 100644 --- a/krb5.spec +++ b/krb5.spec @@ -3,7 +3,7 @@ Name: krb5 Version: 1.18.2 -Release: 10 +Release: 11 Summary: The Kerberos network authentication protocol License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -36,6 +36,11 @@ Patch13: backport-Use-memmove-in-Unicode-functions.patch Patch14: backport-Fix-preauth-crash-on-memory-exhaustion.patch Patch15: backport-Fix-kpropd-crash-with-unrecognized-option.patch Patch16: backport-Remove-klist-s-defname-global-variable.patch +Patch17: backport-Fix-more-non-prototype-functions.patch +Patch18: backport-Fix-Python-regexp-literals.patch +Patch19: backport-Handle-empty-initial-buffer-in-IAKERB-initiator.patch +Patch20: backport-Add-a-simple-DER-support-header.patch +Patch21: backport-CVE-2024-37370-CVE-2024-37371-Fix-vulnerabilities-in-GSS-message-token-handling.patch BuildRequires: gettext BuildRequires: gcc make automake autoconf pkgconfig pam-devel libselinux-devel byacc @@ -327,6 +332,9 @@ make -C src check || : %{_mandir}/man8/* %changelog +* Wed Jul 3 2024 xuraoqing - 1.18.2-11 +- backport patches to fix bugs and CVE-2024-37370 CVE-2024-37371 + * Tue Jun 18 2024 fuanan - 1.18.2-10 - backport patch from upstream -- Gitee