svn commit: r322328 - head/sys/netipsec
Andrey V. Elsukov
ae at FreeBSD.org
Wed Aug 9 19:58:39 UTC 2017
Author: ae
Date: Wed Aug 9 19:58:38 2017
New Revision: 322328
URL: https://svnweb.freebsd.org/changeset/base/322328
Log:
Make user supplied data checks a bit stricter.
key_msg2sp() is used for parsing data from setsockopt(IP[V6]_IPSEC_POLICY)
call. This socket option is usually used to configure IPsec bypass for
socket. Only privileged user can set this socket option.
The message syntax is described here
http://www.kame.net/newsletter/20021210/
and our libipsec is usually used to create the correct request.
Add additional checks:
* that sadb_x_ipsecrequest_len is not out of bounds of user supplied buffer
* that src/dst's sa_len is the same
* that 2*sa_len is not out of bounds of user supplied buffer
* that 2*sa_len fits into bounds of sadb_x_ipsecrequest
Reported by: Ilja van Sprundel
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D11796
Modified:
head/sys/netipsec/key.c
Modified: head/sys/netipsec/key.c
==============================================================================
--- head/sys/netipsec/key.c Wed Aug 9 19:16:54 2017 (r322327)
+++ head/sys/netipsec/key.c Wed Aug 9 19:58:38 2017 (r322328)
@@ -1403,7 +1403,8 @@ key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int
while (tlen > 0) {
/* length check */
- if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
+ if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr) ||
+ xisr->sadb_x_ipsecrequest_len > tlen) {
ipseclog((LOG_DEBUG, "%s: invalid ipsecrequest "
"length.\n", __func__));
key_freesp(&newsp);
@@ -1517,10 +1518,12 @@ key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int
if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
struct sockaddr *paddr;
+ len = tlen - sizeof(*xisr);
paddr = (struct sockaddr *)(xisr + 1);
/* validity check */
- if (paddr->sa_len
- > sizeof(isr->saidx.src)) {
+ if (len < sizeof(struct sockaddr) ||
+ len < 2 * paddr->sa_len ||
+ paddr->sa_len > sizeof(isr->saidx.src)) {
ipseclog((LOG_DEBUG, "%s: invalid "
"request address length.\n",
__func__));
@@ -1528,13 +1531,26 @@ key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int
*error = EINVAL;
return NULL;
}
+ /*
+ * Request length should be enough to keep
+ * source and destination addresses.
+ */
+ if (xisr->sadb_x_ipsecrequest_len <
+ sizeof(*xisr) + 2 * paddr->sa_len) {
+ ipseclog((LOG_DEBUG, "%s: invalid "
+ "ipsecrequest length.\n",
+ __func__));
+ key_freesp(&newsp);
+ *error = EINVAL;
+ return (NULL);
+ }
bcopy(paddr, &isr->saidx.src, paddr->sa_len);
paddr = (struct sockaddr *)((caddr_t)paddr +
paddr->sa_len);
/* validity check */
- if (paddr->sa_len
- > sizeof(isr->saidx.dst)) {
+ if (paddr->sa_len !=
+ isr->saidx.src.sa.sa_len) {
ipseclog((LOG_DEBUG, "%s: invalid "
"request address length.\n",
__func__));
More information about the svn-src-all
mailing list