Date: Thu, 14 Jan 2016 10:11:10 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r293906 - head/sys/netinet6 Message-ID: <201601141011.u0EABAtg038284@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601141011.u0EABAtg038284>