From pb@hert.org  Tue Oct  3 15:45:08 2000
Return-Path: <pb@hert.org>
Received: from plan9.hert.org (dyn-212-129-10-58.paris.none.net [212.129.10.58])
	by hub.freebsd.org (Postfix) with ESMTP id DC01137B66C
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  3 Oct 2000 15:45:04 -0700 (PDT)
Received: (from pb@localhost)
	by plan9.hert.org (8.9.3/8.9.3) id AAA44304
	for FreeBSD-gnats-submit@freebsd.org; Wed, 4 Oct 2000 00:44:04 +0200 (CEST)
	(envelope-from pb@hert.org)
Message-Id: <20001004004403.A44296@eclipse.home>
Date: Wed, 4 Oct 2000 00:44:03 +0200
From: Kalou <pb@hert.org>
To: FreeBSD-gnats-submit@freebsd.org
Subject: EINVAL with sendto(), IP_HDRINCL, and IPPROTO_RAW

>Number:         21737
>Category:       kern
>Synopsis:       sendto returns systematically EINVAL with HDRINCL raw socks.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 03 15:50:00 PDT 2000
>Closed-Date:    Sat Nov 17 07:23:42 PST 2001
>Last-Modified:  Sat Nov 17 07:26:20 PST 2001
>Originator:     Pascal Bouchareine
>Release:        FreeBSD 4.1-RELEASE i386 and 4.0-RELEASE alpha
>Organization:
hert
>Environment:

	a lot..

>Description:

	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 ?

>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..

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

--- 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))


-- 
pub  1024D/98F6C473 2000-08-14 Pascal Bouchareine (kalou) <pb@hert.org>

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: iedowse 
State-Changed-When: Sat Nov 17 07:23:42 PST 2001 
State-Changed-Why:  

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. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=21737 
>Unformatted:
