lkml.org 
[lkml]   [2000]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectbind() allowed to non-local addresses
Using linux-2.4.0-test9, bind() incorrectly allows a bind to a non-local
address. The correct behavior should be a return code of -1 with errno
set to EADDRNOTAVAIL. (Simple snippet to reproduce/debug the problem is
available on request)

There appears to be significant differences between the
net/ipv4/af_inet.c:inet_bind() in the 2.2 and 2.4 sources. The
inet_bind() in the 2.2 sources contains a check to ensure that the value
returned by inet_addr_type() is RTN_LOCAL as well as a #ifdef'ed check
to allow the bind in certain cases if the kernel was compiled with
transparent proxy is enabled. In inet_bind() of the 2.4 tree all of
these checks are conspicuously absent.

The following patch fixes the problem for me, but I am still concerned
possibly breaking transparent proxy. Basically the patch is nothing
more than the addition of a simple check for RTN_LOCAL. (Moving call to
inet_addr_type() is a *very* nit-picky "optimization" that eliminates
wasted time in the call in the event that subsequent port and capability
check fails).


*** af_inet.c Wed Oct 18 11:06:15 2000
--- af_inet.c.orig Mon Sep 18 16:04:13 2000
***************
*** 459,471 ****
if (addr_len < sizeof(struct sockaddr_in))
return -EINVAL;

snum = ntohs(addr->sin_port);
if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
return -EACCES;

! chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
!
/* We keep a pair of addresses. rcv_saddr is the one
* used by hash lookups, and saddr is used for transmit.
*
* In the BSD API these are the same except where it
--- 459,471 ----
if (addr_len < sizeof(struct sockaddr_in))
return -EINVAL;

+ chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
+
snum = ntohs(addr->sin_port);
if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
return -EACCES;

/* We keep a pair of addresses. rcv_saddr is the one
* used by hash lookups, and saddr is used for transmit.
*
* In the BSD API these are the same except where it
***************
*** 483,493 ****
sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr;
if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret ==
RTN_BROADCAST)
sk->saddr = 0; /* Use device */
! else if(chk_addr_ret != RTN_LOCAL){
! err = -EADDERNOTAVAIL;
! goto out;
! }
!
/* Make sure we are allowed to bind here. */
if (sk->prot->get_port(sk, snum) != 0) {
sk->saddr = sk->rcv_saddr = 0;
--- 483,489 ----
sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr;
if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret ==
RTN_BROADCAST)
sk->saddr = 0; /* Use device */
!
/* Make sure we are allowed to bind here. */
if (sk->prot->get_port(sk, snum) != 0) {
sk->saddr = sk->rcv_saddr = 0;




Discussion? Please personally CC me <mpeterson@caldera.com> as I am not
currently subscribed to the linux-kernel list.

Thanks.

--
Matthew Peterson
Software Engineer
Caldera Systems, Inc
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:12    [W:0.048 / U:0.508 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site