Re: bind() allowed to non-local addresses

2000-10-20 Thread Matt Peterson

Eric Lammerts wrote:
> 
> On Fri, 20 Oct 2000, Matt Peterson wrote:
> > Are you also suggesting that every other program that expects bind() to
> > fail with EADDRNOTAVAIL are broken too?  Just for fun, I greped all
> > sources of software shipped in Caldera's distributions for instances of
> > where a check is made for EADDRNOTAVAIL after a call to bind().  Guess
> > what else besides Java is probably "broken" ...
> >
> > - lpng
> > - bind 8.2
> > - automount
> > - cvs
> > - dhcpd
> > - KDE
> > - UCL mbone
> > - ncftp
> > - netatalk
> > - nfsd
> > - rexec
> > - pppd
> > - sendmail
> > - xchat
> 
> Just for fun I looked at the sources of cvs, ncftp, netatalk, rexec
> and pppd. Guess what? None of them check for EADDRNOTAVAIL after a
> call to bind(). 

I stand corrected.  I double checked and not all of the above check
EADDRNOTAVAIL after a bind().  My grep script was only smart enough to
check for calls to bind() and EADDRNOTAVAIL .  It turns out that
EADDRNOTAVAIL is also a commonly checked return code to the
ioctl(SIOCDIFADDR) which is not an issue because it probably does not
follow the bind() code path through the kernel.  

> Cvs and pppd don't even call bind()!
> 
> Get your facts straight, please.

cvs-1.10.8/vms/rcmd.c:64:rs = bind(s, (struct sockaddr *)_isa,
sizeof(local_isa)); 
cvs-1.10.8/vms/rcmd.c:79:rs = bind(s, (struct sockaddr *)_isa,
sizeof(local_isa));

The cvs code does call bind, but you are right, it does not check rs for
EADDRNOTAVAIL.  pppd uses the ioctl() mentioned above.  My apologies.

I do not have time to go through an analize code to see if the success
of bind when the interface is not known would cause any problems.  My
guess is that it would not because before binding the interface is
looked up via ioctl() or gethostbyname().  Also as mentioned earlier in
this thread, INADDR_ANY is also commonly used.  

The point I probably failed in making is that (right or wrong) many
developers (because of tradition, documentation and various specs)
expect bind() on a non-local address to fail.  This is certainly the
case with Sun and many authors of Sockets interface documentation.  

Anyway, I am through discussing the issue.  We will probably use the
sysctl solution posted by David Miller earlier in the thread with
default bind() behavior reverted.

-- 
Matthew Peterson
Sr. Software Engineer
Caldera Systems, Inc
[EMAIL PROTECTED]

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: bind() allowed to non-local addresses

2000-10-20 Thread Matt Peterson

David Woodhouse wrote:
> 
> [EMAIL PROTECTED] said:
> >   There is NOT a bug in the JVM code that handles java.net.DatagramSock
> > et.  Don't you find it a little compelling that the nearly identical
> > JVM code passes the Java Compatibility test suite on Linux 2.2,
> > Solaris, HPUX, SCO, and even Windows?
> 
> If the JVM spec says that it 'MUST' fail when used on a non-local address,
> and the POSIX spec for bind does not say that it 'MUST' fail, then yes,
> there is a bug in the JVM if it assumes that the two are compatible.

Does some one have a copy of the posix 1003.1g draft so this can be
verified.  This is the kind of ammunition I was talking about earlier
that I would need to convince Sun to change the compatibility test
suite.  However, if the 1003.1g draft even mentions failure with errno
set to EADDRNOTAVAIL in a "SHOULD" context, or if EADDRNOTAVAIL is
mentioned at all as a error code for non-local bind, then I am afraid
(given the widespread acceptance of bind() behavior), Sun will not
change the test suite.  
 
> The fact that they just happen to behave the same in certain phases of the
> moon and on other operating systems is not relevant.

Huh?  Please give me one example of a sockets implementation (besides
Linux 2.4) of where bind() does not fail if an attempt is made to bind
do a non-local address.  Your telling me that developers who are used to
seeing a consistant behavior across OSes will think that the difference
in Linux 2.4 is irrelivant?  I don't think so. 
 
> We may decide that we want to pander to this brokenness, especially given
> the widespread nature of the false assumption that bind() will fail when
> given a non-local address. But that doesn't make the JVM non-broken.
> 

Are you also suggesting that every other program that expects bind() to
fail with EADDRNOTAVAIL are broken too?  Just for fun, I greped all
sources of software shipped in Caldera's distributions for instances of
where a check is made for EADDRNOTAVAIL after a call to bind().  Guess
what else besides Java is probably "broken" ...

