[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#164768: marked as done (libc: IPv6 still not correct.)



Your message dated Wed, 16 Oct 2002 16:36:50 -0400
with message-id <20021016203650.GW5613@phunnypharm.org>
and subject line Bug#164768: libc: IPv6 still not correct.
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--------------------------------------
Received: (at submit) by bugs.debian.org; 14 Oct 2002 23:56:06 +0000
>From matthew@pick.ucam.org Mon Oct 14 18:56:05 2002
Return-path: <matthew@pick.ucam.org>
Received: from plum.csi.cam.ac.uk [131.111.8.3] 
	by master.debian.org with esmtp (Exim 3.12 1 (Debian))
	id 181F48-0007zN-00; Mon, 14 Oct 2002 18:56:04 -0500
Received: from rapun.sel.cam.ac.uk ([131.111.232.108] ident=mail)
	by plum.csi.cam.ac.uk with esmtp (Exim 4.10)
	id 181F47-0008KJ-00
	for submit@bugs.debian.org; Tue, 15 Oct 2002 00:56:03 +0100
Received: from matthew by rapun.sel.cam.ac.uk with local (Exim 3.35 #1 (Debian))
	id 181F47-0002cm-00; Tue, 15 Oct 2002 00:56:03 +0100
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID: <[🔎] 15787.22931.74254.66242@rapun.sel.cam.ac.uk>
Date: Tue, 15 Oct 2002 00:56:03 +0100
From: Matthew Vernon <matthew@sel.cam.ac.uk>
To: submit@bugs.debian.org
Subject: libc: IPv6 still not correct.
X-Mailer: VM 7.03 under Emacs 21.2.1
X-Debbugs-CC: Colin Watson <cjwatson@flatline.org.uk>
Sender: Matthew Vernon <matthew@pick.ucam.org>
Delivered-To: submit@bugs.debian.org

Package: libc6
Version: 2.2.5-11.2
Severity: important
Tags: patch

Hi,

This bug was in fact once #82468 (now archived), but having checked
the libc code (and retried the test case), it still exists (and so
really needs fixing.

Executive summary: libc uses an incorrectly-sized sockaddr_in6
structure, which causes programs running under 2.2 kernels to get
error messages when in fact they are behving correctly. Hence the
important severity.

A 2.2 kernel uses:
  struct sockaddr_in6 {
      unsigned short int  sin6_family;    /* AF_INET6 */
        __u16     sin6_port;      /* Transport layer port # */
          __u32     sin6_flowinfo;  /* IPv6 flow information */
            struct in6_addr   sin6_addr;      /* IPv6 address */
 };

While 2.4 (and glibc complies) use:
  struct sockaddr_in6 {
    unsigned short int  sin6_family;    /* AF_INET6 */
    __u16     sin6_port;      /* Transport layer port # */
    __u32     sin6_flowinfo;  /* IPv6 flow information */
    struct in6_addr   sin6_addr;      /* IPv6 address */
    __u32     sin6_scope_id;  /* scope id (new in RFC2553) */
  };


getpeername returns the kernel's idea of a sockaddr_in6 when using an
ipv6 socket.  Now getnameinfo has the following code 

  case AF_INET6:
        if (addrlen < sizeof (struct sockaddr_in6))
            return EAI_FAMILY;

in which the sizeof uses the libc idea of an sockaddr_in6...

Test code:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>

int
main(int argc, char **argv) {
  int sockfd;
  struct addrinfo req,*ans;
  struct sockaddr_storage tmp;
  int len = sizeof(struct sockaddr_storage);

  memset(&req,0,sizeof(req));
  req.ai_flags = 0;
  req.ai_family = PF_INET6;
  req.ai_socktype = SOCK_STREAM;
  req.ai_protocol =IPPROTO_TCP;
  if (getaddrinfo("spacelabs.nl","smtp",&req,&ans) != 0) {
  	printf("getaddrinfo failed\n");
  	return -1;
  }
  sockfd = socket(ans->ai_family,ans->ai_socktype,ans->ai_protocol);
  if (connect(sockfd,ans->ai_addr,ans->ai_addrlen) < 0) {
  	printf("connect failed\n");
  	return -1;
  }
  if (getpeername(sockfd,(struct sockaddr *) &tmp,&len) < 0) {
  	printf("getpeernamed failed\n");
  	return -1;
  }
  printf("getpeername len -> %d, sizeof(sockaddr_in6) -> %d\n",
      len, sizeof(struct sockaddr_in6));
  exit(0);
}

Running this on a current stable libc with 2.2 kernel gives:
  getpeername len -> 24, sizeof(sockaddr_in6) -> 28 
whilst with a 2.4 kernel, one gets:
  getpeername len -> 28, sizeof(sockaddr_in6) -> 28

Now this is a problem if you do, for example:
int
get_sock_port(int sock, int local)
{
        struct sockaddr_storage from;
        socklen_t fromlen;
        char strport[NI_MAXSERV];

        /* Get IP address of client. */
        fromlen = sizeof(from);
        memset(&from, 0, sizeof(from));
        if (local) {
                if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) {
                        error("getsockname failed: %.100s", strerror(errno));
                        return 0;
                }
        } else {
                if (getpeername(sock, (struct sockaddr *) & from, &fromlen) < 0)
 {
                        debug("getpeername failed: %.100s", strerror(errno));
                        fatal_cleanup();
                }
        }
        /* Return port number. */
        if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
             strport, sizeof(strport), NI_NUMERICSERV) != 0)
                fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed");
        return atoi(strport);
}

