svn commit: r293906 - head/sys/netinet6

Gleb Smirnoff glebius at FreeBSD.org
Thu Jan 14 10:11:12 UTC 2016


Author: glebius
Date: Thu Jan 14 10:11:10 2016
New Revision: 293906
URL: https://svnweb.freebsd.org/changeset/base/293906

Log:
  Verify the packet length in sctp6_input().
  
  The sctp6_ctlinput() function does not properly check the length of the packet
  it receives from the ICMP6 input routine. This means that an attacker can craft
  a packet that will cause a kernel panic.
  
  When the kernel receives an ICMP6 error message with one of the types/codes
  it handles, it calls icmp6_notify_error() to deliver it to the upper-level
  protocol. icmp6_notify_error() cycles through the extension headers (if any)
  to find the protocol number of the first non-extension header. It does NOT
  verify the length of the non-extension header.
  
  It passes information about the packet (including the actual packet) to the
  upper-level protocol's pr_ctlinput function. In the case of SCTP for IPv6,
  icmp6_notify_error() calls sctp6_ctlinput().
  
  sctp6_ctlinput() assumes that the incoming packet contains a sufficiently-long
  SCTP header and calls m_copydata() to extract a copy of that header. In turn,
  m_copydata() assumes that the caller has already verified that the offset and
  length parameters are correct. If they are incorrect, it will dereference a
  NULL pointer and cause a kernel panic.
  
  In short, no one is sufficiently verifying the input, and the result is a
  kernel panic.
  
  Submitted by:	jtl
  Security:	SA-16:01.sctp

Modified:
  head/sys/netinet6/sctp6_usrreq.c

Modified: head/sys/netinet6/sctp6_usrreq.c
==============================================================================
--- head/sys/netinet6/sctp6_usrreq.c	Thu Jan 14 10:09:05 2016	(r293905)
+++ head/sys/netinet6/sctp6_usrreq.c	Thu Jan 14 10:11:10 2016	(r293906)
@@ -379,7 +379,6 @@ sctp6_ctlinput(int cmd, struct sockaddr 
 		 * XXX: We assume that when IPV6 is non NULL, M and OFF are
 		 * valid.
 		 */
-		/* check if we can safely examine src and dst ports */
 		struct sctp_inpcb *inp = NULL;
 		struct sctp_tcb *stcb = NULL;
 		struct sctp_nets *net = NULL;
@@ -388,6 +387,10 @@ sctp6_ctlinput(int cmd, struct sockaddr 
 		if (ip6cp->ip6c_m == NULL)
 			return;
 
+		/* Check if we can safely examine the SCTP header. */
+		if (ip6cp->ip6c_m->m_pkthdr.len < ip6cp->ip6c_off + sizeof(sh))
+			return;
+
 		bzero(&sh, sizeof(sh));
 		bzero(&final, sizeof(final));
 		inp = NULL;


More information about the svn-src-head mailing list