summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorAlexey Izbyshev <izbyshev@ispras.ru>2023-02-27 23:05:16 +0300
committerRich Felker <dalias@aerifal.cx>2023-02-28 11:59:53 -0500
commit1a708ece1ad8b924466e81c5fcdf4e22311fd770 (patch)
tree55419af5ea43de87affd4f0001fe49b92b600eb7 /src/network
parentc499c1084eaccd83e4b6e60883a5d92df0202c5e (diff)
downloadmusl-1a708ece1ad8b924466e81c5fcdf4e22311fd770.tar.gz
getifaddrs: fix UB via taking address of null pointer union dereference
getifaddrs computes &ctx->first->ifa even if ctx->first is NULL. While this shouldn't be possible on the success path because the loopback interface is hardcoded into the kernel, this is still possible on the error path (for example, if __rtnetlink_enumerate couldn't create a socket due to exceeding the fd limit).
Diffstat (limited to 'src/network')
-rw-r--r--src/network/getifaddrs.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c
index fed75bd8..74df4d6c 100644
--- a/src/network/getifaddrs.c
+++ b/src/network/getifaddrs.c
@@ -39,8 +39,8 @@ struct ifaddrs_storage {
};
struct ifaddrs_ctx {
- struct ifaddrs_storage *first;
- struct ifaddrs_storage *last;
+ struct ifaddrs *first;
+ struct ifaddrs *last;
struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE];
};
@@ -195,9 +195,9 @@ static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
}
if (ifs->ifa.ifa_name) {
- if (!ctx->first) ctx->first = ifs;
- if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa;
- ctx->last = ifs;
+ if (!ctx->first) ctx->first = &ifs->ifa;
+ if (ctx->last) ctx->last->ifa_next = &ifs->ifa;
+ ctx->last = &ifs->ifa;
} else {
free(ifs);
}
@@ -210,7 +210,7 @@ int getifaddrs(struct ifaddrs **ifap)
int r;
memset(ctx, 0, sizeof *ctx);
r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
- if (r == 0) *ifap = &ctx->first->ifa;
- else freeifaddrs(&ctx->first->ifa);
+ if (r == 0) *ifap = ctx->first;
+ else freeifaddrs(ctx->first);
return r;
}