From 5919e0ea0010dda6c4237083633aff1090463d0e Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jul 22 2022 10:12:54 +0000 Subject: import krb5-1.18.2-21.el8 --- diff --git a/SOURCES/krb5-krad-larger-attrs.patch b/SOURCES/krb5-krad-larger-attrs.patch new file mode 100644 index 0000000..8437921 --- /dev/null +++ b/SOURCES/krb5-krad-larger-attrs.patch @@ -0,0 +1,69 @@ +From b2b7729d71e7ab2cde9c73b40b8e972c82a875a2 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 8 Nov 2021 17:48:50 +0100 +Subject: [PATCH] Support larger RADIUS attributes in libkrad + +In kr_attrset_decode(), explicitly treat the length byte as unsigned. +Otherwise attributes longer than 125 characters will be rejected with +EBADMSG. + +Add a 253-character-long NAS-Identifier attribute to the tests to make +sure that attributes with the maximal number of characters are working +as expected. + +[ghudson@mit.edu: used uint8_t cast per current practices; edited +commit message] + +ticket: 9036 (new) +--- + src/lib/krad/attrset.c | 2 +- + src/lib/krad/t_packet.c | 13 +++++++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c +index d89982a13..6ec031e32 100644 +--- a/src/lib/krad/attrset.c ++++ b/src/lib/krad/attrset.c +@@ -218,7 +218,7 @@ kr_attrset_decode(krb5_context ctx, const krb5_data *in, const char *secret, + + for (i = 0; i + 2 < in->length; ) { + type = in->data[i++]; +- tmp = make_data(&in->data[i + 1], in->data[i] - 2); ++ tmp = make_data(&in->data[i + 1], (uint8_t)in->data[i] - 2); + i += tmp.length + 1; + + retval = (in->length < i) ? EBADMSG : 0; +diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c +index 0a92e9cc2..c22489144 100644 +--- a/src/lib/krad/t_packet.c ++++ b/src/lib/krad/t_packet.c +@@ -57,6 +57,14 @@ make_packet(krb5_context ctx, const krb5_data *username, + krb5_error_code retval; + const krb5_data *data; + int i = 0; ++ krb5_data nas_id; ++ ++ nas_id = string2data("12345678901234567890123456789012345678901234567890" ++ "12345678901234567890123456789012345678901234567890" ++ "12345678901234567890123456789012345678901234567890" ++ "12345678901234567890123456789012345678901234567890" ++ "12345678901234567890123456789012345678901234567890" ++ "123"); + + retval = krad_attrset_new(ctx, &set); + if (retval != 0) +@@ -71,6 +79,11 @@ make_packet(krb5_context ctx, const krb5_data *username, + if (retval != 0) + goto out; + ++ retval = krad_attrset_add(set, krad_attr_name2num("NAS-Identifier"), ++ &nas_id); ++ if (retval != 0) ++ goto out; ++ + retval = krad_packet_new_request(ctx, "foo", + krad_code_name2num("Access-Request"), + set, iterator, &i, &tmp); +-- +2.35.3 + diff --git a/SOURCES/krb5-krad-remote.patch b/SOURCES/krb5-krad-remote.patch new file mode 100644 index 0000000..d9c4d9e --- /dev/null +++ b/SOURCES/krb5-krad-remote.patch @@ -0,0 +1,171 @@ +From da677b071dadda3700d12d037f5896b166d3546d Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 9 Nov 2021 13:00:43 -0500 +Subject: [PATCH] Avoid use after free during libkrad cleanup + +libkrad client requests contain a list of references to remotes, with +no back-references or reference counts. To prevent accesses to +dangling references during cleanup, cancel all requests on all remotes +before freeing any remotes. + +Remove the code for aging out unused servers. This code was fairly +safe as all requests referencing a remote should have completed or +timed out during an hour of disuse, but in the current design we have +no way to guarantee or check that. The set of addresses we send +RADIUS requests to will generally be small, so aging out servers is +unnecessary. + +ticket: 9035 (new) +--- + src/lib/krad/client.c | 42 ++++++++++++++--------------------------- + src/lib/krad/internal.h | 4 ++++ + src/lib/krad/remote.c | 11 ++++++++--- + 3 files changed, 26 insertions(+), 31 deletions(-) + +diff --git a/src/lib/krad/client.c b/src/lib/krad/client.c +index 6365dd1c6..810940afc 100644 +--- a/src/lib/krad/client.c ++++ b/src/lib/krad/client.c +@@ -64,7 +64,6 @@ struct request_st { + + struct server_st { + krad_remote *serv; +- time_t last; + K5_LIST_ENTRY(server_st) list; + }; + +@@ -81,15 +80,10 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret, + krad_remote **out) + { + krb5_error_code retval; +- time_t currtime; + server *srv; + +- if (time(&currtime) == (time_t)-1) +- return errno; +- + K5_LIST_FOREACH(srv, &rc->servers, list) { + if (kr_remote_equals(srv->serv, ai, secret)) { +- srv->last = currtime; + *out = srv->serv; + return 0; + } +@@ -98,7 +92,6 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret, + srv = calloc(1, sizeof(server)); + if (srv == NULL) + return ENOMEM; +- srv->last = currtime; + + retval = kr_remote_new(rc->kctx, rc->vctx, ai, secret, &srv->serv); + if (retval != 0) { +@@ -173,28 +166,12 @@ request_new(krad_client *rc, krad_code code, const krad_attrset *attrs, + return 0; + } + +-/* Close remotes that haven't been used in a while. */ +-static void +-age(struct server_head *head, time_t currtime) +-{ +- server *srv, *tmp; +- +- K5_LIST_FOREACH_SAFE(srv, head, list, tmp) { +- if (currtime == (time_t)-1 || currtime - srv->last > 60 * 60) { +- K5_LIST_REMOVE(srv, list); +- kr_remote_free(srv->serv); +- free(srv); +- } +- } +-} +- + /* Handle a response from a server (or related errors). */ + static void + on_response(krb5_error_code retval, const krad_packet *reqp, + const krad_packet *rspp, void *data) + { + request *req = data; +- time_t currtime; + size_t i; + + /* Do nothing if we are already completed. */ +@@ -221,10 +198,6 @@ on_response(krb5_error_code retval, const krad_packet *reqp, + for (i = 0; req->remotes[i].remote != NULL; i++) + kr_remote_cancel(req->remotes[i].remote, req->remotes[i].packet); + +- /* Age out servers that haven't been used in a while. */ +- if (time(&currtime) != (time_t)-1) +- age(&req->rc->servers, currtime); +- + request_free(req); + } + +@@ -247,10 +220,23 @@ krad_client_new(krb5_context kctx, verto_ctx *vctx, krad_client **out) + void + krad_client_free(krad_client *rc) + { ++ server *srv; ++ + if (rc == NULL) + return; + +- age(&rc->servers, -1); ++ /* Cancel all requests before freeing any remotes, since each request's ++ * callback data may contain references to multiple remotes. */ ++ K5_LIST_FOREACH(srv, &rc->servers, list) ++ kr_remote_cancel_all(srv->serv); ++ ++ while (!K5_LIST_EMPTY(&rc->servers)) { ++ srv = K5_LIST_FIRST(&rc->servers); ++ K5_LIST_REMOVE(srv, list); ++ kr_remote_free(srv->serv); ++ free(srv); ++ } ++ + free(rc); + } + +diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h +index 312dc8258..b086598fb 100644 +--- a/src/lib/krad/internal.h ++++ b/src/lib/krad/internal.h +@@ -120,6 +120,10 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs, + void + kr_remote_cancel(krad_remote *rr, const krad_packet *pkt); + ++/* Cancel all requests awaiting responses. */ ++void ++kr_remote_cancel_all(krad_remote *rr); ++ + /* Determine if this remote object refers to the remote resource identified + * by the addrinfo struct and the secret. */ + krb5_boolean +diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c +index 0f90443ce..b5dd8cd19 100644 +--- a/src/lib/krad/remote.c ++++ b/src/lib/krad/remote.c +@@ -421,15 +421,20 @@ error: + return retval; + } + ++void ++kr_remote_cancel_all(krad_remote *rr) ++{ ++ while (!K5_TAILQ_EMPTY(&rr->list)) ++ request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL); ++} ++ + void + kr_remote_free(krad_remote *rr) + { + if (rr == NULL) + return; + +- while (!K5_TAILQ_EMPTY(&rr->list)) +- request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL); +- ++ kr_remote_cancel_all(rr); + free(rr->secret); + if (rr->info != NULL) + free(rr->info->ai_addr); +-- +2.35.3 + diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec index 895f9d3..8c2049b 100644 --- a/SPECS/krb5.spec +++ b/SPECS/krb5.spec @@ -18,7 +18,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.18.2 # for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces) -Release: 20%{?dist} +Release: 21%{?dist} # lookaside-cached sources; two downloads and a build artifact Source0: https://web.mit.edu/kerberos/dist/krb5/1.18/krb5-%{version}%{prerelease}.tar.gz @@ -91,6 +91,8 @@ Patch145: downstream-Use-newly-enforced-dejagnu-path-naming-convention.patch Patch146: Make-kprop-work-for-dump-files-larger-than-4GB.patch Patch147: Try-harder-to-avoid-password-change-replay-errors.patch Patch148: downstream-Fix-dejagnu-unit-tests-directory-name-for-RPC-lib.patch +Patch149: krb5-krad-larger-attrs.patch +Patch150: krb5-krad-remote.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -701,6 +703,11 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Fri Jul 01 2022 Julien Rische - 1.18.2-21 +- Backport fix of memory use after free during libkrad cleanup +- Backport support for larger RADIUS attributes in libkrad +- Resolves: rhbz#2103125 + * Wed Apr 27 2022 Julien Rische - 1.18.2-19 - Try harder to avoid password change replay errors - Resolves: #2077563