Module Name: src Committed By: maxv Date: Fri Dec 15 21:00:26 UTC 2017
Modified Files: src/sys/net/npf: npf.h Log Message: Fix a vulnerability in NPF, that allows whatever incoming IPv6 packet to bypass a certain number of filtering rules. Basically there is an integer overflow in npf_cache_ip: npc_hlen is a 8bit unsigned int, and can wrap to zero if the IPv6 packet being processed has large extensions. As a result of an overflow, (mbuf + npc_hlen) won't point at the real protocol header, but instead at some garbage within the packet. That garbage, is what NPF applies its rules on. If these filtering rules allow the packet to enter, that packet is given to the main IPv6 entry point. This entry point, however, is not subject to an integer overflow, so it will actually parse the correct protocol header. The result is: NPF read a wrong header, allowed the packet to enter, the kernel read the correct header, and delivered the packet depending on this correct header. So the offending packet was supposed to be kicked, but still went through the firewall. Simple example, a packet with: packet + 0 = IP6 Header packet + 40 = IP6 Routing header (ip6r_len = 31) packet + 48 = Crafted UDP header (uh_dport = 7777) packet + 296 = IP6 Dest header (ip6e_len = 0) packet + 304 = Real UDP header (uh_dport = 6666) Will bypass a rule of the kind "block port 6666". Here NPF reads the crafted UDP header, sees 7777, lets the packet in; later the kernel reads the real UDP header, and delivers it on port 6666. Fix this by using uint32_t. While here, it seems to me there is also a memory overflow: still in npf_cache_ip, npc_hlen may be incremented with a value that goes beyond the mbuf. To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/sys/net/npf/npf.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.