diff options
author | Joachim Wiberg <troglobit@gmail.com> | 2022-11-23 23:03:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-23 23:03:25 +0100 |
commit | b5e2af279dd7afba792c79f49de9125d1de51474 (patch) | |
tree | 53bc8533b07e652cd4d24ab8dbe1849498a0d31a | |
parent | cdd8d4e59c8a042f97f3983bfe26ccf4172c1884 (diff) | |
parent | 8b4688c2a6ed65f383327d7267ffcb60e3205d32 (diff) | |
download | libnet-b5e2af279dd7afba792c79f49de9125d1de51474.tar.gz |
Merge pull request #150 from aroulin/fix-segfault-ifaddrlist
libnet_if_addr.c: fix segfault when number of IPs > 512
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
-rw-r--r-- | src/libnet_if_addr.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/src/libnet_if_addr.c b/src/libnet_if_addr.c index ef1d6c0..3f1fac3 100644 --- a/src/libnet_if_addr.c +++ b/src/libnet_if_addr.c @@ -47,6 +47,7 @@ #include "../include/ifaddrlist.h" #define MAX_IPADDR 512 +static size_t ip_addr_num = MAX_IPADDR; #if !(__WIN32__) @@ -104,10 +105,17 @@ int libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf) { (void)dev; /* unused */ - static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR]; + static struct libnet_ifaddr_list *ifaddrlist = NULL, *ifaddrlist_tmp = NULL; struct ifaddrs *ifap, *ifa; int i = 0; - memset (ifaddrlist, 0 , sizeof(ifaddrlist)); + + if (!ifaddrlist) { + ifaddrlist = calloc(ip_addr_num, sizeof(struct libnet_ifaddr_list)); + if (!ifaddrlist) { + snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): OOM when allocating initial ifaddrlist", __func__); + return 0; + } + } if (getifaddrs(&ifap) != 0) { @@ -130,6 +138,18 @@ libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, regis ifaddrlist[i].addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; ++i; } + + if (i == ip_addr_num) { + // grow by a factor of 1.5, close enough to golden ratio + ip_addr_num += ip_addr_num >> 2; + ifaddrlist_tmp = realloc(ifaddrlist, ip_addr_num * sizeof(struct libnet_ifaddr_list)); + if (!ifaddrlist_tmp) { + snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): OOM when reallocating larger ifaddrlist", __func__); + break; + } + + ifaddrlist = ifaddrlist_tmp; + } } freeifaddrs(ifap); @@ -485,6 +505,7 @@ good: free(al[i].device); al[i].device = NULL; } + free(al); return (1); bad: @@ -493,6 +514,7 @@ bad: free(al[i].device); al[i].device = NULL; } + free(al); return (-1); } |