1 |
From: Andreas Schwab <schwab@linux-m68k.org> |
2 |
Subject: Re: Segfault in getifaddrs_internal in glibc-2.20 |
3 |
Date: Sat, 13 Sep 2014 10:18:20 +0200 |
4 |
|
5 |
Allan McRae <allan@archlinux.org> writes: |
6 |
|
7 |
> diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c |
8 |
> b/sysdeps/unix/sysv/linux/ifaddrs.c |
9 |
> index 2c04e17..1fa4960 100644 |
10 |
> --- a/sysdeps/unix/sysv/linux/ifaddrs.c |
11 |
> +++ b/sysdeps/unix/sysv/linux/ifaddrs.c |
12 |
> @@ -774,7 +774,7 @@ getifaddrs_internal (struct ifaddrs **ifap) |
13 |
> unsigned int preflen; |
14 |
> |
15 |
> if ((max_prefixlen > 0) && |
16 |
> - (ifam->ifa_prefixlen > max_prefixlen)) |
17 |
> + (max_prefixlen > ifam->ifa_prefixlen)) |
18 |
> preflen = max_prefixlen; |
19 |
> else |
20 |
> preflen = ifam->ifa_prefixlen; |
21 |
> |
22 |
> |
23 |
> This seems to fix the issue for them. After looking at the code for a |
24 |
> long time, I am still not sure if this is the correct fix. Can anyone |
25 |
> confirm/deny? |
26 |
|
27 |
That doesn't make any sense. As the name says, max_prefixlen is the |
28 |
limit for the prefix length, but this makes it always equal to |
29 |
max_prefixlen (which is always > 0 here). The bug is of course that |
30 |
commit d89b3d8 doesn't handle a prefix length of zero. |
31 |
|
32 |
Andreas. |
33 |
|
34 |
[BZ #17371] |
35 |
* sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs_internal): Fix |
36 |
last change to handle zero prefix length. |
37 |
--- |
38 |
sysdeps/unix/sysv/linux/ifaddrs.c | 11 ++++------- |
39 |
1 file changed, 4 insertions(+), 7 deletions(-) |
40 |
|
41 |
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c |
42 |
index 2c04e17..a47b2ed 100644 |
43 |
--- a/sysdeps/unix/sysv/linux/ifaddrs.c |
44 |
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c |
45 |
@@ -770,20 +770,17 @@ getifaddrs_internal (struct ifaddrs **ifap) |
46 |
|
47 |
if (cp != NULL) |
48 |
{ |
49 |
- char c; |
50 |
unsigned int preflen; |
51 |
|
52 |
- if ((max_prefixlen > 0) && |
53 |
- (ifam->ifa_prefixlen > max_prefixlen)) |
54 |
+ if (ifam->ifa_prefixlen > max_prefixlen) |
55 |
preflen = max_prefixlen; |
56 |
else |
57 |
preflen = ifam->ifa_prefixlen; |
58 |
|
59 |
- for (i = 0; i < ((preflen - 1) / 8); i++) |
60 |
+ for (i = 0; i < preflen / 8; i++) |
61 |
*cp++ = 0xff; |
62 |
- c = 0xff; |
63 |
- c <<= ((128 - preflen) % 8); |
64 |
- *cp = c; |
65 |
+ if (preflen % 8) |
66 |
+ *cp = 0xff << (8 - preflen % 8); |
67 |
} |
68 |
} |
69 |
} |