From owner-dev-commits-src-branches@freebsd.org Wed May 26 20:38:25 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5EA9B645DC6; Wed, 26 May 2021 20:38:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Fr2pS5Mg2z4gps; Wed, 26 May 2021 20:38:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 41AAD174F7; Wed, 26 May 2021 20:38:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 14QKcNxo055023; Wed, 26 May 2021 20:38:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 14QKcNO9055022; Wed, 26 May 2021 20:38:23 GMT (envelope-from git) Date: Wed, 26 May 2021 20:38:23 GMT Message-Id: <202105262038.14QKcNO9055022@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 92c9af72676d - releng/12.2 - libradius: Fix input validation bugs MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/releng/12.2 X-Git-Reftype: branch X-Git-Commit: 92c9af72676dba7eddac1172d48b150718e60cc4 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 May 2021 20:38:26 -0000 The branch releng/12.2 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=92c9af72676dba7eddac1172d48b150718e60cc4 commit 92c9af72676dba7eddac1172d48b150718e60cc4 Author: Mark Johnston AuthorDate: 2021-05-25 17:59:09 +0000 Commit: Mark Johnston CommitDate: 2021-05-26 20:36:03 +0000 libradius: Fix input validation bugs Approved by: so Security: FreeBSD-SA-21:12.libradius Security: CVE-2021-29629 Sponsored by: The FreeBSD Foundation (cherry picked from commit 8d5c7813061dfa0b187500dfe3aeea7a28181c13) (cherry picked from commit 83280d17fccff2db7d79c7f38e80ec29078ef35e) --- lib/libradius/radlib.c | 54 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/lib/libradius/radlib.c b/lib/libradius/radlib.c index 3b6460e26f0d..a70c8c62a9e7 100644 --- a/lib/libradius/radlib.c +++ b/lib/libradius/radlib.c @@ -187,7 +187,7 @@ is_valid_response(struct rad_handle *h, int srv, MD5_CTX ctx; unsigned char md5[MD5_DIGEST_LENGTH]; const struct rad_server *srvp; - int len; + int alen, len; #ifdef WITH_SSL HMAC_CTX *hctx; u_char resp[MSGSIZE], md[EVP_MAX_MD_SIZE]; @@ -206,8 +206,8 @@ is_valid_response(struct rad_handle *h, int srv, /* Check the message length */ if (h->in_len < POS_ATTRS) return 0; - len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1]; - if (len > h->in_len) + len = (h->in[POS_LENGTH] << 8) | h->in[POS_LENGTH + 1]; + if (len < POS_ATTRS || len > h->in_len) return 0; /* Check the response authenticator */ @@ -233,9 +233,16 @@ is_valid_response(struct rad_handle *h, int srv, /* Search and verify the Message-Authenticator */ hctx = HMAC_CTX_new(); while (pos < len - 2) { - if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) { - /* zero fill the Message-Authenticator */ + if (h->in[pos + 1] != MD5_DIGEST_LENGTH + 2) { + HMAC_CTX_free(hctx); + return 0; + } + if (len - pos < MD5_DIGEST_LENGTH + 2) { + HMAC_CTX_free(hctx); + return 0; + } + memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH); HMAC_Init_ex(hctx, srvp->secret, @@ -255,7 +262,12 @@ is_valid_response(struct rad_handle *h, int srv, } break; } - pos += h->in[pos + 1]; + alen = h->in[pos + 1]; + if (alen < 2) { + HMAC_CTX_free(hctx); + return 0; + } + pos += alen; } HMAC_CTX_free(hctx); } @@ -272,7 +284,7 @@ is_valid_request(struct rad_handle *h) MD5_CTX ctx; unsigned char md5[MD5_DIGEST_LENGTH]; const struct rad_server *srvp; - int len; + int alen, len; #ifdef WITH_SSL HMAC_CTX *hctx; u_char resp[MSGSIZE], md[EVP_MAX_MD_SIZE]; @@ -285,8 +297,8 @@ is_valid_request(struct rad_handle *h) /* Check the message length */ if (h->in_len < POS_ATTRS) return (0); - len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1]; - if (len > h->in_len) + len = (h->in[POS_LENGTH] << 8) | h->in[POS_LENGTH + 1]; + if (len < POS_ATTRS || len > h->in_len) return (0); if (h->in[POS_CODE] != RAD_ACCESS_REQUEST) { @@ -307,7 +319,18 @@ is_valid_request(struct rad_handle *h) pos = POS_ATTRS; hctx = HMAC_CTX_new(); while (pos < len - 2) { + alen = h->in[pos + 1]; + if (alen < 2) + return (0); if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) { + if (len - pos < MD5_DIGEST_LENGTH + 2) { + HMAC_CTX_free(hctx); + return (0); + } + if (alen < MD5_DIGEST_LENGTH + 2) { + HMAC_CTX_free(hctx); + return (0); + } memcpy(resp, h->in, MSGSIZE); /* zero fill the Request-Authenticator */ if (h->in[POS_CODE] != RAD_ACCESS_REQUEST) @@ -327,7 +350,7 @@ is_valid_request(struct rad_handle *h) } break; } - pos += h->in[pos + 1]; + pos += alen; } HMAC_CTX_free(hctx); #endif @@ -929,9 +952,9 @@ rad_cvt_string(const void *data, size_t len) * returns -1. */ int -rad_get_attr(struct rad_handle *h, const void **value, size_t *len) +rad_get_attr(struct rad_handle *h, const void **value, size_t *lenp) { - int type; + int len, type; if (h->in_pos >= h->in_len) return 0; @@ -940,13 +963,14 @@ rad_get_attr(struct rad_handle *h, const void **value, size_t *len) return -1; } type = h->in[h->in_pos++]; - *len = h->in[h->in_pos++] - 2; - if (h->in_pos + (int)*len > h->in_len) { + len = h->in[h->in_pos++]; + if (len < 2 || h->in_pos + len > h->in_len) { generr(h, "Malformed attribute in response"); return -1; } + *lenp = len; *value = &h->in[h->in_pos]; - h->in_pos += *len; + h->in_pos += len; return type; }