Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Aug 2017 12:01:22 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r322576 - stable/11/sys/netipsec
Message-ID:  <201708161201.v7GC1MfD013184@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Aug 16 12:01:22 2017
New Revision: 322576
URL: https://svnweb.freebsd.org/changeset/base/322576

Log:
  MFC r322328:
    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

Modified:
  stable/11/sys/netipsec/key.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netipsec/key.c
==============================================================================
--- stable/11/sys/netipsec/key.c	Wed Aug 16 10:59:37 2017	(r322575)
+++ stable/11/sys/netipsec/key.c	Wed Aug 16 12:01:22 2017	(r322576)
@@ -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__));



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