- lpng
- bind 8.2
- automount
- cvs 
- dhcpd
- KDE
- UCL mbone
- ncftp
- netatalk
- nfsd
- rexec
- pppd
- sendmail
- xchat

... but the Linux kernel... Nope, it's not broken.  Lets email
maintainers of all these projects and tell them that they have been
mistaken all this time in their understanding how bind() should work and
see what kind of a response we get.


Matt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: bind() allowed to non-local addresses

2000-10-20 Thread Matt Peterson

David Woodhouse wrote:
 
 [EMAIL PROTECTED] said:
There is NOT a bug in the JVM code that handles java.net.DatagramSock
  et.  Don't you find it a little compelling that the nearly identical
  JVM code passes the Java Compatibility test suite on Linux 2.2,
  Solaris, HPUX, SCO, and even Windows?
 
 If the JVM spec says that it 'MUST' fail when used on a non-local address,
 and the POSIX spec for bind does not say that it 'MUST' fail, then yes,
 there is a bug in the JVM if it assumes that the two are compatible.

Does some one have a copy of the posix 1003.1g draft so this can be
verified.  This is the kind of ammunition I was talking about earlier
that I would need to convince Sun to change the compatibility test
suite.  However, if the 1003.1g draft even mentions failure with errno
set to EADDRNOTAVAIL in a "SHOULD" context, or if EADDRNOTAVAIL is
mentioned at all as a error code for non-local bind, then I am afraid
(given the widespread acceptance of bind() behavior), Sun will not
change the test suite.  
 
 The fact that they just happen to behave the same in certain phases of the
 moon and on other operating systems is not relevant.

Huh?  Please give me one example of a sockets implementation (besides
Linux 2.4) of where bind() does not fail if an attempt is made to bind
do a non-local address.  Your telling me that developers who are used to
seeing a consistant behavior across OSes will think that the difference
in Linux 2.4 is irrelivant?  I don't think so. 
 
 We may decide that we want to pander to this brokenness, especially given
 the widespread nature of the false assumption that bind() will fail when
 given a non-local address. But that doesn't make the JVM non-broken.
 

Are you also suggesting that every other program that expects bind() to
fail with EADDRNOTAVAIL are broken too?  Just for fun, I greped all
sources of software shipped in Caldera's distributions for instances of
where a check is made for EADDRNOTAVAIL after a call to bind().  Guess
what else besides Java is probably "broken" ...

- lpng
- bind 8.2
- automount
- cvs 
- dhcpd
- KDE
- UCL mbone
- ncftp
- netatalk
- nfsd
- rexec
- pppd
- sendmail
- xchat

... but the Linux kernel... Nope, it's not broken.  Lets email
maintainers of all these projects and tell them that they have been
mistaken all this time in their understanding how bind() should work and
see what kind of a response we get.


Matt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: bind() allowed to non-local addresses

2000-10-20 Thread Matt Peterson

Eric Lammerts wrote:
 
 On Fri, 20 Oct 2000, Matt Peterson wrote:
  Are you also suggesting that every other program that expects bind() to
  fail with EADDRNOTAVAIL are broken too?  Just for fun, I greped all
  sources of software shipped in Caldera's distributions for instances of
  where a check is made for EADDRNOTAVAIL after a call to bind().  Guess
  what else besides Java is probably "broken" ...
 
  - lpng
  - bind 8.2
  - automount
  - cvs
  - dhcpd
  - KDE
  - UCL mbone
  - ncftp
  - netatalk
  - nfsd
  - rexec
  - pppd
  - sendmail
  - xchat
 
 Just for fun I looked at the sources of cvs, ncftp, netatalk, rexec
 and pppd. Guess what? None of them check for EADDRNOTAVAIL after a
 call to bind(). 

I stand corrected.  I double checked and not all of the above check
EADDRNOTAVAIL after a bind().  My grep script was only smart enough to
check for calls to bind() and EADDRNOTAVAIL .  It turns out that
EADDRNOTAVAIL is also a commonly checked return code to the
ioctl(SIOCDIFADDR) which is not an issue because it probably does not
follow the bind() code path through the kernel.  

 Cvs and pppd don't even call bind()!
 
 Get your facts straight, please.

cvs-1.10.8/vms/rcmd.c:64:rs = bind(s, (struct sockaddr *)local_isa,
sizeof(local_isa)); 
cvs-1.10.8/vms/rcmd.c:79:rs = bind(s, (struct sockaddr *)local_isa,
sizeof(local_isa));

The cvs code does call bind, but you are right, it does not check rs for
EADDRNOTAVAIL.  pppd uses the ioctl() mentioned above.  My apologies.

I do not have time to go through an analize code to see if the success
of bind when the interface is not known would cause any problems.  My
guess is that it would not because before binding the interface is
looked up via ioctl() or gethostbyname().  Also as mentioned earlier in
this thread, INADDR_ANY is also commonly used.  

The point I probably failed in making is that (right or wrong) many
developers (because of tradition, documentation and various specs)
expect bind() on a non-local address to fail.  This is certainly the
case with Sun and many authors of Sockets interface documentation.  

Anyway, I am through discussing the issue.  We will probably use the
sysctl solution posted by David Miller earlier in the thread with
default bind() behavior reverted.

-- 
Matthew Peterson
Sr. Software Engineer
Caldera Systems, Inc
[EMAIL PROTECTED]

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

Andi Kleen wrote:
> 
> > The JRE compliance tests have a test which makes sure that for a
> > non-local addresses, bind() returns an error code, specifically
> > -EADDRNOTAVAIL.
> 
> Sounds like a bug that should be reported to Sun.
> 

Hello?  Send a bug to Sun?   I don't see any logic here.  I have traced
through the Sun code all the way to the bind() call and through to the
code in the kernel where the check for local interfaces is ignored.  The
JVM code path is VERY simple and ends up in a straightforward call to
bind().  The same problem is easily reproduced in C code.  There is NOT
a bug in the JVM code that handles java.net.DatagramSocket.  Don't you
find it a little compelling that the nearly identical JVM code passes
the Java Compatibility test suite on Linux 2.2, Solaris, HPUX, SCO, and
even Windows?  

I might even go as far as to argue that there is not a problem with the
JCK test suite either.  The BSD Socket interface is documented.  It may
be a little shady in some areas (this being one of them) but at least
the Sun test suite is expecting the documented (look at any man page or
sockets reference) and long standing behavior of bind().  Any argument
for changing the way bind() works needs to be able to stand up to the
challenge of developers who are expecting bind() to behave the way it
has for many years on many different platforms.  

Again, there is not a bug in the JVM's handling of
java.net.DatagramSocket().  I offered the JVM as an example only because
it is one application that I know of expects the standardized behavior
of bind().  The bind() behavior in Linux 2.4 is not an issue because it
affects Java only -- it is an issue because it also affects other
applications and developers that are likewise expecting the traditional
bind() behavior.

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



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

"David S. Miller" wrote:
> 
>Date: Thu, 19 Oct 2000 09:23:26 -0600
>From: Matt Peterson <[EMAIL PROTECTED]>
> 
>Have you thought about an SOL_SOCKET level socket option?  It might
>be more intuitive for programmers than an ioctl and could be
>documented with sockets where it will be used.
> 
> Where did I say "ioctl"?

Sorry,  I've had ioctl on the brain lately.  Yes, sysctl is a good
solution.

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



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

"David S. Miller" wrote:
> 
>Date: Thu, 19 Oct 2000 09:07:57 -0600
>From: Matt Peterson <[EMAIL PROTECTED]>
> 
>Hence, the JVM fails compatibility on Linux 2.4.
> 
> Due ot this and other reasons I'm restoring the 2.2.x behavior by
> default, but adding a sysctl so that systems using dynamic addressing
> may elect to get the different bind() behavior.
> 
> Later,
> David S. Miller
> [EMAIL PROTECTED]

Have you thought about an SOL_SOCKET level socket option?  It might be
more intuitive for programmers than an ioctl and could be documented
with sockets where it will be used.  Again, we would run into
compatibility issues with other Sockets implementations, but
traditionally the sockopt funtionality between implementations are
(sorta) expected to vary.   Just an idea.


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



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

"David S. Miller" wrote:
> 
>Date:Wed, 18 Oct 2000 17:20:22 -0600
>From: Matt Peterson <[EMAIL PROTECTED]>
> 
>Assuming that my "compatibility argument" is not considered valid.
>What I really need is some good ammunition for going back to Sun to
>ask them to change the JRE spec -- like some significant kernel
>features or Linux applications that relies on this new bind()
>behavior.
> 
> How about first finding out why their buggy JRE detects whether an
> address is local by trying to bind() to it :-)
> 
> Really, when an application feeds a specific address into bind() it
> must have good reason for selecting it.  All I want to know in this
> specific instance, is why Sun's JRE is sending non-local addresses
> into bind(), that's all.
> 
> Later,
> David S. Miller
> [EMAIL PROTECTED]


