diff options
author | claudio <> | 2008-11-24 20:08:49 +0000 |
---|---|---|
committer | claudio <> | 2008-11-24 20:08:49 +0000 |
commit | 1cb9fdc86cd93809f9606b4865b35475b00b7933 (patch) | |
tree | 5e3df59e7fdbdee8b5350d4479dc16f459c64429 /src | |
parent | 4483ecc8aa0fe10a3c5ed81f2f06c03dfbc1241c (diff) | |
download | openbsd-1cb9fdc86cd93809f9606b4865b35475b00b7933.tar.gz openbsd-1cb9fdc86cd93809f9606b4865b35475b00b7933.tar.bz2 openbsd-1cb9fdc86cd93809f9606b4865b35475b00b7933.zip |
Correctly jump over routing headers and calculate the size of the if_data
struct in the if_msghdr instead of using sizeof() blindly. This allows us
to grow if_data without causing issues for the getifaddrs() users.
OK deraadt@ (who needs this for some cool upcomming stuff)
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/net/getifaddrs.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/lib/libc/net/getifaddrs.c b/src/lib/libc/net/getifaddrs.c index 0db89f6c19..6f7ea15721 100644 --- a/src/lib/libc/net/getifaddrs.c +++ b/src/lib/libc/net/getifaddrs.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: getifaddrs.c,v 1.9 2002/08/09 06:12:25 itojun Exp $ */ | 1 | /* $OpenBSD: getifaddrs.c,v 1.10 2008/11/24 20:08:49 claudio Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 1995, 1999 | 4 | * Copyright (c) 1995, 1999 |
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #include <errno.h> | 37 | #include <errno.h> |
38 | #include <ifaddrs.h> | 38 | #include <ifaddrs.h> |
39 | #include <stddef.h> | ||
39 | #include <stdlib.h> | 40 | #include <stdlib.h> |
40 | #include <string.h> | 41 | #include <string.h> |
41 | #include <unistd.h> | 42 | #include <unistd.h> |
@@ -61,7 +62,7 @@ getifaddrs(struct ifaddrs **pif) | |||
61 | struct sockaddr_dl *dl; | 62 | struct sockaddr_dl *dl; |
62 | struct sockaddr *sa; | 63 | struct sockaddr *sa; |
63 | u_short index = 0; | 64 | u_short index = 0; |
64 | size_t len, alen; | 65 | size_t len, alen, dlen; |
65 | struct ifaddrs *ifa, *ift; | 66 | struct ifaddrs *ifa, *ift; |
66 | int i; | 67 | int i; |
67 | char *data; | 68 | char *data; |
@@ -92,7 +93,8 @@ getifaddrs(struct ifaddrs **pif) | |||
92 | if (ifm->ifm_addrs & RTA_IFP) { | 93 | if (ifm->ifm_addrs & RTA_IFP) { |
93 | index = ifm->ifm_index; | 94 | index = ifm->ifm_index; |
94 | ++icnt; | 95 | ++icnt; |
95 | dl = (struct sockaddr_dl *)(ifm + 1); | 96 | dl = (struct sockaddr_dl *)(next + |
97 | rtm->rtm_hdrlen); | ||
96 | dcnt += SA_RLEN((struct sockaddr *)dl) + | 98 | dcnt += SA_RLEN((struct sockaddr *)dl) + |
97 | ALIGNBYTES; | 99 | ALIGNBYTES; |
98 | dcnt += sizeof(ifm->ifm_data); | 100 | dcnt += sizeof(ifm->ifm_data); |
@@ -109,7 +111,7 @@ getifaddrs(struct ifaddrs **pif) | |||
109 | #define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) | 111 | #define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) |
110 | if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) | 112 | if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) |
111 | break; | 113 | break; |
112 | p = (char *)(ifam + 1); | 114 | p = next + rtm->rtm_hdrlen; |
113 | ++icnt; | 115 | ++icnt; |
114 | /* Scan to look for length of address */ | 116 | /* Scan to look for length of address */ |
115 | alen = 0; | 117 | alen = 0; |
@@ -169,7 +171,8 @@ getifaddrs(struct ifaddrs **pif) | |||
169 | ifm = (struct if_msghdr *)rtm; | 171 | ifm = (struct if_msghdr *)rtm; |
170 | if (ifm->ifm_addrs & RTA_IFP) { | 172 | if (ifm->ifm_addrs & RTA_IFP) { |
171 | index = ifm->ifm_index; | 173 | index = ifm->ifm_index; |
172 | dl = (struct sockaddr_dl *)(ifm + 1); | 174 | dl = (struct sockaddr_dl *)(next + |
175 | rtm->rtm_hdrlen); | ||
173 | 176 | ||
174 | cif = ift; | 177 | cif = ift; |
175 | ift->ifa_name = names; | 178 | ift->ifa_name = names; |
@@ -185,7 +188,11 @@ getifaddrs(struct ifaddrs **pif) | |||
185 | 188 | ||
186 | /* ifm_data needs to be aligned */ | 189 | /* ifm_data needs to be aligned */ |
187 | ift->ifa_data = data = (void *)ALIGN(data); | 190 | ift->ifa_data = data = (void *)ALIGN(data); |
188 | memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); | 191 | dlen = rtm->rtm_hdrlen - |
192 | offsetof(struct if_msghdr, ifm_data); | ||
193 | if (dlen > sizeof(ifm->ifm_data)) | ||
194 | dlen = sizeof(ifm->ifm_data); | ||
195 | memcpy(data, &ifm->ifm_data, dlen); | ||
189 | data += sizeof(ifm->ifm_data); | 196 | data += sizeof(ifm->ifm_data); |
190 | 197 | ||
191 | ift = (ift->ifa_next = ift + 1); | 198 | ift = (ift->ifa_next = ift + 1); |
@@ -203,7 +210,7 @@ getifaddrs(struct ifaddrs **pif) | |||
203 | ift->ifa_name = cif->ifa_name; | 210 | ift->ifa_name = cif->ifa_name; |
204 | ift->ifa_flags = cif->ifa_flags; | 211 | ift->ifa_flags = cif->ifa_flags; |
205 | ift->ifa_data = NULL; | 212 | ift->ifa_data = NULL; |
206 | p = (char *)(ifam + 1); | 213 | p = next + rtm->rtm_hdrlen; |
207 | /* Scan to look for length of address */ | 214 | /* Scan to look for length of address */ |
208 | alen = 0; | 215 | alen = 0; |
209 | for (p0 = p, i = 0; i < RTAX_MAX; i++) { | 216 | for (p0 = p, i = 0; i < RTAX_MAX; i++) { |