Package: libc0.1 Version: 2.13-35 Severity: grave Tags: d-i upstream patch ipv6 Justification: renders package unusable
On a GNU/kFreeBSD machine without IPv6 connection, but with a DNS server returning IPv6 addresses, getaddrinfo() might fail to return only IPv4 addresses, causing some applications to fail to connect to some host using an host name. This happens when getaddrinfo() is called with service = 0 (aka port), which is perfectly valid. getaddrinfo() determine the source address the kernel would use for a given destination address by opening a SOCK_DGRAM connection with ŧhe same port as the service. A Linux kernel accepts such a connection with the port 0, while the FreeBSD kernel doesn't. A lot of applications are calling getaddrinfo() with the port they are going to use later, but a few others do not. Among them busybox is affected, causing wget on IPv6 addresses for non-IPv6 connected machine to fail, in turn causing the installation to fail: | $ busybox wget http://ftp.debian.org | Connecting to ftp.debian.org ([2001:610:1908:b000::148:12]:80) | wget: can't connect to remote host: No route to host As more and more Debian mirrors (including the default ftp.debian.org) have an IPv6 address, it makes GNU/kFreeBSD difficultly installable on such machines. The fix is to use port = 1 in such case, as it is done in the FreeBSD libc. This is what the attached patch does. I'll do an upload of eglibc in the next days, including this patch. -- System Information: Debian Release: wheezy/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: kfreebsd-amd64 (x86_64) Kernel: kFreeBSD 8.3-1-amd64 Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libc6 depends on: ii libc-bin 2.13-35 ii libgcc1 1:4.7.1-7 libc6 recommends no packages. Versions of packages libc6 suggests: ii debconf [debconf-2.0] 1.5.46 ii glibc-doc 2.13-35 ii locales 2.13-35 ii locales-all [locales] 2.13-35 -- debconf information excluded
--- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -2267,8 +2267,15 @@ } socklen_t sl = sizeof (results[i].source_addr); + struct sockaddr sa = *q->ai_addr; +#ifdef __FreeBSD_kernel__ + /* The FreeBSD kernel doesn't allow connections on port 0. Use + port 1 instead, as on the FreeBSD libc. */ + if (((struct sockaddr_in *)&sa)->sin_port == htons(0)) + ((struct sockaddr_in *)&sa)->sin_port = htons(1); +#endif if (fd != -1 - && __connect (fd, q->ai_addr, q->ai_addrlen) == 0 + && __connect (fd, &sa, q->ai_addrlen) == 0 && __getsockname (fd, (struct sockaddr *) &results[i].source_addr, &sl) == 0)