The JVM is simply running the appropriate native code for bytecodes that
represents the java.net.DatagramSocket(int port, InetAddress laddr)
constructor.  Documentation for this constructor reads "Creates a
datagram socket, bound to the specified local address."  What do you
expect the JVM to will do?  It trys to bind() to the supplied address
and port.  There are no bugs here.  java.net.DatagramSocket is just
trying to emulate the expected Sockets interface behavior.  The Sun JVM
compatibility test suite appropriately includes some test to ensure that
error conditions are handled correctly.  Supplying a non-local IP
address to bind() is an error condition.  Hence, the JVM fails
compatibility on Linux 2.4.

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



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

"David S. Miller" wrote:
 
Date:Wed, 18 Oct 2000 17:20:22 -0600
From: Matt Peterson [EMAIL PROTECTED]
 
Assuming that my "compatibility argument" is not considered valid.
What I really need is some good ammunition for going back to Sun to
ask them to change the JRE spec -- like some significant kernel
features or Linux applications that relies on this new bind()
behavior.
 
 How about first finding out why their buggy JRE detects whether an
 address is local by trying to bind() to it :-)
 
 Really, when an application feeds a specific address into bind() it
 must have good reason for selecting it.  All I want to know in this
 specific instance, is why Sun's JRE is sending non-local addresses
 into bind(), that's all.
 
 Later,
 David S. Miller
 [EMAIL PROTECTED]


The JVM is simply running the appropriate native code for bytecodes that
represents the java.net.DatagramSocket(int port, InetAddress laddr)
constructor.  Documentation for this constructor reads "Creates a
datagram socket, bound to the specified local address."  What do you
expect the JVM to will do?  It trys to bind() to the supplied address
and port.  There are no bugs here.  java.net.DatagramSocket is just
trying to emulate the expected Sockets interface behavior.  The Sun JVM
compatibility test suite appropriately includes some test to ensure that
error conditions are handled correctly.  Supplying a non-local IP
address to bind() is an error condition.  Hence, the JVM fails
compatibility on Linux 2.4.

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



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

"David S. Miller" wrote:
 
Date: Thu, 19 Oct 2000 09:07:57 -0600
From: Matt Peterson [EMAIL PROTECTED]
 
Hence, the JVM fails compatibility on Linux 2.4.
 
 Due ot this and other reasons I'm restoring the 2.2.x behavior by
 default, but adding a sysctl so that systems using dynamic addressing
 may elect to get the different bind() behavior.
 
 Later,
 David S. Miller
 [EMAIL PROTECTED]

Have you thought about an SOL_SOCKET level socket option?  It might be
more intuitive for programmers than an ioctl and could be documented
with sockets where it will be used.  Again, we would run into
compatibility issues with other Sockets implementations, but
traditionally the sockopt funtionality between implementations are
(sorta) expected to vary.   Just an idea.


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



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

"David S. Miller" wrote:
 
Date: Thu, 19 Oct 2000 09:23:26 -0600
From: Matt Peterson [EMAIL PROTECTED]
 
Have you thought about an SOL_SOCKET level socket option?  It might
be more intuitive for programmers than an ioctl and could be
documented with sockets where it will be used.
 
 Where did I say "ioctl"?

Sorry,  I've had ioctl on the brain lately.  Yes, sysctl is a good
solution.

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



Re: bind() allowed to non-local addresses

2000-10-19 Thread Matt Peterson

Andi Kleen wrote:
 
  The JRE compliance tests have a test which makes sure that for a
  non-local addresses, bind() returns an error code, specifically
  -EADDRNOTAVAIL.
 
 Sounds like a bug that should be reported to Sun.
 

Hello?  Send a bug to Sun?   I don't see any logic here.  I have traced
through the Sun code all the way to the bind() call and through to the
code in the kernel where the check for local interfaces is ignored.  The
JVM code path is VERY simple and ends up in a straightforward call to
bind().  The same problem is easily reproduced in C code.  There is NOT
a bug in the JVM code that handles java.net.DatagramSocket.  Don't you
find it a little compelling that the nearly identical JVM code passes
the Java Compatibility test suite on Linux 2.2, Solaris, HPUX, SCO, and
even Windows?  

