Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 May 2021 20:40:12 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 4027ac420dab - releng/11.4 - libradius: Fix input validation bugs
Message-ID:  <202105262040.14QKeCFX059457@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/11.4 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=4027ac420dab08abe2882db0cd6fd7ed8762071f

commit 4027ac420dab08abe2882db0cd6fd7ed8762071f
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-05-25 17:59:09 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-05-26 20:39:59 +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 5e90dfc54f864651fd98087c6e1f1cbce203b20c)
---
 lib/libradius/radlib.c | 44 +++++++++++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 15 deletions(-)

diff --git a/lib/libradius/radlib.c b/lib/libradius/radlib.c
index 55c6f5cb04a1..acca95da6f66 100644
--- a/lib/libradius/radlib.c
+++ b/lib/libradius/radlib.c
@@ -186,7 +186,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];
@@ -205,8 +205,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 */
@@ -231,9 +231,12 @@ is_valid_response(struct rad_handle *h, int srv,
 
 		/* Search and verify the Message-Authenticator */
 		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)
+					return 0;
+				if (len - pos < MD5_DIGEST_LENGTH + 2)
+					return 0;
+
 				memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH);
 
 				HMAC_CTX_init(&hctx);
@@ -253,7 +256,10 @@ is_valid_response(struct rad_handle *h, int srv,
 					return 0;
 				break;
 			}
-			pos += h->in[pos + 1];
+			alen = h->in[pos + 1];
+			if (alen < 2)
+				return 0;
+			pos += alen;
 		}
 	}
 #endif
@@ -269,7 +275,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];
@@ -282,8 +288,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) {
@@ -303,7 +309,14 @@ is_valid_request(struct rad_handle *h)
 	/* Search and verify the Message-Authenticator */
 	pos = POS_ATTRS;
 	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)
+				return (0);
+			if (alen < MD5_DIGEST_LENGTH + 2)
+				return (0);
 			memcpy(resp, h->in, MSGSIZE);
 			/* zero fill the Request-Authenticator */
 			if (h->in[POS_CODE] != RAD_ACCESS_REQUEST)
@@ -323,7 +336,7 @@ is_valid_request(struct rad_handle *h)
 				return (0);
 			break;
 		}
-		pos += h->in[pos + 1];
+		pos += alen;
 	}
 #endif
 	return (1);
@@ -924,9 +937,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;
@@ -935,13 +948,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;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105262040.14QKeCFX059457>