diff --git a/SOURCES/freeradius-CVE-2019-13456-10-iterations.patch b/SOURCES/freeradius-CVE-2019-13456-10-iterations.patch new file mode 100644 index 0000000..0d727f4 --- /dev/null +++ b/SOURCES/freeradius-CVE-2019-13456-10-iterations.patch @@ -0,0 +1,38 @@ +From 3ea2a5a026e73d81cd9a3e9bbd4300c433004bfa Mon Sep 17 00:00:00 2001 +From: Mathy Vanhoef +Date: Wed, 5 Jun 2019 19:21:06 +0000 +Subject: [PATCH] EAP-pwd: fix side-channel leak where 1 in 2018 handshakes + fail + +Previously the Hunting and Pecking algorithm of EAP-pwd aborted when +more than 10 iterations are needed. Every iteration has a 50% chance +of finding the password element. This means one in every 2048 handshakes +will fail, in which case an error frame is sent to the client. This +event leaks information that can be abused in an offline password +brute-force attack. More precisely, the adversary learns that all 10 +iterations failed for the given random EAP-pwd token. Using the same +techniques as in the Dragonblood attack, this can be used to brute-force +the password. + +This patch fixes the above issue by executing enough iterations such that +the password element is always found eventually. + +Note that timing and cache leaks remain a risk against the current +implementation of EAP-pwd. +--- + src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c b/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c +index c54f08c030..d94851c3aa 100644 +--- a/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c ++++ b/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.c +@@ -192,7 +192,7 @@ int compute_password_element (pwd_session_t *session, uint16_t grp_num, + } + ctr = 0; + while (1) { +- if (ctr > 10) { ++ if (ctr > 100) { + DEBUG("unable to find random point on curve for group %d, something's fishy", grp_num); + goto fail; + } diff --git a/SOURCES/freeradius-CVE-2019-17185-DoS-multithreaded-BN-CTX.patch b/SOURCES/freeradius-CVE-2019-17185-DoS-multithreaded-BN-CTX.patch new file mode 100644 index 0000000..af6de93 --- /dev/null +++ b/SOURCES/freeradius-CVE-2019-17185-DoS-multithreaded-BN-CTX.patch @@ -0,0 +1,134 @@ +From 6b522f8780813726799e6b8cf0f1f8e0ce2c8ebf Mon Sep 17 00:00:00 2001 +From: Mathy Vanhoef +Date: Fri, 4 Oct 2019 17:53:52 +0400 +Subject: [PATCH] EAP-pwd: fix DoS due to multithreaded BN_CTX access + +The EAP-pwd module created one global OpenSSL BN_CTX instance, and +used this instance in all incoming requests. This means that different +threads used the same BN_CTX instance, which can result in a crash. +An adversary can trigger these crashes by concurrently initiating +multiple EAP-pwd handshakes from different clients. + +Fix this bug by creating a separate BN_CTX instance for each request. +--- + .../rlm_eap/types/rlm_eap_pwd/eap_pwd.h | 1 + + .../rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.c | 24 +++++++++---------- + .../rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.h | 2 -- + 3 files changed, 13 insertions(+), 14 deletions(-) + +diff --git a/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.h b/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.h +index 013a6e7992..ca12778f61 100644 +--- a/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.h ++++ b/src/modules/rlm_eap/types/rlm_eap_pwd/eap_pwd.h +@@ -90,6 +90,7 @@ typedef struct _pwd_session_t { + uint8_t *out; /* message to fragment */ + size_t out_pos; + size_t out_len; ++ BN_CTX *bnctx; + EC_GROUP *group; + EC_POINT *pwe; + BIGNUM *order; +diff --git a/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.c b/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.c +index 76cc57023e..eefca985d7 100644 +--- a/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.c ++++ b/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.c +@@ -55,8 +55,6 @@ static int mod_detach (void *arg) + + inst = (eap_pwd_t *) arg; + +- if (inst->bnctx) BN_CTX_free(inst->bnctx); +- + return 0; + } + +@@ -76,11 +74,6 @@ static int mod_instantiate (CONF_SECTION *cs, void **instance) + return -1; + } + +- if ((inst->bnctx = BN_CTX_new()) == NULL) { +- cf_log_err_cs(cs, "Failed to get BN context"); +- return -1; +- } +- + return 0; + } + +@@ -96,6 +89,7 @@ static int _free_pwd_session (pwd_session_t *session) + EC_POINT_clear_free(session->pwe); + BN_clear_free(session->order); + BN_clear_free(session->prime); ++ BN_CTX_free(session->bnctx); + + return 0; + } +@@ -217,6 +211,12 @@ static int mod_session_init (void *instance, eap_handler_t *handler) + session->order = NULL; + session->prime = NULL; + ++ session->bnctx = BN_CTX_new(); ++ if (session->bnctx == NULL) { ++ ERROR("rlm_eap_pwd: Failed to get BN context"); ++ return 0; ++ } ++ + /* + * The admin can dynamically change the MTU. + */ +@@ -496,7 +496,7 @@ static int mod_process(void *arg, eap_handler_t *handler) + /* + * compute our scalar and element + */ +- if (compute_scalar_element(session, inst->bnctx)) { ++ if (compute_scalar_element(session, session->bnctx)) { + DEBUG2("failed to compute server's scalar and element"); + return 0; + } +@@ -508,7 +508,7 @@ static int mod_process(void *arg, eap_handler_t *handler) + * element is a point, get both coordinates: x and y + */ + if (!EC_POINT_get_affine_coordinates_GFp(session->group, session->my_element, x, y, +- inst->bnctx)) { ++ session->bnctx)) { + DEBUG2("server point assignment failed"); + BN_clear_free(x); + BN_clear_free(y); +@@ -552,7 +552,7 @@ static int mod_process(void *arg, eap_handler_t *handler) + /* + * process the peer's commit and generate the shared key, k + */ +- if (process_peer_commit(session, in, in_len, inst->bnctx)) { ++ if (process_peer_commit(session, in, in_len, session->bnctx)) { + RDEBUG2("failed to process peer's commit"); + return 0; + } +@@ -560,7 +560,7 @@ static int mod_process(void *arg, eap_handler_t *handler) + /* + * compute our confirm blob + */ +- if (compute_server_confirm(session, session->my_confirm, inst->bnctx)) { ++ if (compute_server_confirm(session, session->my_confirm, session->bnctx)) { + ERROR("rlm_eap_pwd: failed to compute confirm!"); + return 0; + } +@@ -591,7 +591,7 @@ static int mod_process(void *arg, eap_handler_t *handler) + RDEBUG2("pwd exchange is incorrect: not commit!"); + return 0; + } +- if (compute_peer_confirm(session, peer_confirm, inst->bnctx)) { ++ if (compute_peer_confirm(session, peer_confirm, session->bnctx)) { + RDEBUG2("pwd exchange cannot compute peer's confirm"); + return 0; + } +diff --git a/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.h b/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.h +index 189530d066..2264566bb6 100644 +--- a/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.h ++++ b/src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.h +@@ -40,8 +40,6 @@ + #include + + typedef struct _eap_pwd_t { +- BN_CTX *bnctx; +- + uint32_t group; + uint32_t fragment_size; + char const *server_id; diff --git a/SOURCES/freeradius-correct-receiving-multiple-packets.patch b/SOURCES/freeradius-correct-receiving-multiple-packets.patch new file mode 100644 index 0000000..8250740 --- /dev/null +++ b/SOURCES/freeradius-correct-receiving-multiple-packets.patch @@ -0,0 +1,70 @@ +diff --git a/src/main/tls_listen.c b/src/main/tls_listen.c +index 32cf564..45e7641 100644 +--- a/src/main/tls_listen.c ++++ b/src/main/tls_listen.c +@@ -189,6 +189,18 @@ static int tls_socket_recv(rad_listen_t *listener) + + RDEBUG3("Reading from socket %d", request->packet->sockfd); + PTHREAD_MUTEX_LOCK(&sock->mutex); ++ ++ /* ++ * If there is pending application data, as set up by ++ * SSL_peek(), read that before reading more data from ++ * the socket. ++ */ ++ if (SSL_pending(sock->ssn->ssl)) { ++ RDEBUG3("Reading pending buffered data"); ++ sock->ssn->dirty_in.used = 0; ++ goto get_application_data; ++ } ++ + rcode = read(request->packet->sockfd, + sock->ssn->dirty_in.data, + sizeof(sock->ssn->dirty_in.data)); +@@ -250,6 +262,7 @@ static int tls_socket_recv(rad_listen_t *listener) + /* + * Try to get application data. + */ ++get_application_data: + status = tls_application_data(sock->ssn, request); + RDEBUG("Application data status %d", status); + +@@ -333,9 +346,11 @@ int dual_tls_recv(rad_listen_t *listener) + RAD_REQUEST_FUNP fun = NULL; + listen_socket_t *sock = listener->data; + RADCLIENT *client = sock->client; ++ BIO *rbio; + + if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0; + ++redo: + if (!tls_socket_recv(listener)) { + return 0; + } +@@ -403,6 +418,26 @@ int dual_tls_recv(rad_listen_t *listener) + return 0; + } + ++ /* ++ * Check for more application data. ++ * ++ * If there is pending SSL data, "peek" at the ++ * application data. If we get at least one byte of ++ * application data, go back to tls_socket_recv(). ++ * SSL_peek() will set SSL_pending(), and ++ * tls_socket_recv() will read another packet. ++ */ ++ rbio = SSL_get_rbio(sock->ssn->ssl); ++ if (BIO_ctrl_pending(rbio)) { ++ char buf[1]; ++ int peek = SSL_peek(sock->ssn->ssl, buf, 1); ++ ++ if (peek > 0) { ++ DEBUG("more TLS records after dual_tls_recv"); ++ goto redo; ++ } ++ } ++ + return 1; + } + diff --git a/SOURCES/freeradius-logrotate b/SOURCES/freeradius-logrotate index 1c3c5b9..8ea356a 100644 --- a/SOURCES/freeradius-logrotate +++ b/SOURCES/freeradius-logrotate @@ -14,6 +14,7 @@ nocreate missingok compress + su radiusd radiusd } /var/log/radius/checkrad.log { @@ -22,6 +23,7 @@ create missingok compress + su radiusd radiusd } /var/log/radius/radius.log { @@ -33,6 +35,7 @@ postrotate /usr/bin/systemctl reload-or-try-restart radiusd endscript + su radiusd radiusd } /var/log/radius/radwtmp { @@ -41,11 +44,13 @@ create compress missingok + su radiusd radiusd } /var/log/radius/sqltrace.sql { - monthly - rotate 4 - create - compress - missingok + monthly + rotate 4 + create + compress + missingok + su radiusd radiusd } diff --git a/SOURCES/freeradius-no-cleartext-password.patch b/SOURCES/freeradius-no-cleartext-password.patch new file mode 100644 index 0000000..93eaadd --- /dev/null +++ b/SOURCES/freeradius-no-cleartext-password.patch @@ -0,0 +1,14 @@ +diff --git a/src/modules/rlm_pap/rlm_pap.c b/src/modules/rlm_pap/rlm_pap.c +index be50257..284b1d3 100644 +--- a/src/modules/rlm_pap/rlm_pap.c ++++ b/src/modules/rlm_pap/rlm_pap.c +@@ -539,8 +539,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_clear(UNUSED rlm_pap_t *inst, REQUE + (rad_digest_cmp(vp->vp_octets, + request->password->vp_octets, + vp->vp_length) != 0)) { +- REDEBUG("Cleartext password \"%s\" does not match \"known good\" password", +- request->password->vp_strvalue); ++ REDEBUG("Cleartext password does not match \"known good\" password"); + return RLM_MODULE_REJECT; + } + return RLM_MODULE_OK; diff --git a/SOURCES/freeradius-paircompare-attribute-reference.patch b/SOURCES/freeradius-paircompare-attribute-reference.patch new file mode 100644 index 0000000..c2ea3ed --- /dev/null +++ b/SOURCES/freeradius-paircompare-attribute-reference.patch @@ -0,0 +1,43 @@ +From e56048c98bfab25ae9453a52bbe6bcc02f20f515 Mon Sep 17 00:00:00 2001 +From: Arran Cudbard-Bell +Date: Tue, 25 Jul 2017 14:00:02 -0400 +Subject: [PATCH] Allow paircompare to work with attribute references and + expansions. Hopefully Fixes #1947 + +--- + src/main/modcall.c | 6 ------ + src/main/parser.c | 4 +--- + 2 files changed, 1 insertion(+), 9 deletions(-) + +diff --git a/src/main/modcall.c b/src/main/modcall.c +index c385db21f4..4723971d20 100644 +--- a/src/main/modcall.c ++++ b/src/main/modcall.c +@@ -3479,12 +3479,6 @@ static bool pass2_callback(void *ctx, fr_cond_t *c) + + if (!radius_find_compare(map->lhs->tmpl_da)) return true; + +- if (map->rhs->type == TMPL_TYPE_ATTR) { +- cf_log_err(map->ci, "Cannot compare virtual attribute %s to another attribute", +- map->lhs->name); +- return false; +- } +- + if (map->rhs->type == TMPL_TYPE_REGEX) { + cf_log_err(map->ci, "Cannot compare virtual attribute %s via a regex", + map->lhs->name); +diff --git a/src/main/parser.c b/src/main/parser.c +index 5fab262fdc..8b57725a1f 100644 +--- a/src/main/parser.c ++++ b/src/main/parser.c +@@ -1196,9 +1196,7 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *st + * and do no parsing until after all of the modules + * are loaded. But that has issues, too. + */ +- if ((c->data.map->lhs->type == TMPL_TYPE_LITERAL) && +- (lhs_type == T_BARE_WORD) && +- (c->data.map->rhs->type == TMPL_TYPE_LITERAL)) { ++ if ((c->data.map->lhs->type == TMPL_TYPE_LITERAL) && (lhs_type == T_BARE_WORD)) { + int hyphens = 0; + bool may_be_attr = true; + size_t i; diff --git a/SPECS/freeradius.spec b/SPECS/freeradius.spec index 1b22f88..4350c95 100644 --- a/SPECS/freeradius.spec +++ b/SPECS/freeradius.spec @@ -1,7 +1,7 @@ Summary: High-performance and highly configurable free RADIUS server Name: freeradius Version: 3.0.13 -Release: 10%{?dist} +Release: 15%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Daemons URL: http://www.freeradius.org/ @@ -38,6 +38,11 @@ Patch14: freeradius-FR-GV-304-check-for-option-overflowing-the-packet.patch Patch15: freeradius-FR-GV-201-check-input-output-length-in-make_secret.patch Patch16: freeradius-Fix-double-free-in-rlm_sql-acct_redundant.patch Patch17: freeradius-EAP-PWD-curve-handling.patch +Patch18: freeradius-CVE-2019-13456-10-iterations.patch +Patch19: freeradius-paircompare-attribute-reference.patch +Patch20: freeradius-no-cleartext-password.patch +Patch21: freeradius-correct-receiving-multiple-packets.patch +Patch22: freeradius-CVE-2019-17185-DoS-multithreaded-BN-CTX.patch %global docdir %{?_pkgdocdir}%{!?_pkgdocdir:%{_docdir}/%{name}-%{version}} @@ -211,6 +216,11 @@ This plugin provides the unixODBC support for the FreeRADIUS server project. %patch15 -p1 %patch16 -p1 %patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 %build # Force compile/link options, extra security for network facing daemon @@ -811,9 +821,31 @@ exit 0 %{_libdir}/freeradius/rlm_sql_unixodbc.so %changelog +* Thu Apr 16 2020 Alexander Scheel - 3.0.13-15 +- Fixes EAP-PWD: DoS issues due to multithreaded BN_CTX access + Resolves: bz#1818808 + + * Fri Feb 7 2020 Alexander Scheel - 3.0.13-14 +- Fixes receiving of multiple RADIUS packets under load + Resolves: bz#1630684 + +* Fri Feb 7 2020 Alexander Scheel - 3.0.13-13 +- Fixes logging of cleartext pap password + Resolves: bz#1677435 + +* Fri Feb 7 2020 Alexander Scheel - 3.0.13-12 +- Fixes paircompare with attribute references and expansions + Resolves: bz#1592741 + +* Tue Feb 4 2020 Alexander Scheel - 3.0.13-11 +- Fixes logrotate, EAP-PWD vulnerability + Resolves: bz#1719368 privilege escalation due to insecure logrotate configuration + Resolves: bz#1751796 eap-pwd: Information leak due to aborting when needing more than 10 iterations + * Thu Apr 25 2019 Alexander Scheel - 3.0.13-10 - Fixes two EAP-PWD security issues - Resolves: bz#1699413 authentication bypass with an invalid curve attack + Resolves: bz#1699414 authentication bypass with an invalid curve attack + Resolves: bz#1699419 fake authentication using reflection * Thu Feb 22 2018 Nikolai Kondrashov - 3.0.13-9 - Fix double free in rlm_sql acct_redundant