Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Oct 2000 00:44:03 +0200
From:      Kalou <pb@hert.org>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/21737: EINVAL with sendto(), IP_HDRINCL, and IPPROTO_RAW
Message-ID:  <20001004004403.A44296@eclipse.home>

next in thread | raw e-mail | index | archive | help

>Number:         21737
>Category:       kern
>Synopsis:       sendto returns systematically EINVAL with HDRINCL raw socks.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 03 15:50:00 PDT 2000
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001004004403.A44296>