Compare commits

..

No commits in common. "2b82f5b5f60b2b7431a3b8bdcf97130d0853beac" and "785336d79d1d503bf3f282027a3f3a776a8ba187" have entirely different histories.

15 changed files with 18 additions and 1995 deletions

View File

@ -1,66 +0,0 @@
From 6217454323b39cedb1b03ac161ecb0ade3ad84e6 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 20 Oct 2024 02:09:26 -0400
Subject: [PATCH] Allow null keyblocks in IOV checksum functions
Null keyblocks are allowed by the libk5crypto checksum functions when
the checksum type is not keyed. However, krb5_c_make_checksum_iov()
and krb5_c_verify_checksum_iov() crash on null keyblock inputs because
they do not check before converting to krb5_key as their non-IOV
variants do. Add the missing null checks.
ticket: 9146 (new)
---
src/lib/crypto/krb/make_checksum_iov.c | 10 ++++++----
src/lib/crypto/krb/verify_checksum_iov.c | 10 ++++++----
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/lib/crypto/krb/make_checksum_iov.c b/src/lib/crypto/krb/make_checksum_iov.c
index 549180d..84e98b1 100644
--- a/src/lib/crypto/krb/make_checksum_iov.c
+++ b/src/lib/crypto/krb/make_checksum_iov.c
@@ -81,12 +81,14 @@ krb5_c_make_checksum_iov(krb5_context context,
krb5_crypto_iov *data,
size_t num_data)
{
- krb5_key key;
+ krb5_key key = NULL;
krb5_error_code ret;
- ret = krb5_k_create_key(context, keyblock, &key);
- if (ret != 0)
- return ret;
+ if (keyblock != NULL) {
+ ret = krb5_k_create_key(context, keyblock, &key);
+ if (ret != 0)
+ return ret;
+ }
ret = krb5_k_make_checksum_iov(context, cksumtype, key, usage,
data, num_data);
krb5_k_free_key(context, key);
diff --git a/src/lib/crypto/krb/verify_checksum_iov.c b/src/lib/crypto/krb/verify_checksum_iov.c
index fc76c0e..47a25a9 100644
--- a/src/lib/crypto/krb/verify_checksum_iov.c
+++ b/src/lib/crypto/krb/verify_checksum_iov.c
@@ -88,12 +88,14 @@ krb5_c_verify_checksum_iov(krb5_context context,
size_t num_data,
krb5_boolean *valid)
{
- krb5_key key;
+ krb5_key key = NULL;
krb5_error_code ret;
- ret = krb5_k_create_key(context, keyblock, &key);
- if (ret != 0)
- return ret;
+ if (keyblock != NULL) {
+ ret = krb5_k_create_key(context, keyblock, &key);
+ if (ret != 0)
+ return ret;
+ }
ret = krb5_k_verify_checksum_iov(context, checksum_type, key, usage, data,
num_data, valid);
krb5_k_free_key(context, key);
--
2.43.0

View File

@ -1,71 +0,0 @@
From b03d55c2b841731c8194cb12566cad1d6d2ad3cb Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 4 Oct 2024 18:00:21 +0200
Subject: [PATCH] Avoid mutex locking in krb5int_trace()
Trace logging doesn't need unique timestamps, so the locking within
krb5_crypto_us_timeofday() makes trace logging slower for no reason.
Add a new helper k5_us_timeofday(), which is merely a wrapper around
the existing get_time_now(), and use it in krb5int_trace().
[ghudson@mit.edu: edited commit message]
---
src/include/k5-int.h | 1 +
src/lib/krb5/os/c_ustime.c | 15 +++++++++++++++
src/lib/krb5/os/trace.c | 2 +-
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index fd79d7c..f492acb 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -697,6 +697,7 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context,
const krb5_keyblock *from,
krb5_keyblock *to);
+krb5_error_code k5_us_timeofday(krb5_timestamp *, krb5_int32 *);
krb5_error_code krb5_crypto_us_timeofday(krb5_timestamp *, krb5_int32 *);
/*
diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c
index f69f2ea..265c3b3 100644
--- a/src/lib/krb5/os/c_ustime.c
+++ b/src/lib/krb5/os/c_ustime.c
@@ -73,6 +73,21 @@ get_time_now(struct time_now *n)
#endif
+krb5_error_code
+k5_us_timeofday(krb5_timestamp *seconds, krb5_int32 *microseconds)
+{
+ struct time_now now;
+ krb5_error_code err;
+
+ err = get_time_now(&now);
+ if (err)
+ return err;
+
+ *seconds = now.sec;
+ *microseconds = now.usec;
+ return 0;
+}
+
static struct time_now last_time;
krb5_error_code
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index c4058dd..2af459d 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -411,7 +411,7 @@ krb5int_trace(krb5_context context, const char *fmt, ...)
str = trace_format(context, fmt, ap);
if (str == NULL)
goto cleanup;
- if (krb5_crypto_us_timeofday(&sec, &usec) != 0)
+ if (k5_us_timeofday(&sec, &usec) != 0)
goto cleanup;
if (asprintf(&msg, "[%d] %u.%06d: %s\n", (int)getpid(),
(unsigned int)sec, (int)usec, str) < 0)
--
2.43.0

View File

@ -1,621 +0,0 @@
From 871125fea8ce0370a972bf65f7d1de63f619b06c Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Thu, 22 Aug 2024 17:15:50 +0200
Subject: [PATCH] Generate and verify message MACs in libkrad
Implement some of the measures specified in
draft-ietf-radext-deprecating-radius-03 for mitigating the BlastRADIUS
attack (CVE-2024-3596):
* Include a Message-Authenticator MAC as the first attribute when
generating a packet of type Access-Request, Access-Reject,
Access-Accept, or Access-Challenge (sections 5.2.1 and 5.2.4), if
the secret is non-empty. (An empty secret indicates the use of Unix
domain socket transport.)
* Validate the Message-Authenticator MAC in received packets, if
present.
FreeRADIUS enforces Message-Authenticator as of versions 3.2.5 and
3.0.27. libkrad must generate Message-Authenticator attributes in
order to remain compatible with these implementations.
[ghudson@mit.edu: adjusted style and naming; simplified some
functions; edited commit message]
ticket: 9142 (new)
tags: pullup
target_version: 1.21-next
---
src/include/k5-int.h | 5 +
src/lib/crypto/krb/checksum_hmac_md5.c | 28 ++++
src/lib/crypto/libk5crypto.exports | 1 +
src/lib/krad/attr.c | 17 ++
src/lib/krad/attrset.c | 58 +++++--
src/lib/krad/internal.h | 7 +-
src/lib/krad/packet.c | 205 +++++++++++++++++++++++--
src/lib/krad/t_attrset.c | 2 +-
src/lib/krad/t_daemon.py | 3 +-
src/lib/krad/t_packet.c | 11 ++
src/tests/t_otp.py | 3 +
11 files changed, 309 insertions(+), 31 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 863d9fe9cf9..8143dbba75c 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2404,4 +2404,9 @@ krb5_boolean
k5_sname_compare(krb5_context context, krb5_const_principal sname,
krb5_const_principal princ);
+/* Generate an HMAC-MD5 keyed checksum as specified by RFC 2104. */
+krb5_error_code
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output);
+
#endif /* _KRB5_INT_H */
diff --git a/src/lib/crypto/krb/checksum_hmac_md5.c b/src/lib/crypto/krb/checksum_hmac_md5.c
index ec024f39661..a809388549f 100644
--- a/src/lib/crypto/krb/checksum_hmac_md5.c
+++ b/src/lib/crypto/krb/checksum_hmac_md5.c
@@ -92,3 +92,31 @@ krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp,
free(hash_iov);
return ret;
}
+
+krb5_error_code
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ krb5_error_code ret;
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+ krb5_keyblock keyblock = { 0 };
+ krb5_data hashed_key;
+ uint8_t hkeybuf[16];
+ krb5_crypto_iov iov;
+
+ /* Hash the key if it is longer than the block size. */
+ if (key->length > hash->blocksize) {
+ hashed_key = make_data(hkeybuf, sizeof(hkeybuf));
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *key;
+ ret = hash->hash(&iov, 1, &hashed_key);
+ if (ret)
+ return ret;
+ key = &hashed_key;
+ }
+
+ keyblock.magic = KV5M_KEYBLOCK;
+ keyblock.length = key->length;
+ keyblock.contents = (uint8_t *)key->data;
+ return krb5int_hmac_keyblock(hash, &keyblock, data, num_data, output);
+}
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 052f4d4b510..2b27028a0f5 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -103,3 +103,4 @@ krb5_c_prfplus
krb5_c_derive_prfplus
k5_enctype_to_ssf
krb5int_c_deprecated_enctype
+k5_hmac_md5
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
index 9c13d9d7556..4ad32122a8e 100644
--- a/src/lib/krad/attr.c
+++ b/src/lib/krad/attr.c
@@ -122,6 +122,23 @@ static const attribute_record attributes[UCHAR_MAX] = {
{"NAS-Port-Type", 4, 4, NULL, NULL},
{"Port-Limit", 4, 4, NULL, NULL},
{"Login-LAT-Port", 1, MAX_ATTRSIZE, NULL, NULL},
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Password-Retry */
+ {NULL, 0, 0, NULL, NULL}, /* Prompt */
+ {NULL, 0, 0, NULL, NULL}, /* Connect-Info */
+ {NULL, 0, 0, NULL, NULL}, /* Configuration-Token */
+ {NULL, 0, 0, NULL, NULL}, /* EAP-Message */
+ {"Message-Authenticator", MD5_DIGEST_SIZE, MD5_DIGEST_SIZE, NULL, NULL},
};
/* Encode User-Password attribute. */
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
index f309f1581c1..488bfce7bbb 100644
--- a/src/lib/krad/attrset.c
+++ b/src/lib/krad/attrset.c
@@ -164,14 +164,42 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
return 0;
}
+/* Place an encoded attributes into outbuf at position *i. Increment *i by the
+ * length of the encoding. */
+static krb5_error_code
+append_attr(krb5_context ctx, const char *secret,
+ const uint8_t *auth, krad_attr type, const krb5_data *data,
+ uint8_t outbuf[MAX_ATTRSETSIZE], size_t *i)
+{
+ uint8_t buffer[MAX_ATTRSIZE];
+ size_t attrlen;
+ krb5_error_code retval;
+
+ retval = kr_attr_encode(ctx, secret, auth, type, data, buffer, &attrlen);
+ if (retval)
+ return retval;
+
+ if (attrlen > MAX_ATTRSETSIZE - *i - 2)
+ return EMSGSIZE;
+
+ outbuf[(*i)++] = type;
+ outbuf[(*i)++] = attrlen + 2;
+ memcpy(outbuf + *i, buffer, attrlen);
+ *i += attrlen;
+
+ return 0;
+}
+
krb5_error_code
kr_attrset_encode(const krad_attrset *set, const char *secret,
- const unsigned char *auth,
+ const uint8_t *auth, krb5_boolean add_msgauth,
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen)
{
- unsigned char buffer[MAX_ATTRSIZE];
krb5_error_code retval;
- size_t i = 0, attrlen;
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ const uint8_t zeroes[MD5_DIGEST_SIZE] = { 0 };
+ krb5_data zerodata;
+ size_t i = 0;
attr *a;
if (set == NULL) {
@@ -179,19 +207,21 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
return 0;
}
- K5_TAILQ_FOREACH(a, &set->list, list) {
- retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
- buffer, &attrlen);
- if (retval != 0)
+ if (add_msgauth) {
+ /* Encode Message-Authenticator as the first attribute, per
+ * draft-ietf-radext-deprecating-radius-03 section 5.2. */
+ zerodata = make_data((uint8_t *)zeroes, MD5_DIGEST_SIZE);
+ retval = append_attr(set->ctx, secret, auth, msgauth_type, &zerodata,
+ outbuf, &i);
+ if (retval)
return retval;
+ }
- if (i + attrlen + 2 > MAX_ATTRSETSIZE)
- return EMSGSIZE;
-
- outbuf[i++] = a->type;
- outbuf[i++] = attrlen + 2;
- memcpy(&outbuf[i], buffer, attrlen);
- i += attrlen;
+ K5_TAILQ_FOREACH(a, &set->list, list) {
+ retval = append_attr(set->ctx, secret, auth, a->type, &a->attr,
+ outbuf, &i);
+ if (retval)
+ return retval;
}
*outlen = i;
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
index 7619563fc56..e2a16c77a64 100644
--- a/src/lib/krad/internal.h
+++ b/src/lib/krad/internal.h
@@ -43,6 +43,8 @@
#define UCHAR_MAX 255
#endif
+#define MD5_DIGEST_SIZE 16
+
/* RFC 2865 */
#define MAX_ATTRSIZE (UCHAR_MAX - 2)
#define MAX_ATTRSETSIZE (KRAD_PACKET_SIZE_MAX - 20)
@@ -65,10 +67,11 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
krad_attr type, const krb5_data *in,
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
-/* Encode the attributes into the buffer. */
+/* Encode set into outbuf. If add_msgauth is true, include a zeroed
+ * Message-Authenticator as the first attribute. */
krb5_error_code
kr_attrset_encode(const krad_attrset *set, const char *secret,
- const unsigned char *auth,
+ const uint8_t *auth, krb5_boolean add_msgauth,
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen);
/* Decode attributes from a buffer. */
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
index aee830b651f..7e599ab39bd 100644
--- a/src/lib/krad/packet.c
+++ b/src/lib/krad/packet.c
@@ -36,6 +36,7 @@
typedef unsigned char uchar;
/* RFC 2865 */
+#define MSGAUTH_SIZE (2 + MD5_DIGEST_SIZE)
#define OFFSET_CODE 0
#define OFFSET_ID 1
#define OFFSET_LENGTH 2
@@ -222,6 +223,106 @@ packet_set_attrset(krb5_context ctx, const char *secret, krad_packet *pkt)
return kr_attrset_decode(ctx, &tmp, secret, pkt_auth(pkt), &pkt->attrset);
}
+/* Determine if a packet requires a Message-Authenticator attribute. */
+static inline krb5_boolean
+requires_msgauth(const char *secret, krad_code code)
+{
+ /* If no secret is provided, assume that the transport is a UNIX socket.
+ * Message-Authenticator is required only on UDP and TCP connections. */
+ if (*secret == '\0')
+ return FALSE;
+
+ /*
+ * Per draft-ietf-radext-deprecating-radius-03 sections 5.2.1 and 5.2.4,
+ * Message-Authenticator is required in Access-Request packets and all
+ * potential responses when UDP or TCP transport is used.
+ */
+ return code == krad_code_name2num("Access-Request") ||
+ code == krad_code_name2num("Access-Reject") ||
+ code == krad_code_name2num("Access-Accept") ||
+ code == krad_code_name2num("Access-Challenge");
+}
+
+/* Check if the packet has a Message-Authenticator attribute. */
+static inline krb5_boolean
+has_pkt_msgauth(const krad_packet *pkt)
+{
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+
+ return krad_attrset_get(pkt->attrset, msgauth_type, 0) != NULL;
+}
+
+/* Return the beginning of the Message-Authenticator attribute in pkt, or NULL
+ * if no such attribute is present. */
+static const uint8_t *
+lookup_msgauth_addr(const krad_packet *pkt)
+{
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ size_t i;
+ uint8_t *p;
+
+ i = OFFSET_ATTR;
+ while (i + 2 < pkt->pkt.length) {
+ p = (uint8_t *)offset(&pkt->pkt, i);
+ if (msgauth_type == *p)
+ return p;
+ i += p[1];
+ }
+
+ return NULL;
+}
+
+/*
+ * Calculate the message authenticator MAC for pkt as specified in RFC 2869
+ * section 5.14, placing the result in mac_out. Use the provided authenticator
+ * auth, which may be from pkt or from a corresponding request.
+ */
+static krb5_error_code
+calculate_mac(const char *secret, const krad_packet *pkt,
+ const uint8_t auth[AUTH_FIELD_SIZE],
+ uint8_t mac_out[MD5_DIGEST_SIZE])
+{
+ uint8_t zeroed_msgauth[MSGAUTH_SIZE];
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ const uint8_t *msgauth_attr, *msgauth_end, *pkt_end;
+ krb5_crypto_iov input[5];
+ krb5_data ksecr, mac;
+
+ msgauth_attr = lookup_msgauth_addr(pkt);
+ if (msgauth_attr == NULL)
+ return EINVAL;
+ msgauth_end = msgauth_attr + MSGAUTH_SIZE;
+ pkt_end = (const uint8_t *)pkt->pkt.data + pkt->pkt.length;
+
+ /* Read code, id, and length from the packet. */
+ input[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[0].data = make_data(pkt->pkt.data, OFFSET_AUTH);
+
+ /* Read the provided authenticator. */
+ input[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[1].data = make_data((uint8_t *)auth, AUTH_FIELD_SIZE);
+
+ /* Read any attributes before Message-Authenticator. */
+ input[2].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[2].data = make_data(pkt_attr(pkt), msgauth_attr - pkt_attr(pkt));
+
+ /* Read Message-Authenticator with the data bytes all set to zero, per RFC
+ * 2869 section 5.14. */
+ zeroed_msgauth[0] = msgauth_type;
+ zeroed_msgauth[1] = MSGAUTH_SIZE;
+ memset(zeroed_msgauth + 2, 0, MD5_DIGEST_SIZE);
+ input[3].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[3].data = make_data(zeroed_msgauth, MSGAUTH_SIZE);
+
+ /* Read any attributes after Message-Authenticator. */
+ input[4].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[4].data = make_data((uint8_t *)msgauth_end, pkt_end - msgauth_end);
+
+ mac = make_data(mac_out, MD5_DIGEST_SIZE);
+ ksecr = string2data((char *)secret);
+ return k5_hmac_md5(&ksecr, input, 5, &mac);
+}
+
ssize_t
krad_packet_bytes_needed(const krb5_data *buffer)
{
@@ -255,6 +356,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
krad_packet *pkt;
uchar id;
size_t attrset_len;
+ krb5_boolean msgauth_required;
pkt = packet_new();
if (pkt == NULL) {
@@ -274,9 +376,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
if (retval != 0)
goto error;
+ /* Determine if Message-Authenticator is required. */
+ msgauth_required = (*secret != '\0' &&
+ code == krad_code_name2num("Access-Request"));
+
/* Encode the attributes. */
- retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
- &attrset_len);
+ retval = kr_attrset_encode(set, secret, pkt_auth(pkt), msgauth_required,
+ pkt_attr(pkt), &attrset_len);
if (retval != 0)
goto error;
@@ -285,6 +391,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
pkt_code_set(pkt, code);
pkt_len_set(pkt, pkt->pkt.length);
+ if (msgauth_required) {
+ /* Calculate and set the Message-Authenticator MAC. */
+ retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2);
+ if (retval != 0)
+ goto error;
+ }
+
/* Copy the attrset for future use. */
retval = packet_set_attrset(ctx, secret, pkt);
if (retval != 0)
@@ -307,14 +420,18 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
krb5_error_code retval;
krad_packet *pkt;
size_t attrset_len;
+ krb5_boolean msgauth_required;
pkt = packet_new();
if (pkt == NULL)
return ENOMEM;
+ /* Determine if Message-Authenticator is required. */
+ msgauth_required = requires_msgauth(secret, code);
+
/* Encode the attributes. */
- retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
- &attrset_len);
+ retval = kr_attrset_encode(set, secret, pkt_auth(request),
+ msgauth_required, pkt_attr(pkt), &attrset_len);
if (retval != 0)
goto error;
@@ -330,6 +447,18 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
if (retval != 0)
goto error;
+ if (msgauth_required) {
+ /*
+ * Calculate and replace the Message-Authenticator MAC. Per RFC 2869
+ * section 5.14, use the authenticator from the request, not from the
+ * response.
+ */
+ retval = calculate_mac(secret, pkt, pkt_auth(request),
+ pkt_attr(pkt) + 2);
+ if (retval != 0)
+ goto error;
+ }
+
/* Copy the attrset for future use. */
retval = packet_set_attrset(ctx, secret, pkt);
if (retval != 0)
@@ -343,6 +472,34 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
return retval;
}
+/* Verify the Message-Authenticator value in pkt, using the provided
+ * authenticator (which may be from pkt or from a corresponding request). */
+static krb5_error_code
+verify_msgauth(const char *secret, const krad_packet *pkt,
+ const uint8_t auth[AUTH_FIELD_SIZE])
+{
+ uint8_t mac[MD5_DIGEST_SIZE];
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ const krb5_data *msgauth;
+ krb5_error_code retval;
+
+ msgauth = krad_packet_get_attr(pkt, msgauth_type, 0);
+ if (msgauth == NULL)
+ return ENODATA;
+
+ retval = calculate_mac(secret, pkt, auth, mac);
+ if (retval)
+ return retval;
+
+ if (msgauth->length != MD5_DIGEST_SIZE)
+ return EMSGSIZE;
+
+ if (k5_bcmp(mac, msgauth->data, MD5_DIGEST_SIZE) != 0)
+ return EBADMSG;
+
+ return 0;
+}
+
/* Decode a packet. */
static krb5_error_code
decode_packet(krb5_context ctx, const char *secret, const krb5_data *buffer,
@@ -394,21 +551,35 @@ krad_packet_decode_request(krb5_context ctx, const char *secret,
krad_packet **reqpkt)
{
const krad_packet *tmp = NULL;
+ krad_packet *req;
krb5_error_code retval;
- retval = decode_packet(ctx, secret, buffer, reqpkt);
- if (cb != NULL && retval == 0) {
+ retval = decode_packet(ctx, secret, buffer, &req);
+ if (retval)
+ return retval;
+
+ /* Verify Message-Authenticator if present. */
+ if (has_pkt_msgauth(req)) {
+ retval = verify_msgauth(secret, req, pkt_auth(req));
+ if (retval) {
+ krad_packet_free(req);
+ return retval;
+ }
+ }
+
+ if (cb != NULL) {
for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) {
if (pkt_id_get(*reqpkt) == pkt_id_get(tmp))
break;
}
- }
- if (cb != NULL && (retval != 0 || tmp != NULL))
- (*cb)(data, TRUE);
+ if (tmp != NULL)
+ (*cb)(data, TRUE);
+ }
+ *reqpkt = req;
*duppkt = tmp;
- return retval;
+ return 0;
}
krb5_error_code
@@ -435,9 +606,17 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
break;
}
- /* If the authenticator matches, then the response is valid. */
- if (memcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) == 0)
- break;
+ /* Verify the response authenticator. */
+ if (k5_bcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) != 0)
+ continue;
+
+ /* Verify Message-Authenticator if present. */
+ if (has_pkt_msgauth(*rsppkt)) {
+ if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0)
+ continue;
+ }
+
+ break;
}
}
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
index 085f4b25d72..a520fe10ebd 100644
--- a/src/lib/krad/t_attrset.c
+++ b/src/lib/krad/t_attrset.c
@@ -62,7 +62,7 @@ main(void)
noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
/* Encode attrset. */
- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len));
+ noerror(kr_attrset_encode(set, "foo", auth, FALSE, buffer, &encode_len));
krad_attrset_free(set);
/* Manually encode User-Name. */
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
index 4a3de079c7d..647d4894eb8 100755
--- a/src/lib/krad/t_daemon.py
+++ b/src/lib/krad/t_daemon.py
@@ -40,6 +40,7 @@
ATTRIBUTE\tUser-Name\t1\tstring
ATTRIBUTE\tUser-Password\t2\toctets
ATTRIBUTE\tNAS-Identifier\t32\tstring
+ATTRIBUTE\tMessage-Authenticator\t80\toctets
"""
class TestServer(server.Server):
@@ -52,7 +53,7 @@ def _HandleAuthPacket(self, pkt):
if key == "User-Password":
passwd = [pkt.PwDecrypt(x) for x in pkt[key]]
- reply = self.CreateReplyPacket(pkt)
+ reply = self.CreateReplyPacket(pkt, message_authenticator=True)
if passwd == ['accept']:
reply.code = packet.AccessAccept
else:
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
index c22489144f4..104b6507a26 100644
--- a/src/lib/krad/t_packet.c
+++ b/src/lib/krad/t_packet.c
@@ -172,6 +172,9 @@ main(int argc, const char **argv)
krb5_data username, password;
krb5_boolean auth = FALSE;
krb5_context ctx;
+ const krad_packet *dupreq;
+ const krb5_data *encpkt;
+ krad_packet *decreq;
username = string2data("testUser");
@@ -184,9 +187,17 @@ main(int argc, const char **argv)
password = string2data("accept");
noerror(make_packet(ctx, &username, &password, &packets[ACCEPT_PACKET]));
+ encpkt = krad_packet_encode(packets[ACCEPT_PACKET]);
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
+ &dupreq, &decreq));
+ krad_packet_free(decreq);
password = string2data("reject");
noerror(make_packet(ctx, &username, &password, &packets[REJECT_PACKET]));
+ encpkt = krad_packet_encode(packets[REJECT_PACKET]);
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
+ &dupreq, &decreq));
+ krad_packet_free(decreq);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
index c3b820a411d..dd5cdc5c26d 100755
--- a/src/tests/t_otp.py
+++ b/src/tests/t_otp.py
@@ -49,6 +49,7 @@
ATTRIBUTE User-Password 2 octets
ATTRIBUTE Service-Type 6 integer
ATTRIBUTE NAS-Identifier 32 string
+ATTRIBUTE Message-Authenticator 80 octets
'''
class RadiusDaemon(Process):
@@ -97,6 +98,8 @@ def run(self):
reply.code = packet.AccessReject
replyq['reply'] = False
+ reply.add_message_authenticator()
+
outq.put(replyq)
if addr is None:
sock.send(reply.ReplyPacket())

View File

@ -1,59 +0,0 @@
From 78ceba024b64d49612375be4a12d1c066b0bfbd0 Mon Sep 17 00:00:00 2001
From: Zoltan Borbely <Zoltan.Borbely@morganstanley.com>
Date: Tue, 28 Jan 2025 16:39:25 -0500
Subject: [PATCH] Prevent overflow when calculating ulog block size
In kdb_log.c:resize(), log an error and fail if the update size is
larger than the largest possible block size (2^16-1).
CVE-2025-24528:
In MIT krb5 release 1.7 and later with incremental propagation
enabled, an authenticated attacker can cause kadmind to write beyond
the end of the mapped region for the iprop log file, likely causing a
process crash.
[ghudson@mit.edu: edited commit message and added CVE description]
ticket: 9159 (new)
tags: pullup
target_version: 1.21-next
---
src/lib/kdb/kdb_log.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
index 2659a250187..68fae919a52 100644
--- a/src/lib/kdb/kdb_log.c
+++ b/src/lib/kdb/kdb_log.c
@@ -183,7 +183,7 @@ extend_file_to(int fd, unsigned int new_size)
*/
static krb5_error_code
resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
- unsigned int recsize)
+ unsigned int recsize, const kdb_incr_update_t *upd)
{
unsigned int new_block, new_size;
@@ -195,6 +195,12 @@ resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
new_block *= ULOG_BLOCK;
new_size += ulogentries * new_block;
+ if (new_block > UINT16_MAX) {
+ syslog(LOG_ERR, _("ulog overflow caused by principal %.*s"),
+ upd->kdb_princ_name.utf8str_t_len,
+ upd->kdb_princ_name.utf8str_t_val);
+ return KRB5_LOG_ERROR;
+ }
if (new_size > MAXLOGLEN)
return KRB5_LOG_ERROR;
@@ -291,7 +297,7 @@ store_update(kdb_log_context *log_ctx, kdb_incr_update_t *upd)
recsize = sizeof(kdb_ent_header_t) + upd_size;
if (recsize > ulog->kdb_block) {
- retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize);
+ retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize, upd);
if (retval)
return retval;
}

View File

@ -1,30 +0,0 @@
From 85c93922232300b0316546a2fc6dd93c7e2906cd Mon Sep 17 00:00:00 2001
From: Feng Guo <gardonkoo@163.com>
Date: Thu, 28 Nov 2024 21:32:37 +0800
Subject: [PATCH] Fix LDAP module leak on authentication error
In initialize_server(), unbind the server handle if authenticate()
fails.
[ghudson@mit.edu: rewrote commit message]
ticket: 9153 (new)
---
src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c | 1 +
1 file changed, 1 insertion(+)
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 5e77d5e49..d19e2b761 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c
@@ -189,6 +189,7 @@ initialize_server(krb5_ldap_context *ldap_context, krb5_ldap_server_info *info)
if (ret) {
info->server_status = OFF;
time(&info->downtime);
+ ldap_unbind_ext_s(server->ldap_handle, NULL, NULL);
free(server);
return ret;
}
--
2.33.0

View File

@ -1,48 +0,0 @@
From 6f6d795be8d0dd0a46952cf8afa59b65d71df744 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 3 Oct 2024 18:40:04 +0200
Subject: [PATCH] Fix krb5_crypto_us_timeofday() microseconds check
Commit a60db180211a383bd382afe729e9309acb8dcf53 mistakenly reversed
the sense of the krb5_crypto_us_timeofday() conditional that enforces
fowards movement of the microseconds value within a second. Moreover,
the macros ts_after() and ts_incr() should not have been applied to
non-timestamp values. Revert the incorrect changes.
[ghudson@mit.edu: rewrote commit message]
ticket: 9141 (new)
tags: pullup
target_version: 1.21-next
Reference:https://github.com/krb5/krb5/commit/6f6d795be8d0dd0a46952cf8afa59b65d71df744
Conflict:NA
---
src/lib/krb5/os/c_ustime.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c
index f69f2ea4c..7019ea197 100644
--- a/src/lib/krb5/os/c_ustime.c
+++ b/src/lib/krb5/os/c_ustime.c
@@ -106,14 +106,14 @@ krb5_crypto_us_timeofday(krb5_timestamp *seconds, krb5_int32 *microseconds)
need to properly handle the case where the administrator intentionally
adjusted time backwards. */
if (now.sec == ts_incr(last_time.sec, -1) ||
- (now.sec == last_time.sec && !ts_after(last_time.usec, now.usec))) {
+ (now.sec == last_time.sec && now.usec <= last_time.usec)) {
/* Correct 'now' to be exactly one microsecond later than 'last_time'.
Note that _because_ we perform this hack, 'now' may be _earlier_
than 'last_time', even though the system time is monotonically
increasing. */
now.sec = last_time.sec;
- now.usec = ts_incr(last_time.usec, 1);
+ now.usec = last_time.usec + 1;
if (now.usec >= 1000000) {
now.sec = ts_incr(now.sec, 1);
now.usec = 0;
--
2.33.0

View File

@ -1,32 +0,0 @@
From 0a23b0cd9466e8a7c6fb82fce185be6e0834ce26 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 27 Oct 2024 19:01:51 -0400
Subject: [PATCH] Fix krb5_ldap_list_policy() filtering loop
The loop at the end of this function is intended to ignore ticket
policy DNs that can't be converted to names. But it instead leaves a
hole in the output list if that happens, effectively truncating the
list and leaking any subsequent entries. Use the correct index for
the output list.
ticket: 9148 (new)
---
src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c
index 4f48fd6..27a2235 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c
@@ -382,7 +382,7 @@ krb5_ldap_list_policy(krb5_context context, char *containerdn, char ***policy)
for (i = 0, j = 0; list[i] != NULL; i++, j++) {
int ret;
- ret = krb5_ldap_policydn_to_name (context, list[i], &(*policy)[i]);
+ ret = krb5_ldap_policydn_to_name (context, list[i], &(*policy)[j]);
if (ret != 0)
j--;
}
--
2.43.0

View File

@ -1,517 +0,0 @@
From e50f46b210ddafe85cc917e2571516ade46bc65f Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 17 Nov 2024 13:54:12 -0500
Subject: [PATCH] Fix minor logic errors
In k5_externalize_auth_context(), serialize the correct field when
remote_port is set. This is not a reachable bug because the function
is only accessible via gss_export_sec_context(), and the GSS library
does not set a remote port.
In generic_gss_oid_to_str(), remove an inconsistently-applied test for
a null minor_status. Also remove minor_status null checks from
generic_gss_release_oid() and generic_gss_str_to_oid(), but add output
initializations and pointer checks to the API functions in g_oid_ops.c
in a similar manner to other GSSAPI functions. Remove
gssint_copy_oid_set() and replace its one call with a call to
generic_gss_copy_oid_set().
In the checksum functions, avoid crashing if the caller passes a null
key and checksum type 0. An error will be returned instead when
find_cksumtype() can't find the checksum type.
(krb5_k_verify_checksum() already had this check.)
In pkinit_open_session(), remove an unnecessary null check for
ctx->p11_module_name, and add a check for p11name being null due to an
asprintf() failure.
In profile_add_node(), add a check for null ret_node in the duplicate
subsection check. This is not a reachable bug because the function is
currently never called with null ret_node and null value.
In ksu's main(), check for krb5_cc_default_name() returning NULL
(which only happens on allocation failure). Also clean up some
vestiges left behind by commit
9ebae7cb434b9b177c0af85c67a6d6267f46bc68.
In ksu's get_authorized_princ_names(), close login_fp if we fail to
open k5users_path.
In the KDC and kpropd write_pid_file(), avoid briefly leaking the file
handle on write failure.
Reported by Valery Fedorenko.
Conflict:src/lib/gssapi/mechglue/g_oid_ops.c,src/kdc/main.c
---
src/clients/ksu/heuristic.c | 5 +-
src/clients/ksu/main.c | 30 +++-------
src/kadmin/server/ovsec_kadmd.c | 26 +++------
src/kdc/main.c | 9 +--
src/kprop/kpropd.c | 7 ++-
src/lib/crypto/krb/make_checksum.c | 2 +-
src/lib/crypto/krb/make_checksum_iov.c | 2 +-
src/lib/crypto/krb/verify_checksum_iov.c | 2 +-
src/lib/gssapi/generic/oid_ops.c | 9 +--
src/lib/gssapi/mechglue/g_oid_ops.c | 58 +++++++++++++++----
src/lib/gssapi/mechglue/mglueP.h | 6 --
src/lib/gssapi/spnego/spnego_mech.c | 2 +-
src/lib/krb5/krb/ser_actx.c | 2 +-
.../preauth/pkinit/pkinit_crypto_openssl.c | 30 +++++-----
src/util/profile/prof_tree.c | 3 +-
15 files changed, 104 insertions(+), 89 deletions(-)
diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c
index 47baa78..962b794 100644
--- a/src/clients/ksu/heuristic.c
+++ b/src/clients/ksu/heuristic.c
@@ -237,8 +237,11 @@ get_authorized_princ_names(luser, cmd, princ_list)
}
}
if (!k5users_flag){
- if ((users_fp = fopen(k5users_path, "r")) == NULL)
+ users_fp = fopen(k5users_path, "r");
+ if (users_fp == NULL) {
+ close_time(1, NULL, k5login_flag, login_fp);
return 0;
+ }
if ( fowner(users_fp, pwd->pw_uid) == FALSE){
close_time(k5users_flag,users_fp, k5login_flag,login_fp);
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index a7cb7ed..35ecf1b 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -107,7 +107,6 @@ main (argc, argv)
krb5_ccache cc_source = NULL;
const char * cc_source_tag = NULL;
- const char * cc_source_tag_tmp = NULL;
char * cmd = NULL, * exec_cmd = NULL;
int errflg = 0;
krb5_boolean auth_val;
@@ -281,23 +280,13 @@ main (argc, argv)
case 'c':
if (cc_source_tag == NULL) {
cc_source_tag = xstrdup(optarg);
- if ( strchr(cc_source_tag, ':')){
- cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1;
-
- if (!ks_ccache_name_is_initialized(ksu_context,
- cc_source_tag)) {
- com_err(prog_name, errno,
- _("while looking for credentials cache %s"),
- cc_source_tag_tmp);
- exit (1);
- }
- }
- else {
- fprintf(stderr, _("malformed credential cache name %s\n"),
+ if (!ks_ccache_name_is_initialized(ksu_context,
+ cc_source_tag)) {
+ com_err(prog_name, errno,
+ _("while looking for credentials cache %s"),
cc_source_tag);
- errflg++;
+ exit(1);
}
-
} else {
fprintf(stderr, _("Only one -c option allowed\n"));
errflg++;
@@ -381,11 +370,10 @@ main (argc, argv)
if (cc_source_tag == NULL){
cc_source_tag = krb5_cc_default_name(ksu_context);
- cc_source_tag_tmp = strchr(cc_source_tag, ':');
- if (cc_source_tag_tmp == 0)
- cc_source_tag_tmp = cc_source_tag;
- else
- cc_source_tag_tmp++;
+ if (cc_source_tag == NULL) {
+ fprintf(stderr, _("ksu: failed to get default ccache name\n"));
+ exit(1);
+ }
}
/* get a handle for the cache */
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 73d9bac..fe78ad6 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -239,7 +239,7 @@ log_badverf(gss_name_t client_name, gss_name_t server_name,
OM_uint32 minor;
gss_buffer_desc client, server;
gss_OID gss_type;
- const char *a;
+ const char *a, *cname, *sname;
rpcproc_t proc;
unsigned int i;
const char *procname;
@@ -253,19 +253,11 @@ log_badverf(gss_name_t client_name, gss_name_t server_name,
(void)gss_display_name(&minor, client_name, &client, &gss_type);
(void)gss_display_name(&minor, server_name, &server, &gss_type);
- if (client.value == NULL) {
- client.value = "(null)";
- clen = sizeof("(null)") - 1;
- } else {
- clen = client.length;
- }
+ cname = (client.value == NULL) ? "(null)" : client.value;
+ clen = (client.value == NULL) ? sizeof("(null)") - 1 : client.length;
trunc_name(&clen, &cdots);
- if (server.value == NULL) {
- server.value = "(null)";
- slen = sizeof("(null)") - 1;
- } else {
- slen = server.length;
- }
+ sname = (server.value == NULL) ? "(null)" : server.value;
+ slen = (server.value == NULL) ? sizeof("(null)") - 1 : server.length;
trunc_name(&slen, &sdots);
a = client_addr(rqst->rq_xprt);
@@ -281,14 +273,14 @@ log_badverf(gss_name_t client_name, gss_name_t server_name,
krb5_klog_syslog(LOG_NOTICE,
_("WARNING! Forged/garbled request: %s, claimed "
"client = %.*s%s, server = %.*s%s, addr = %s"),
- procname, (int)clen, (char *)client.value, cdots,
- (int)slen, (char *)server.value, sdots, a);
+ procname, (int)clen, cname, cdots, (int)slen, sname,
+ sdots, a);
} else {
krb5_klog_syslog(LOG_NOTICE,
_("WARNING! Forged/garbled request: %d, claimed "
"client = %.*s%s, server = %.*s%s, addr = %s"),
- proc, (int)clen, (char *)client.value, cdots,
- (int)slen, (char *)server.value, sdots, a);
+ proc, (int)clen, cname, cdots, (int)slen, sname,
+ sdots, a);
}
(void)gss_release_buffer(&minor, &client);
diff --git a/src/kdc/main.c b/src/kdc/main.c
index d30e6cd..f11f141 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -871,14 +871,15 @@ write_pid_file(const char *path)
{
FILE *file;
unsigned long pid;
+ int st1, st2;
file = WRITABLEFOPEN(path, "w");
if (file == NULL)
return errno;
- pid = (unsigned long) getpid();
- if (fprintf(file, "%ld\n", pid) < 0 || fclose(file) == EOF)
- return errno;
- return 0;
+ pid = (unsigned long)getpid();
+ st1 = (fprintf(file, "%ld\n", pid) < 0) ? errno : 0;
+ st2 = (fclose(file) == EOF) ? errno : 0;
+ return st1 ? st1 : st2;
}
static void
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
index e0500d4..724ed95 100644
--- a/src/kprop/kpropd.c
+++ b/src/kprop/kpropd.c
@@ -180,14 +180,15 @@ write_pid_file(const char *path)
{
FILE *fp;
unsigned long pid;
+ int st1, st2;
fp = fopen(path, "w");
if (fp == NULL)
return errno;
pid = (unsigned long)getpid();
- if (fprintf(fp, "%ld\n", pid) < 0 || fclose(fp) == EOF)
- return errno;
- return 0;
+ st1 = (fprintf(fp, "%ld\n", pid) < 0) ? errno : 0;
+ st2 = (fclose(fp) == EOF) ? errno : 0;
+ return st1 ? st1 : st2;
}
typedef void (*sig_handler_fn)(int sig);
diff --git a/src/lib/crypto/krb/make_checksum.c b/src/lib/crypto/krb/make_checksum.c
index 398c84a..3c57e41 100644
--- a/src/lib/crypto/krb/make_checksum.c
+++ b/src/lib/crypto/krb/make_checksum.c
@@ -40,7 +40,7 @@ krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
krb5_octet *trunc;
krb5_error_code ret;
- if (cksumtype == 0) {
+ if (cksumtype == 0 && key != NULL) {
ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype,
&cksumtype);
if (ret != 0)
diff --git a/src/lib/crypto/krb/make_checksum_iov.c b/src/lib/crypto/krb/make_checksum_iov.c
index 84e98b1..c9e9da8 100644
--- a/src/lib/crypto/krb/make_checksum_iov.c
+++ b/src/lib/crypto/krb/make_checksum_iov.c
@@ -39,7 +39,7 @@ krb5_k_make_checksum_iov(krb5_context context,
krb5_crypto_iov *checksum;
const struct krb5_cksumtypes *ctp;
- if (cksumtype == 0) {
+ if (cksumtype == 0 && key != NULL) {
ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype,
&cksumtype);
if (ret != 0)
diff --git a/src/lib/crypto/krb/verify_checksum_iov.c b/src/lib/crypto/krb/verify_checksum_iov.c
index 47a25a9..532e45c 100644
--- a/src/lib/crypto/krb/verify_checksum_iov.c
+++ b/src/lib/crypto/krb/verify_checksum_iov.c
@@ -40,7 +40,7 @@ krb5_k_verify_checksum_iov(krb5_context context,
krb5_data computed;
krb5_crypto_iov *checksum;
- if (checksum_type == 0) {
+ if (checksum_type == 0 && key != NULL) {
ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype,
&checksum_type);
if (ret != 0)
diff --git a/src/lib/gssapi/generic/oid_ops.c b/src/lib/gssapi/generic/oid_ops.c
index 253d646..0d65a95 100644
--- a/src/lib/gssapi/generic/oid_ops.c
+++ b/src/lib/gssapi/generic/oid_ops.c
@@ -68,8 +68,7 @@
OM_uint32
generic_gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
{
- if (minor_status)
- *minor_status = 0;
+ *minor_status = 0;
if (oid == NULL || *oid == GSS_C_NO_OID)
return(GSS_S_COMPLETE);
@@ -245,8 +244,7 @@ generic_gss_oid_to_str(OM_uint32 *minor_status,
unsigned char *cp;
struct k5buf buf;
- if (minor_status != NULL)
- *minor_status = 0;
+ *minor_status = 0;
if (oid_str != GSS_C_NO_BUFFER) {
oid_str->length = 0;
@@ -353,8 +351,7 @@ generic_gss_str_to_oid(OM_uint32 *minor_status,
int brace = 0;
gss_OID oid;
- if (minor_status != NULL)
- *minor_status = 0;
+ *minor_status = 0;
if (oid_out != NULL)
*oid_out = GSS_C_NO_OID;
diff --git a/src/lib/gssapi/mechglue/g_oid_ops.c b/src/lib/gssapi/mechglue/g_oid_ops.c
index 1d7970c..035da76 100644
--- a/src/lib/gssapi/mechglue/g_oid_ops.c
+++ b/src/lib/gssapi/mechglue/g_oid_ops.c
@@ -38,6 +38,13 @@ gss_create_empty_oid_set(minor_status, oid_set)
gss_OID_set *oid_set;
{
OM_uint32 status;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+ if (oid_set != NULL)
+ *oid_set = GSS_C_NO_OID_SET;
+ if (minor_status == NULL || oid_set == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
status = generic_gss_create_empty_oid_set(minor_status, oid_set);
if (status != GSS_S_COMPLETE)
map_errcode(minor_status);
@@ -51,6 +58,14 @@ gss_add_oid_set_member(minor_status, member_oid, oid_set)
gss_OID_set *oid_set;
{
OM_uint32 status;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+ if (minor_status == NULL || oid_set == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ if (member_oid == GSS_C_NO_OID || member_oid->length == 0 ||
+ member_oid->elements == NULL)
+ return GSS_S_CALL_INACCESSIBLE_READ;
status = generic_gss_add_oid_set_member(minor_status, member_oid, oid_set);
if (status != GSS_S_COMPLETE)
map_errcode(minor_status);
@@ -64,6 +79,14 @@ gss_test_oid_set_member(minor_status, member, set, present)
gss_OID_set set;
int *present;
{
+ if (minor_status != NULL)
+ *minor_status = 0;
+ if (present != NULL)
+ *present = 0;
+ if (minor_status == NULL || present == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ if (member == GSS_C_NO_OID || set == GSS_C_NO_OID_SET)
+ return GSS_S_CALL_INACCESSIBLE_READ;
return generic_gss_test_oid_set_member(minor_status, member, set, present);
}
@@ -73,7 +96,19 @@ gss_oid_to_str(minor_status, oid, oid_str)
gss_OID oid;
gss_buffer_t oid_str;
{
- OM_uint32 status = generic_gss_oid_to_str(minor_status, oid, oid_str);
+ OM_uint32 status;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+ if (oid_str != GSS_C_NO_BUFFER) {
+ oid_str->length = 0;
+ oid_str->value = NULL;
+ }
+ if (minor_status == NULL || oid_str == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ if (oid == GSS_C_NO_OID || oid->length == 0 || oid->elements == NULL)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ status = generic_gss_oid_to_str(minor_status, oid, oid_str);
if (status != GSS_S_COMPLETE)
map_errcode(minor_status);
return status;
@@ -85,21 +120,22 @@ gss_str_to_oid(minor_status, oid_str, oid)
gss_buffer_t oid_str;
gss_OID *oid;
{
- OM_uint32 status = generic_gss_str_to_oid(minor_status, oid_str, oid);
+ OM_uint32 status;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+ if (oid != NULL)
+ *oid = GSS_C_NO_OID;
+ if (minor_status == NULL || oid == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ if (GSS_EMPTY_BUFFER(oid_str))
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ status = generic_gss_str_to_oid(minor_status, oid_str, oid);
if (status != GSS_S_COMPLETE)
map_errcode(minor_status);
return status;
}
-OM_uint32
-gssint_copy_oid_set(
- OM_uint32 *minor_status,
- const gss_OID_set_desc * const oidset,
- gss_OID_set *new_oidset)
-{
- return generic_gss_copy_oid_set(minor_status, oidset, new_oidset);
-}
-
int KRB5_CALLCONV
gss_oid_equal(
gss_const_OID first_oid,
diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
index 2b65939..f66a54a 100644
--- a/src/lib/gssapi/mechglue/mglueP.h
+++ b/src/lib/gssapi/mechglue/mglueP.h
@@ -806,12 +806,6 @@ OM_uint32 gssint_create_union_context(
gss_union_ctx_id_t * /* ctx_out */
);
-OM_uint32 gssint_copy_oid_set(
- OM_uint32 *, /* minor_status */
- const gss_OID_set_desc * const, /* oid set */
- gss_OID_set * /* new oid set */
-);
-
gss_OID gss_find_mechanism_from_name_type (gss_OID); /* name_type */
OM_uint32 gss_add_mech_name_type
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 654964c..f8b50d8 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -401,7 +401,7 @@ spnego_gss_acquire_cred_from(OM_uint32 *minor_status,
&amechs, time_rec);
if (actual_mechs && amechs != GSS_C_NULL_OID_SET) {
- (void) gssint_copy_oid_set(&tmpmin, amechs, actual_mechs);
+ (void) generic_gss_copy_oid_set(&tmpmin, amechs, actual_mechs);
}
(void) gss_release_oid_set(&tmpmin, &amechs);
diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c
index 6de35a1..ed8e255 100644
--- a/src/lib/krb5/krb/ser_actx.c
+++ b/src/lib/krb5/krb/ser_actx.c
@@ -171,7 +171,7 @@ k5_externalize_auth_context(krb5_auth_context auth_context,
/* Now handle remote_port, if appropriate */
if (!kret && auth_context->remote_port) {
(void) krb5_ser_pack_int32(TOKEN_RPORT, &bp, &remain);
- kret = k5_externalize_address(auth_context->remote_addr,
+ kret = k5_externalize_address(auth_context->remote_port,
&bp, &remain);
}
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index f2e4dcb..3a98980 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -3735,20 +3735,22 @@ pkinit_open_session(krb5_context context,
/* Login if needed */
if (tinfo.flags & CKF_LOGIN_REQUIRED) {
- if (cctx->p11_module_name != NULL) {
- if (cctx->slotid != PK_NOSLOT) {
- if (asprintf(&p11name,
- "PKCS11:module_name=%s:slotid=%ld:token=%.*s",
- cctx->p11_module_name, (long)cctx->slotid,
- (int)label_len, tinfo.label) < 0)
- p11name = NULL;
- } else {
- if (asprintf(&p11name,
- "PKCS11:module_name=%s,token=%.*s",
- cctx->p11_module_name,
- (int)label_len, tinfo.label) < 0)
- p11name = NULL;
- }
+ if (cctx->slotid != PK_NOSLOT) {
+ if (asprintf(&p11name,
+ "PKCS11:module_name=%s:slotid=%ld:token=%.*s",
+ cctx->p11_module_name, (long)cctx->slotid,
+ (int)label_len, tinfo.label) < 0)
+ p11name = NULL;
+ } else {
+ if (asprintf(&p11name,
+ "PKCS11:module_name=%s,token=%.*s",
+ cctx->p11_module_name,
+ (int)label_len, tinfo.label) < 0)
+ p11name = NULL;
+ }
+ if (p11name == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
}
if (cctx->defer_id_prompt) {
/* Supply the identity name to be passed to the responder. */
diff --git a/src/util/profile/prof_tree.c b/src/util/profile/prof_tree.c
index b3c15ca..cecd33e 100644
--- a/src/util/profile/prof_tree.c
+++ b/src/util/profile/prof_tree.c
@@ -172,7 +172,8 @@ errcode_t profile_add_node(struct profile_node *section, const char *name,
} else if (value == NULL && cmp == 0 &&
p->value == NULL && p->deleted != 1) {
/* Found duplicate subsection, so don't make a new one. */
- *ret_node = p;
+ if (ret_node)
+ *ret_node = p;
return 0;
}
}
--
2.33.0

View File

@ -1,62 +0,0 @@
From aac785e5e050415f8b8cb29059d2f658f755e7e7 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 28 Oct 2024 11:51:54 -0400
Subject: [PATCH] Fix type violation in libkrad
remote.c uses casts to cover up a signature difference between
iterator() and krad_packet_iter_cb. The difference is unimportant in
typical platform ABIs, but calling the function this way is undefined
behavior (C99 6.3.2.8). Fix iterator() to conform to
krad_packet_iter_cb and remove the casts.
---
src/lib/krad/remote.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
index 06ae751..28f2e83 100644
--- a/src/lib/krad/remote.c
+++ b/src/lib/krad/remote.c
@@ -76,15 +76,15 @@ on_timeout(verto_ctx *ctx, verto_ev *ev);
/* Iterate over the set of outstanding packets. */
static const krad_packet *
-iterator(request **out)
+iterator(void *data, krb5_boolean cancel)
{
- request *tmp = *out;
+ request **rptr = data, *req = *rptr;
- if (tmp == NULL)
+ if (cancel || req == NULL)
return NULL;
- *out = K5_TAILQ_NEXT(tmp, list);
- return tmp->request;
+ *rptr = K5_TAILQ_NEXT(req, list);
+ return req->request;
}
/* Create a new request. */
@@ -349,8 +349,7 @@ on_io_read(krad_remote *rr)
/* Decode the packet. */
tmp = K5_TAILQ_FIRST(&rr->list);
retval = krad_packet_decode_response(rr->kctx, rr->secret, &rr->buffer,
- (krad_packet_iter_cb)iterator, &tmp,
- &req, &rsp);
+ iterator, &tmp, &req, &rsp);
rr->buffer.length = 0;
if (retval != 0)
return;
@@ -457,7 +456,7 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
r = K5_TAILQ_FIRST(&rr->list);
retval = krad_packet_new_request(rr->kctx, rr->secret, code, attrs,
- (krad_packet_iter_cb)iterator, &r, &tmp);
+ iterator, &r, &tmp);
if (retval != 0)
goto error;
--
2.33.0

View File

@ -1,62 +0,0 @@
From 038793c3083f44c4fb62626c12f80c80147029cf Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@cryptomilk.org>
Date: Fri, 11 Oct 2024 12:45:13 +0200
Subject: [PATCH] Fix unlikely password change leak
In kpasswd_sendto_msg_callback(), if getsockname() does not reveal the
local address, a copy of the first local address's contents is made
and never freed. Instead of making an allocated copy of the address
contents, make a shallow copy of the whole address. Delay freeing the
address array until the end of the function so that alias pointer made
by the shallow copy remains valid.
[ghudson@mit.edu: further simplified code; rewrote commit message]
---
src/lib/krb5/os/changepw.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
index c592325..9cae409 100644
--- a/src/lib/krb5/os/changepw.c
+++ b/src/lib/krb5/os/changepw.c
@@ -115,6 +115,7 @@ kpasswd_sendto_msg_callback(SOCKET fd, void *data, krb5_data *message)
struct sendto_callback_context *ctx = data;
GETSOCKNAME_ARG3_TYPE addrlen;
krb5_data output;
+ krb5_address **addrs = NULL;
memset (message, 0, sizeof(krb5_data));
@@ -143,20 +144,10 @@ kpasswd_sendto_msg_callback(SOCKET fd, void *data, krb5_data *message)
local_kaddr.length = sizeof(ss2sin6(&local_addr)->sin6_addr);
local_kaddr.contents = (krb5_octet *) &ss2sin6(&local_addr)->sin6_addr;
} else {
- krb5_address **addrs;
-
code = krb5_os_localaddr(ctx->context, &addrs);
if (code)
goto cleanup;
-
- local_kaddr.magic = addrs[0]->magic;
- local_kaddr.addrtype = addrs[0]->addrtype;
- local_kaddr.length = addrs[0]->length;
- local_kaddr.contents = k5memdup(addrs[0]->contents, addrs[0]->length,
- &code);
- krb5_free_addresses(ctx->context, addrs);
- if (local_kaddr.contents == NULL)
- goto cleanup;
+ local_kaddr = *addrs[0];
}
@@ -193,6 +184,7 @@ kpasswd_sendto_msg_callback(SOCKET fd, void *data, krb5_data *message)
message->data = output.data;
cleanup:
+ krb5_free_addresses(ctx->context, addrs);
return code;
}
--
2.43.0

View File

@ -1,175 +0,0 @@
From a96541981ee34c8642ddeb6101b98e883e41c6e5 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Fri, 6 Sep 2024 17:18:11 +0200
Subject: [PATCH] Fix various issues detected by static analysis
In klists's show_credential(), ensure that the column counter doesn't
decrease if printf() fails.
In process_k5beta7_princ(), bounds-check the e_length field.
In ndr_enc_delegation_info(), initialize b so it is always valid for
the cleanup handler.
In krb5_dbe_def_decrypt_key_data(), change the flow control so ret is
always set by the end of the function. Return KRB5_KDB_INVALIDKEYSIZE
if there isn't enough data in the first key_data_contents field or if
the serialized key length is invalid.
In svcauth_gss_validate(), expand rpchdr to accomodate the header plus
MAX_AUTH_BYTES.
In svcudp_reply(), change slen to unsigned to match the return type of
XDR_GETPOS() and eliminate an unnecessary check for slen >= 0.
In krb5int_pthread_loaded()(), remove pthread_equal() from the weak
symbol checks. It is implemented as an inline function in some glibc
versions, which makes the comparison "&pthread_equal == 0" always
false.
[ghudson@mit.edu: further modified krb5_dbe_def_decrypt_key_data() for
clarity; added detail to commit message]
Reference:https://github.com/krb5/krb5/commit/a96541981ee34c8642ddeb6101b98e883e41c6e5
Conflict:src/kdc/ndr.c,src/lib/kdb/decrypt_key.c
---
src/clients/klist/klist.c | 12 ++++++------
src/kadmin/dbutil/dump.c | 5 +++++
src/lib/rpc/svc_auth_gss.c | 5 ++++-
src/lib/rpc/svc_udp.c | 13 +++++++------
src/util/support/threads.c | 2 --
5 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index 394c75b..1511c59 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -681,7 +681,7 @@ show_credential(krb5_creds *cred, const char *defname)
krb5_error_code ret;
krb5_ticket *tkt = NULL;
char *name = NULL, *sname = NULL, *tktsname, *flags;
- int extra_field = 0, ccol = 0, i;
+ int extra_field = 0, ccol = 0, i, r;
krb5_boolean is_config = krb5_is_config_principal(context, cred->server);
ret = krb5_unparse_name(context, cred->client, &name);
@@ -711,11 +711,11 @@ show_credential(krb5_creds *cred, const char *defname)
fputs("config: ", stdout);
ccol = 8;
for (i = 1; i < cred->server->length; i++) {
- ccol += printf("%s%.*s%s",
- i > 1 ? "(" : "",
- (int)cred->server->data[i].length,
- cred->server->data[i].data,
- i > 1 ? ")" : "");
+ r = printf("%s%.*s%s", i > 1 ? "(" : "",
+ (int)cred->server->data[i].length,
+ cred->server->data[i].data, i > 1 ? ")" : "");
+ if (r >= 0)
+ ccol += r;
}
fputs(" = ", stdout);
ccol += 3;
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index 4d6cc0b..feb053d 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -704,6 +704,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
dbentry->len = u1;
dbentry->n_key_data = u4;
+
+ if (u5 > UINT16_MAX) {
+ load_err(fname, *linenop, _("invalid principal extra data size"));
+ goto fail;
+ }
dbentry->e_length = u5;
if (kp != NULL) {
diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
index aba7694..e290018 100644
--- a/src/lib/rpc/svc_auth_gss.c
+++ b/src/lib/rpc/svc_auth_gss.c
@@ -296,7 +296,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
struct opaque_auth *oa;
gss_buffer_desc rpcbuf, checksum;
OM_uint32 maj_stat, min_stat, qop_state;
- u_char rpchdr[128];
+ u_char rpchdr[32 + MAX_AUTH_BYTES];
int32_t *buf;
log_debug("in svcauth_gss_validate()");
@@ -314,6 +314,8 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
return (FALSE);
buf = (int32_t *)(void *)rpchdr;
+
+ /* Write the 32 first bytes of the header. */
IXDR_PUT_LONG(buf, msg->rm_xid);
IXDR_PUT_ENUM(buf, msg->rm_direction);
IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
@@ -322,6 +324,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
IXDR_PUT_ENUM(buf, oa->oa_flavor);
IXDR_PUT_LONG(buf, oa->oa_length);
+
if (oa->oa_length) {
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
buf += RNDUP(oa->oa_length) / sizeof(int32_t);
diff --git a/src/lib/rpc/svc_udp.c b/src/lib/rpc/svc_udp.c
index 8ecbdf2..3aff277 100644
--- a/src/lib/rpc/svc_udp.c
+++ b/src/lib/rpc/svc_udp.c
@@ -248,8 +248,9 @@ static bool_t svcudp_reply(
{
struct svcudp_data *su = su_data(xprt);
XDR *xdrs = &su->su_xdrs;
- int slen;
+ u_int slen;
bool_t stat = FALSE;
+ ssize_t r;
xdrproc_t xdr_results = NULL;
caddr_t xdr_location = 0;
@@ -272,12 +273,12 @@ static bool_t svcudp_reply(
if (xdr_replymsg(xdrs, msg) &&
(!has_args ||
(SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
- slen = (int)XDR_GETPOS(xdrs);
- if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
- (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
- == slen) {
+ slen = XDR_GETPOS(xdrs);
+ r = sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen);
+ if (r >= 0 && (u_int)r == slen) {
stat = TRUE;
- if (su->su_cache && slen >= 0) {
+ if (su->su_cache) {
cache_set(xprt, (uint32_t) slen);
}
}
diff --git a/src/util/support/threads.c b/src/util/support/threads.c
index be7e4c2..4ded805 100644
--- a/src/util/support/threads.c
+++ b/src/util/support/threads.c
@@ -118,7 +118,6 @@ struct tsd_block {
# pragma weak pthread_mutex_destroy
# pragma weak pthread_mutex_init
# pragma weak pthread_self
-# pragma weak pthread_equal
# pragma weak pthread_getspecific
# pragma weak pthread_setspecific
# pragma weak pthread_key_create
@@ -151,7 +150,6 @@ int krb5int_pthread_loaded (void)
|| &pthread_mutex_destroy == 0
|| &pthread_mutex_init == 0
|| &pthread_self == 0
- || &pthread_equal == 0
/* Any program that's really multithreaded will have to be
able to create threads. */
|| &pthread_create == 0
--
2.33.0

View File

@ -1,90 +0,0 @@
From 3b57de1b68f31fa297d91e8b00bd91587d71fd02 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 1 Nov 2024 13:42:44 -0400
Subject: [PATCH] Fix various small logic errors
Correct five logic errors (all unlikely to manifest as user-visible
bugs) found by static analysis. Reported by Valery Fedorenko.
---
src/kdc/policy.c | 2 +-
src/lib/apputils/net-server.c | 2 +-
src/lib/rpc/unit-test/client.c | 1 +
src/plugins/audit/kdc_j_encode.c | 10 ++++------
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 2 ++
5 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/kdc/policy.c b/src/kdc/policy.c
index a3ff556c5..1ae1c7a05 100644
--- a/src/kdc/policy.c
+++ b/src/kdc/policy.c
@@ -180,7 +180,7 @@ unload_kdcpolicy_plugins(krb5_context context)
{
kdcpolicy_handle *hp, h;
- for (hp = handles; *hp != NULL; hp++) {
+ for (hp = handles; hp != NULL && *hp != NULL; hp++) {
h = *hp;
if (h->vt.fini != NULL)
h->vt.fini(context, h->moddata);
diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c
index 75372d894..b3da72d3f 100644
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -1127,7 +1127,7 @@ kill_lru_tcp_or_rpc_connection(void *handle, verto_ev *newev)
}
if (oldest_c != NULL) {
krb5_klog_syslog(LOG_INFO, _("dropping %s fd %d from %s"),
- c->type == CONN_RPC ? "rpc" : "tcp",
+ oldest_c->type == CONN_RPC ? "rpc" : "tcp",
verto_get_fd(oldest_ev), oldest_c->addrbuf);
if (oldest_c->type == CONN_RPC)
oldest_c->rpc_force_close = 1;
diff --git a/src/lib/rpc/unit-test/client.c b/src/lib/rpc/unit-test/client.c
index 9b907bcdc..7965a4306 100644
--- a/src/lib/rpc/unit-test/client.c
+++ b/src/lib/rpc/unit-test/client.c
@@ -165,6 +165,7 @@ main(int argc, char **argv)
if (echo_resp == NULL) {
fprintf(stderr, "RPC_TEST_ECHO call %d%s", i,
clnt_sperror(clnt, ""));
+ break;
}
if (strncmp(*echo_resp, "Echo: ", 6) &&
strcmp(echo_arg, (*echo_resp) + 6) != 0)
diff --git a/src/plugins/audit/kdc_j_encode.c b/src/plugins/audit/kdc_j_encode.c
index fb4a4ed73..0df258d76 100755
--- a/src/plugins/audit/kdc_j_encode.c
+++ b/src/plugins/audit/kdc_j_encode.c
@@ -419,12 +419,10 @@ kau_j_tgs_u2u(const krb5_boolean ev_success, krb5_audit_state *state,
goto error;
}
/* Client in the second ticket. */
- if (req != NULL) {
- ret = princ_to_value(req->second_ticket[0]->enc_part2->client,
- obj, AU_REQ_U2U_USER);
- if (ret)
- goto error;
- }
+ ret = princ_to_value(req->second_ticket[0]->enc_part2->client,
+ obj, AU_REQ_U2U_USER);
+ if (ret)
+ goto error;
/* Enctype of a session key of the second ticket. */
ret = int32_to_value(req->second_ticket[0]->enc_part2->session->enctype,
obj, AU_SRV_ETYPE);
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 6d1966194..4ae2c00ad 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -4110,6 +4110,8 @@ pkinit_get_certs_pkcs12(krb5_context context,
TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(context);
+ if (p12name == NULL)
+ goto cleanup;
if (id_cryptoctx->defer_id_prompt) {
/* Supply the identity name to be passed to the responder. */
pkinit_set_deferred_id(&id_cryptoctx->deferred_ids, p12name, 0,
--
2.33.0

View File

@ -1,91 +0,0 @@
From bba0c36394cb88265da6e3d6566dd88b9c7978ca Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 21 Oct 2024 19:04:08 -0400
Subject: [PATCH] Prevent late initialization of GSS error map
Some of the peripheral libgssapi_krb5 utility functions, such as
gss_str_to_oid(), do not access the mechanism list and therefore do
not reach any of the calls to gssint_mechglue_initialize_library().
If one of these functions is called early and produces an error, its
call to map_error() will operate on the uninitialized error map. When
the library is later initialized, any entries added to the error map
this way will be leaked.
To ensure that the error map is initialized before it is operated on,
add library initialization calls to gssint_mecherrmap_map() and
gssint_mecherrmap_get().
ticket: 9145 (new)
Reference:https://github.com/krb5/krb5/commit/bba0c36394cb88265da6e3d6566dd88b9c7978ca
Conflict:src/lib/gssapi/generic/deps
---
src/lib/gssapi/generic/Makefile.in | 2 +-
src/lib/gssapi/generic/deps | 6 ++++--
src/lib/gssapi/generic/util_errmap.c | 6 +++++-
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/lib/gssapi/generic/Makefile.in b/src/lib/gssapi/generic/Makefile.in
index 1a95a7d..ac69a85 100644
--- a/src/lib/gssapi/generic/Makefile.in
+++ b/src/lib/gssapi/generic/Makefile.in
@@ -1,6 +1,6 @@
mydir=lib$(S)gssapi$(S)generic
BUILDTOP=$(REL)..$(S)..$(S)..
-LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/..
+LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/../mechglue
##DOS##BUILDTOP = ..\..\..
##DOS##PREFIXDIR=generic
diff --git a/src/lib/gssapi/generic/deps b/src/lib/gssapi/generic/deps
index 5b80e7f..222b088 100644
--- a/src/lib/gssapi/generic/deps
+++ b/src/lib/gssapi/generic/deps
@@ -59,8 +59,10 @@ util_buffer_set.so util_buffer_set.po $(OUTPRE)util_buffer_set.$(OBJEXT): \
util_buffer_set.c
util_errmap.so util_errmap.po $(OUTPRE)util_errmap.$(OBJEXT): \
$(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
- $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/krb5/krb5.h \
- $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(srcdir)/../mechglue/mechglue.h \
+ $(srcdir)/../mechglue/mglueP.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-input.h $(top_srcdir)/include/k5-platform.h \
$(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
errmap.h gssapiP_generic.h gssapi_err_generic.h gssapi_ext.h \
gssapi_generic.h util_errmap.c
diff --git a/src/lib/gssapi/generic/util_errmap.c b/src/lib/gssapi/generic/util_errmap.c
index 628a455..138310c 100644
--- a/src/lib/gssapi/generic/util_errmap.c
+++ b/src/lib/gssapi/generic/util_errmap.c
@@ -25,6 +25,7 @@
*/
#include "gssapiP_generic.h"
+#include <mglueP.h>
#include <string.h>
#ifndef _WIN32
#include <unistd.h>
@@ -181,6 +182,9 @@ OM_uint32 gssint_mecherrmap_map(OM_uint32 minor, const gss_OID_desc * oid)
f = stderr;
#endif
+ if (gssint_mechglue_initialize_library() != 0)
+ return 0;
+
me.code = minor;
me.mech = *oid;
k5_mutex_lock(&mutex);
@@ -249,7 +253,7 @@ int gssint_mecherrmap_get(OM_uint32 minor, gss_OID mech_oid,
{
const struct mecherror *p;
- if (minor == 0) {
+ if (minor == 0 || gssint_mechglue_initialize_library() != 0) {
return EINVAL;
}
k5_mutex_lock(&mutex);
--
2.33.0

View File

@ -1,38 +0,0 @@
From d09433aed821d40142b10dc5b4a0aa8110c5a09e Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 6 Nov 2024 17:31:37 -0500
Subject: [PATCH] Prevent undefined shift in decode_krb5_flags()
In the statement "f |= bits[i] << (8 * (3 - i))", bits[i] is
implicitly promoted from uint8_t to int according to the integer
promotion rules (C99 6.3.1.1). If i is 0 and bits[i] >= 128, the
result cannot be represented as an int and the behavior of the shift
is undefined (C99 6.5.7). To ensure that the shift operation is
defined, cast bits[i] to uint32_t.
(f and the function output are int32_t, but the conversion of uint32_t
to int32_t is implementation-defined when the value cannot be
represented, not undefined. We check in configure.ac that the
platform is two's complement.)
(Discovered by OSS-Fuzz.)
---
src/lib/krb5/asn.1/asn1_k_encode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index ad5a18a24..1a250c98c 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -250,7 +250,7 @@ decode_krb5_flags(const taginfo *t, const uint8_t *asn1, size_t len, void *val)
return ret;
/* Copy up to 32 bits into f, starting at the most significant byte. */
for (i = 0; i < blen && i < 4; i++)
- f |= bits[i] << (8 * (3 - i));
+ f |= (uint32_t)bits[i] << (8 * (3 - i));
*(krb5_flags *)val = f;
free(bits);
return 0;
--
2.33.0

View File

@ -3,7 +3,7 @@
Name: krb5 Name: krb5
Version: 1.21.2 Version: 1.21.2
Release: 15 Release: 10
Summary: The Kerberos network authentication protocol Summary: The Kerberos network authentication protocol
License: MIT License: MIT
URL: http://web.mit.edu/kerberos/www/ URL: http://web.mit.edu/kerberos/www/
@ -39,21 +39,7 @@ Patch15: backport-Handle-empty-initial-buffer-in-IAKERB-initiator.patch
Patch16: backport-CVE-2024-37370-CVE-2024-37371-Fix-vulnerabilities-in-GSS-message-token-handling.patch Patch16: backport-CVE-2024-37370-CVE-2024-37371-Fix-vulnerabilities-in-GSS-message-token-handling.patch
Patch17: backport-Change-krb5_get_credentials-endtime-behavior.patch Patch17: backport-Change-krb5_get_credentials-endtime-behavior.patch
Patch18: backport-Fix-memory-leak-in-PAC-checksum-verification.patch Patch18: backport-Fix-memory-leak-in-PAC-checksum-verification.patch
Patch19: fix-libkadm5-parameter-leak.patch Patch19: fix-libkadm5-parameter-leak.patch
Patch20: backport-CVE-2024-3596.patch
Patch21: backport-Avoid-mutex-locking-in-krb5int_trace.patch
Patch22: backport-Fix-unlikely-password-change-leak.patch
Patch23: backport-Allow-null-keyblocks-in-IOV-checksum-functions.patch
Patch24: backport-Fix-krb5_ldap_list_policy-filtering-loop.patch
Patch25: backport-Fix-various-issues-detected-by-static-analysis.patch
Patch26: backport-Fix-krb5_crypto_us_timeofday-microseconds-check.patch
Patch27: backport-Prevent-late-initialization-of-GSS-error-map.patch
Patch28: backport-CVE-2025-24528.patch
Patch29: backport-Fix-LDAP-module-leak-on-authentication-error.patch
Patch30: backport-Fix-minor-logic-errors.patch
Patch31: backport-Fix-type-violation-in-libkrad.patch
Patch32: backport-Fix-various-small-logic-errors.patch
Patch33: backport-Prevent-undefined-shift-in-decode_krb5_flags.patch
BuildRequires: gettext BuildRequires: gettext
BuildRequires: gcc make automake autoconf pkgconfig pam-devel libselinux-devel byacc BuildRequires: gcc make automake autoconf pkgconfig pam-devel libselinux-devel byacc
@ -85,7 +71,6 @@ Provides: krb5-pkinit = %{version}-%{release}
Provides: krb5-server-ldap = %{version}-%{release} Provides: krb5-server-ldap = %{version}-%{release}
Obsoletes: krb5-pkinit-openssl < %{version}-%{release} Obsoletes: krb5-pkinit-openssl < %{version}-%{release}
Provides: krb5-pkinit-openssl = %{version}-%{release} Provides: krb5-pkinit-openssl = %{version}-%{release}
%{?systemd_requires}
%description server %description server
This package provides krb5 server programs. This package provides krb5 server programs.
@ -116,7 +101,12 @@ Requires: /etc/crypto-policies/back-ends/krb5.config
%description libs %description libs
This package contains the shared libraries needed by Kerberos 5. This package contains the shared libraries needed by Kerberos 5.
%package_help %package help
Summary: The documents for krb5
BuildArch: noarch
%description help
%{summary}.
%prep %prep
%autosetup -n %{name}-%{version} -p1 %autosetup -n %{name}-%{version} -p1
@ -228,6 +218,10 @@ find %buildroot -type f \( -name '*.so' -o -name '*.so.*' \) -exec chmod 755 {}
make -C src runenv.py make -C src runenv.py
make -C src check || : make -C src check || :
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%post server %post server
%systemd_post krb5kdc.service kadmin.service kprop.service %systemd_post krb5kdc.service kadmin.service kprop.service
/bin/systemctl daemon-reload /bin/systemctl daemon-reload
@ -239,11 +233,13 @@ make -C src check || :
%systemd_postun_with_restart krb5kdc.service kadmin.service kprop.service %systemd_postun_with_restart krb5kdc.service kadmin.service kprop.service
%files %files
%defattr(-,root,root,-)
%doc NOTICE README %doc NOTICE README
%{_libdir}/libkadm5clnt_mit.so.* %{_libdir}/libkadm5clnt_mit.so.*
%{_libdir}/libkadm5srv_mit.so.* %{_libdir}/libkadm5srv_mit.so.*
%files libs -f mit-krb5.lang %files libs -f mit-krb5.lang
%defattr(-,root,root,-)
%dir /etc/gss %dir /etc/gss
%dir /etc/gss/mech.d %dir /etc/gss/mech.d
%dir /etc/krb5.conf.d %dir /etc/krb5.conf.d
@ -266,6 +262,7 @@ make -C src check || :
%dir %{_var}/kerberos/krb5/user %dir %{_var}/kerberos/krb5/user
%files server %files server
%defattr(-,root,root,-)
%{_unitdir}/krb5kdc.service %{_unitdir}/krb5kdc.service
%{_unitdir}/kadmin.service %{_unitdir}/kadmin.service
%{_unitdir}/kprop.service %{_unitdir}/kprop.service
@ -302,6 +299,7 @@ make -C src check || :
%{_datadir}/kerberos/ldap/kerberos.ldif %{_datadir}/kerberos/ldap/kerberos.ldif
%files client %files client
%defattr(-,root,root,-)
%config(noreplace) /etc/pam.d/ksu %config(noreplace) /etc/pam.d/ksu
%{_bindir}/kdestroy %{_bindir}/kdestroy
%{_bindir}/kinit %{_bindir}/kinit
@ -315,6 +313,7 @@ make -C src check || :
%attr(4755,root,root) %{_bindir}/ksu %attr(4755,root,root) %{_bindir}/ksu
%files devel %files devel
%defattr(-,root,root,-)
%{_includedir}/* %{_includedir}/*
%{_libdir}/{libgssapi_krb5.so,libgssrpc.so,libk5crypto.so,libkdb5.so,libkrad.so,libkrb5.so,libkrb5support.so} %{_libdir}/{libgssapi_krb5.so,libgssrpc.so,libk5crypto.so,libkdb5.so,libkrad.so,libkrb5.so,libkrb5support.so}
%{_libdir}/pkgconfig/* %{_libdir}/pkgconfig/*
@ -331,6 +330,7 @@ make -C src check || :
%{_sbindir}/uuserver %{_sbindir}/uuserver
%files help %files help
%defattr(-,root,root,-)
%{_mandir}/man1/* %{_mandir}/man1/*
%{_mandir}/man5/* %{_mandir}/man5/*
%{_mandir}/man5/{.k5identity.5.*,.k5login.5.*} %{_mandir}/man5/{.k5identity.5.*,.k5login.5.*}
@ -338,21 +338,6 @@ make -C src check || :
%{_mandir}/man8/* %{_mandir}/man8/*
%changelog %changelog
* Tue Mar 25 2025 Linux_zhang <zhangruifang@h-partners.com> - 1.21.2-15
- backport patches to fix bugs
* Thu Jan 30 2025 Funda Wang <fundawang@yeah.net> - 1.21.2-14
- fix CVE-2025-24528
* Wed Dec 04 2024 wangjiang <app@cameyan.com> - 1.21.2-13
- backport upstream patches
* Fri Nov 22 2024 liuh <liuhuan01@kylinos.cn> - 1.21.2-12
- backport patches from upstream
* Thu Nov 07 2024 Funda Wang <fundawang@yeah.net> - 1.21.2-11
- fix CVE-2024-3596
* Wed Oct 30 2024 yanshuai <yanshuai@kylinos.cn> - 1.21.2-10 * Wed Oct 30 2024 yanshuai <yanshuai@kylinos.cn> - 1.21.2-10
- Fix libkadm5 parameter leak - Fix libkadm5 parameter leak