Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 86313

Summary: Erroneous address ordering from glibc getaddrinfo()
Product: Gentoo Linux Reporter: Fredrik Tolf <fredrik>
Component: [OLD] Core systemAssignee: Gentoo Toolchain Maintainers <toolchain>
Status: RESOLVED UPSTREAM    
Severity: normal    
Priority: High    
Version: 2004.2   
Hardware: All   
OS: All   
Whiteboard:
Package list:
Runtime testing required: ---
Attachments: Patch to sort addresses correctly
Simple program to test getaddrinfo()

Description Fredrik Tolf 2005-03-22 14:40:29 UTC
The getaddrinfo() implementation in sysdeps/posix/getaddrinfo.c in glibc sorts destination addresses incorrectly.

For example, I have a dual-stack v4/v6 network with site-local v4 addresses (192.168.x.x) and globally aggregatble 6to4 addresses (2002:52b6:8514::/48). One pair of hosts on this network are called pc7 and pc16. pc7's addresses are 192.168.1.254 and 2002:52b6:8514:200:20c:76ff:fe3b:a3f4. pc16's addresses are 192.168.0.7 and 2002:52b6:8514:100::3.
When I try to connect from pc7 to pc16, I get the destination addresses listed in the wrong order:
192.168.0.7
2002:52b6:8514:100::3

This is incorrect, since, according to pages 12-13 of RFC 3484, these should be tied on rules 1 through 5, and then the IPv6 addresses should be prioritized before the IPv4 address on Rule 6 (prefer higher precedence), since 6to4 addresses have precedence 30, while IPv4 addresses (treated as IPv4-mapped IPv6 addresses according to section 3.2 in RFC 3484) have precedence 10.

There is a small typo bug, however, in the match_prefix function in getaddrinfo.c that causes this behavior. On line 1267 (in the glibc-2.3.4.20041102 ebuild, including its patches), the condition is:
    while (bits > 8)
whereas it should be:
    while (bits >= 8)
Because of this, the match_prefix function never matches the entire address, and never finds the difference in scope. Instead, it goes on to rule 8 (prefer smaller scope), which prefers the IPv4 address since the scope of the v4 address in site-local, which is more narrow than the globally aggregatable 6to4 address.

I've reported this to the glibc bugzilla:
<http://sources.redhat.com/bugzilla/show_bug.cgi?id=524>

However, that was in November, and I still haven't got a reply, so I was at least hoping that Gentoo might patch this until it's fixed upstream (so that I don't have to patch manually anymore).
Comment 1 Fredrik Tolf 2005-03-22 14:42:31 UTC
Created attachment 54182 [details, diff]
Patch to sort addresses correctly

This is the same patch that I sent to the glibc bugzilla.
Comment 2 Fredrik Tolf 2005-03-22 14:45:19 UTC
Created attachment 54183 [details]
Simple program to test getaddrinfo()

This is a simple program to help test the getaddrinfo implementation. Call with
a hostname to get its addresses output (in hex format, though) on stdout.
Call without arguments to experience a segv. ;-)
Comment 3 SpanKY gentoo-dev 2005-03-22 15:36:17 UTC
should be sent to glibc bugzilla ...
Comment 4 Fredrik Tolf 2005-04-19 18:45:58 UTC
By all means, and like I wrote in the initial description, I _have_ sent it to the glibc bugzilla.

However, since noone there seems to have noticed it in three months, it would be very nice to have the patch in portage until anyone on the glibc bugzilla sees it.
Comment 5 Fredrik Tolf 2005-09-28 14:17:15 UTC
Upstream finally accepted the patch, so no more need for this bug.
Comment 6 SpanKY gentoo-dev 2005-09-28 14:52:20 UTC
yeah sorry, i cant read

i'll add this patch to our current glibc-2.3.5 patchset, thanks
Comment 7 SpanKY gentoo-dev 2005-09-28 16:57:48 UTC
now in glibc-2.3.5-r1
Comment 8 Toralf Förster gentoo-dev 2005-10-08 07:55:51 UTC
The more I have a look at the code snippet the more I am wondering iwhether the
patch itself is ok/enough or not. Have a look at the line immediately after the
while()-loop:

...
if (bits < 8)
...

Before the patch was applied the case "bits is equal to 8" would result in the
fact that neither the while()-loop nor the if()-condition would met this case.
Now the if()-condition seems to be true at all- and therefore senseless.

So I am wondering if either the if()-condition was senseless already before or
do I miss something ?

P.S. I tried to get an account at sources.bugzilla... today in the morning to
make a comment directly into
http://sources.redhat.com/bugzilla/show_bug.cgi?id=524 but didn't get an
confirmation at my account request until now.
Comment 9 Fredrik Tolf 2005-10-09 03:46:29 UTC
I'm not sure if I'm following you. Are you saying that the `if' condition is
always triggered? In that case, you are wrong, because it is not triggered if
`bits' was initially divisible by 8 (which seems to be the common case).

If you are saying that the `if' condition is never triggered, you are also
wrong, because it is used in the case where `bits' in not divisible by 8.
Admittedly, there are no such cases in the current prefix lists, but...

If you didn't mean either, then I am sorry, but I will have to ask that you
clarify yourself. I just couldn't seem to be able to parse "Now the
if()-condition seems to be true at all".

If there is anything that I'm dubious about, it is if the initializers of the
prefix lists really gain in the same results in all endiannesses.