I might even go as far as to argue that there is not a problem with the
JCK test suite either.  The BSD Socket interface is documented.  It may
be a little shady in some areas (this being one of them) but at least
the Sun test suite is expecting the documented (look at any man page or
sockets reference) and long standing behavior of bind().  Any argument
for changing the way bind() works needs to be able to stand up to the
challenge of developers who are expecting bind() to behave the way it
has for many years on many different platforms.  

Again, there is not a bug in the JVM's handling of
java.net.DatagramSocket().  I offered the JVM as an example only because
it is one application that I know of expects the standardized behavior
of bind().  The bind() behavior in Linux 2.4 is not an issue because it
affects Java only -- it is an issue because it also affects other
applications and developers that are likewise expecting the traditional
bind() behavior.

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



Re: bind() allowed to non-local addresses

2000-10-18 Thread Matt Peterson

[EMAIL PROTECTED] wrote:
> 
> Hello!
> 
> > 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.
> 
> You can bind to any address, it is your right. You will not able
> to receive on or to send from such socket until address will become
> really local.
> 
> Such bind is allowed because the address can be dynamic.
> Nobody wants that a service did not start only because
> the moment of start address was temporarily off-line.
> 
> Alexey

This issue here is mostly one of compatibility and standards
compliance.  You may not be able to obtain the Posix draft P1003.1g but
you should be able to see XNS Issue 5.2 which defines the
industry-standard Open Systems interfaces to communications services
(including Sockets).  You might be required to supply name and email
address to see the free online copy:

http://www.opengroup.org/onlinepubs/009619199/bind.htm#tagcjh_03_03

According to the specs and numerous implementations, looks like the way
bind() is supposed to work is that it returns EADDRNOTAVAIL if the
specified address is not available from the local machine rather than
waiting for a recv() or send() to fail.  Many developers working on
software ports have felt the pain of loose interpretations of the
Sockets interface.  This divergence would add yet another headache.  

Your argument for supporting dynamic interfaces is valid, I really like
the idea of being able to bind to an interface that is not up yet. I can
definitely see where this would be helpful -- too bad is is not part of
the spec.  What I don't like about it is that it may break existing
applications.  Is the Socket spec so loose that Linux 2.4 can be
comfortable in its current condition?  I hope not.  

Since it is possible that this "bug" un-repairably breaks the
portability of our application (a Java virtual machine) to the new
kernel, I suspect that there may be other applications that it breaks
too.  

Assuming that my "compatibility argument" is not considered valid.  What
I really need is some good ammunition for going back to Sun to ask them
to change the JRE spec -- like some significant kernel features or Linux
applications that relies on this new bind() behavior.

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



bind() allowed to non-local addresses

2000-10-18 Thread Matt Peterson

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 <[EMAIL PROTECTED]> 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 [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



bind() allowed to non-local addresses

2000-10-18 Thread Matt Peterson

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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: bind() allowed to non-local addresses

2000-10-18 Thread Matt Peterson

[EMAIL PROTECTED] wrote:
 
 Hello!
 
  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.
 
 You can bind to any address, it is your right. You will not able
 to receive on or to send from such socket until address will become
 really local.
 
 Such bind is allowed because the address can be dynamic.
 Nobody wants that a service did not start only because
 the moment of start address was temporarily off-line.
 
 Alexey

This issue here is mostly one of compatibility and standards
compliance.  You may not be able to obtain the Posix draft P1003.1g but
you should be able to see XNS Issue 5.2 which defines the
industry-standard Open Systems interfaces to communications services
(including Sockets).  You might be required to supply name and email
address to see the free online copy:

http://www.opengroup.org/onlinepubs/009619199/bind.htm#tagcjh_03_03

According to the specs and numerous implementations, looks like the way
bind() is supposed to work is that it returns EADDRNOTAVAIL if the
specified address is not available from the local machine rather than
waiting for a recv() or send() to fail.  Many developers working on
software ports have felt the pain of loose interpretations of the
Sockets interface.  This divergence would add yet another headache.  

Your argument for supporting dynamic interfaces is valid, I really like
the idea of being able to bind to an interface that is not up yet. I can
definitely see where this would be helpful -- too bad is is not part of
the spec.  What I don't like about it is that it may break existing
applications.  Is the Socket spec so loose that Linux 2.4 can be
comfortable in its current condition?  I hope not.  

Since it is possible that this "bug" un-repairably breaks the
portability of our application (a Java virtual machine) to the new
kernel, I suspect that there may be other applications that it breaks
too.  

Assuming that my "compatibility argument" is not considered valid.  What
I really need is some good ammunition for going back to Sun to ask them
to change the JRE spec -- like some significant kernel features or Linux
applications that relies on this new bind() behavior.

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