Date: Wed, 26 May 2021 20:39:42 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: 5e90dfc54f86 - stable/11 - libradius: Fix input validation bugs Message-ID: <202105262039.14QKdgVR055291@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/11 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=5e90dfc54f864651fd98087c6e1f1cbce203b20c commit 5e90dfc54f864651fd98087c6e1f1cbce203b20c 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:38:54 +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) --- 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?202105262039.14QKdgVR055291>