Subject: kern/991: change request for /sys/netinet/ip_input.c
To: None <gnats-admin@NetBSD.ORG>
From: Darren Reed <darrenr@vitruvius.arbld.unimelb.EDU.AU>
List: netbsd-bugs
Date: 04/24/1995 15:05:03
>Number:         991
>Category:       kern
>Synopsis:       packets destined for interface IP# are accepted regardless of which interface they arrive on.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 24 15:05:01 1995
>Originator:     Darren Reed
>Organization:
University of Melbourne
>Release:        netbsd-current
>Environment:
SparcIPC, NetBSD-current
System: NetBSD candella.arbld.unimelb.edu.au 1.0A NetBSD 1.0A (1.0A) #4: Mon Feb 20 18:33:28 EST 1995 root@:/usr/src/sys/arch/sparc/compile/1.0A sparc


>Description:
	When setting up an IP firewall, packets can pass "through" the
kernel, from the "wrong" interface.  The problem is that packets destined
for the ip# associated with (say) le0 will be accepted as being for "us"
if they come in on le1 (one could argue that le1's ip# should be used
anyway, but which one actually gets used is dependant on things usually
outside of the kernel's control).

	In a firewall environment, it is often useful to be able to say
that only packets from this interface can goto it's own IP#, allowing
different services to be run depending on the interface, without there
being any risk that of the wrong service being selected.

	In case I've become confused here, example scenario:
le0 ip# 1.2.3.4
le1 ip# 1.2.4.3
- I run network service A on port 1234 for 1.2.3.4 and service B on port
  1234 for 1.2.4.3.  In the current kernel, people connected to my host
  via le0 can use service B although this is meant for those attached to
  le1.  The object is to enforce people sending packets to my host via
  le0 to use service A and not make B available at all.

On arguing that perhaps the services themselves should do the access control
better, it is often hard to know which ip#'s will be found on both sides and
opens up the possibility of misconfiguration where otherwise the kernel makes
some effort to protect you.

The patch supplied introduces a new "option" for config - FIREWALL.  This may
be an overkill, but I'm hesitant to have it a default action (for fear of
causing too much else to break - maybe it could be a adb'able variable ?).
It would, however, be an appropriate inclusion for kerel configuration when
setting up a firewall.  I hope to have the patch correct - I'm sure I've
seen it on current-users before or very similar.

>How-To-Repeat:
>Fix:

*** /sys/netinet/ip_input.c.orig	Mon Apr 24 00:58:51 1995
--- /sys/netinet/ip_input.c	Mon Apr 24 01:11:07 1995
***************
*** 241,247 ****
  	for (ia = in_ifaddr; ia; ia = ia->ia_next) {
  #define	satosin(sa)	((struct sockaddr_in *)(sa))
  
! 		if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr)
  			goto ours;
  		if (
  #ifdef	DIRECTED_BROADCAST
--- 241,251 ----
  	for (ia = in_ifaddr; ia; ia = ia->ia_next) {
  #define	satosin(sa)	((struct sockaddr_in *)(sa))
  
! 		if (
! #ifdef	FIREWALL
! 		    ia->ia_ifp == m->m_pkthdr.rcvif &&
! #endif
! 		    IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr)
  			goto ours;
  		if (
  #ifdef	DIRECTED_BROADCAST
>Audit-Trail:
>Unformatted: