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/lib/libc | |
| 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/lib/libc')
| -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++) { |