[code from SSH] getnameinfo barfs at this point on a 2.2 kernel.

Now, a fix to libc might be:
--- glibc-2.2.5/inet/getnameinfo.c	Tue Jan 30 00:23:05 2001
+++ glibc-2.2.5-fix/inet/getnameinfo.c	Sun Aug  4 01:15:42 2002
@@ -62,6 +62,13 @@
 # define min(x,y) (((x) > (y)) ? (y) : (x))
 #endif /* min */
 
+struct __sockaddr_in6_rfc2133
+  {
+      __SOCKADDR_COMMON (__sin6_);
+      in_port_t __sin6_port;
+      uint32_t __sin6_flowinfo;
+      struct in6_addr __sin6_addr;
+  };
 
 static char *
 internal_function
@@ -193,7 +200,7 @@
 	return EAI_FAMILY;
       break;
     case AF_INET6:
-      if (addrlen < sizeof (struct sockaddr_in6))
+      if (addrlen < sizeof (struct __sockaddr_in6_rfc2133))
 	return EAI_FAMILY;
       break;
     default:
@@ -298,7 +305,8 @@
 
 		    c = inet_ntop (AF_INET6,
 				   (const void *) &sin6p->sin6_addr, host, hostlen);
-		    scopeid = sin6p->sin6_scope_id;
+		    scopeid = (addrlen >= sizeof(struct sockaddr_in6)) ? 
+			      sin6p->sin6_scope_id : 0;
 		    if (scopeid != 0)
 		      {
 			/* Buffer is >= IFNAMSIZ+1.  */


For more information on this bug, please see
http://bugs.debian.org/82468

Thanks,

Matthew

-- 
Rapun.sel - outermost outpost of the Pick Empire
http://www.pick.ucam.org

---------------------------------------
Received: (at 164768-done) by bugs.debian.org; 16 Oct 2002 20:36:52 +0000
>From bmc@phunnypharm.org Wed Oct 16 15:36:52 2002
Return-path: <bmc@phunnypharm.org>
Received: from blowme.phunnypharm.org [65.207.35.140] 
	by master.debian.org with esmtp (Exim 3.12 1 (Debian))
	id 181uuS-0001UO-00; Wed, 16 Oct 2002 15:36:52 -0500
Received: from hopper.phunnypharm.org ([192.168.0.13] ident=mail)
	by blowme.phunnypharm.org with esmtp (Exim 3.35 #1 (Debian))
	id 181uuR-0001Z8-00; Wed, 16 Oct 2002 16:36:51 -0400
Received: from bmc by hopper.phunnypharm.org with local (Exim 3.36 #1 (Debian))
	id 181uuQ-0008Un-00; Wed, 16 Oct 2002 16:36:50 -0400
Date: Wed, 16 Oct 2002 16:36:50 -0400
From: Ben Collins <bcollins@debian.org>
To: Matthew Vernon <matthew@sel.cam.ac.uk>
Cc: 164768-done@bugs.debian.org
Subject: Re: Bug#164768: libc: IPv6 still not correct.
Message-ID: <20021016203650.GW5613@phunnypharm.org>
References: <[🔎] 15787.22931.74254.66242@rapun.sel.cam.ac.uk> <[🔎] 1034673694.9997.4.camel@mill> <[🔎] 15787.60788.715242.744044@rapun.sel.cam.ac.uk> <20021016013853.GB5613@phunnypharm.org> <15789.50859.118525.42764@rapun.sel.cam.ac.uk>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <15789.50859.118525.42764@rapun.sel.cam.ac.uk>
User-Agent: Mutt/1.4i
Delivered-To: 164768-done@bugs.debian.org
X-Spam-Status: No, hits=-16.7 required=5.0
	tests=IN_REP_TO,QUOTED_EMAIL_TEXT,REFERENCES,
	      SIGNATURE_SHORT_DENSE,SPAM_PHRASE_01_02,USER_AGENT,
	      USER_AGENT_MUTT
	version=2.41
X-Spam-Level: 

On Wed, Oct 16, 2002 at 09:06:03PM +0100, Matthew Vernon wrote:
> reopen 164768
> quit
> [please preserve the X-Debbugs-CC]
> Ben Collins writes:
> <snip>
>  > > With respect, I think you misunderstand. The kernel defines what the
>  > > structure should be, and returns it accordingly. It is the job of the
>  > > libc to hide this from the programmer; especially when the structure
>  > > in question changes over time in the kernel (quite legitimately).
>  > 
>  > No, he understands perfectly well. Fact is, 2.2. kernels were broken
>  > with regard to ipv6 anyway, and supporting it just leaves the hacks in
>  > place for longer. If you want proper ipv6, use 2.4.x kernels.
> 
> For the avoidance of doubt, this is the same problem as reported in
> 82468[1] (which was closed "this ssh/libc bug is long since gone"
> without any fix being applied), but I can't re-open that bug since its
> archived.
> 
> In the example code I posted with this report (and which appears in
> 82468), the struct sockaddr returned by getpeername is what
> getnameinfo barfs on. That code comes from ssh, which by default will
> use AF_UNSPEC in the ai_family of hints to getaddrinfo, for example.  

And as I've said in the past numerous times. The fact that every other
IPv6 using program (including apache, bind, telnet, etc.) get this
right, and sshd doesn't, isn't libc's fault.

I've pushed this over to sshd, and we wont accept the error here.

-- 
Debian     - http://www.debian.org/
Linux 1394 - http://www.linux1394.org/
Subversion - http://subversion.tigris.org/
Deqo       - http://www.deqo.com/



Reply to: