NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/54443: IPFilter and UDP checksum field 0xffff



>Number:         54443
>Category:       kern
>Synopsis:       ipf mistakenly regards UDP packet with checksum field 0xffff as bad
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Aug 06 15:40:00 +0000 2019
>Originator:     Edgar FuÃ?
>Release:        NetBSD 8.1_STABLE
>Organization:
Mathematisches Institut der Universität Bonn
>Description:
	With UDP, a checksum value of 0x0000 is represented as 0xffff in the UDP header's checksum field because a field value of 0x0000 means not to check the checksum.
	When verifying the UDP checksum by computing the checksum on the relevant data including the received checksum field (as the NetBSD TCP/IP stack does), 0xffff doesn't need to be special-cased (as 0x0000 does), because due to idiosyncracies of the one's complement arithmetic used to compute the Internet Checksum, 0x0000 and 0xffff mostly (the exception is all other data bytes being zero, which doesn't appear as a packet) mean the same thing being two representations of Zero.
	But IPFilter verifies the UDP checksum by re-computing it on the received packet without the checksum actually received and then comparing the values. In this case, a UDP checksum field value of 0xffff in the received packet /does/ need to be special-cased to match a re-computed Internet Checksum of 0x0000.
	
	This can cause the NFS client (and thus parts of VFS) to seemingly randomly lock up when a (UDP) NFS reply is continuously (nothing changes in the request, so nothing changes in the reply) dropped.
>How-To-Repeat:
	Enable IPFilter, try to send/receive UDP traffic with a UDP checksum field of 0xffff.
>Fix:
	Index: sys/external/bsd/ipf/netinet/fil.c
	===================================================================
	RCS file: /cvsroot/src/sys/external/bsd/ipf/netinet/fil.c,v
	retrieving revision 1.20.4.2
	diff -u -p -r1.20.4.2 fil.c
	--- sys/external/bsd/ipf/netinet/fil.c	26 Dec 2018 13:18:53 -0000	1.20.4.2
	+++ sys/external/bsd/ipf/netinet/fil.c	6 Aug 2019 15:14:14 -0000
	@@ -6527,8 +6527,11 @@ ipf_checkl4sum(fr_info_t *fin)
			/*NOTREACHED*/
		}
	 
	-	if (csump != NULL)
	+	if (csump != NULL) {
			hdrsum = *csump;
	+		if (fin->fin_p == IPPROTO_UDP && hdrsum == 0xffff)
	+			hdrsum = 0x0000;
	+	}
	 
		if (dosum) {
			sum = fr_cksum(fin, fin->fin_ip, fin->fin_p, fin->fin_dp);

	Or equivalently (sans the DTrace probe) map sum == 0x0000 to 0xffff in the IPPROTO_UDP case.

	The fix hould be up-streamed I guess.



Home | Main Index | Thread Index | Old Index