Bug 21737

Summary: sendto returns systematically EINVAL with HDRINCL raw socks.
Product: Base System Reporter: Kalou <pb>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.1-RELEASE   
Hardware: Any   
OS: Any   

Description Kalou 2000-10-03 23:50:00 UTC
	An IPPROTO_RAW socket, set with IP_HDRINCL option via setsockopt,
	won't let any raw packet out and return EINVAL. This is due to the
	fact that FreeBSD kernel uses flipped ip_len to speed up handling,
	where the user just supplied a htons'ed one.

	Then, a check in rip_output() forbids the case where :

	  ip->ip_len < m->m_pkthdr.len

        A user supplied IP header is seen as 10240 bytes long and denied.

	Is this a kernel bug or a documented feature of the IPPROTO_RAW
	layer ?

Fix: Against version 1.64.2.1 of sys/netinet/raw_ip.c :



-- 
pub  1024D/98F6C473 2000-08-14 Pascal Bouchareine (kalou) <pb@hert.org>--Qyb7dSnpCu39ivbQ8pQtBhNQdghxT3XUwTT6OlQUzmRC6NGT
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- raw_ip.c    Sat Jul 15 09:14:31 2000
+++ /sys/netinet/raw_ip.c       Wed Oct  4 02:45:28 2000
@@ -210,7 +210,16 @@
                        m_freem(m);
                        return(EMSGSIZE);
                }
+
                ip = mtod(m, struct ip *);
+
+               /* user supplied packet is supposed to be sent
+               ** as is. Since we work with flipped ip_len until
+               ** the packet is sent, fixup user input :)
+               */
+
+               ip->ip_len = ntohs(ip->ip_len);
+
                /* don't allow both user specified and setsockopt options,
                   and don't allow packet length sizes that will crash */
                if (((IP_VHL_HL(ip->ip_vhl) != (sizeof (*ip) >> 2))
How-To-Repeat: 
	Well the code is rather heavy so i won't post there in.
	Just compile and run freebsd-spoof.c or any raw ip utility
	using IP_HDRINCL or mail me back for an example..
Comment 1 iedowse freebsd_committer freebsd_triage 2001-11-17 15:23:42 UTC
State Changed
From-To: open->closed


Unfortunately this unexpected byte-swapping of IP_HDRINCL fields 
is something FreeBSD has done for a long time, and fixing it 
would break binary compatibility with existing applications.