mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
BUG/MEDIUM: standard: Fix memory leak in str2ip2()
An haproxy compiled with: > make -j4 all TARGET=linux2628 USE_GETADDRINFO=1 And running with a configuration like this: defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 frontend fe bind :::8080 v4v6 default_backend be backend be server s example.com:80 check Will leak memory inside `str2ip2()`, because the list `result` is not properly freed in success cases: ==18875== 140 (76 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 87 of 111 ==18875== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==18875== by 0x537A565: gaih_inet (getaddrinfo.c:1223) ==18875== by 0x537DD5D: getaddrinfo (getaddrinfo.c:2425) ==18875== by 0x4868E5: str2ip2 (standard.c:733) ==18875== by 0x43F28B: srv_set_addr_via_libc (server.c:3767) ==18875== by 0x43F50A: srv_iterate_initaddr (server.c:3879) ==18875== by 0x43F50A: srv_init_addr (server.c:3944) ==18875== by 0x475B30: init (haproxy.c:1595) ==18875== by 0x40406D: main (haproxy.c:2479) The exists as long as the usage of getaddrinfo in that function exists, it was introduced in commit: d5f4328efd5f4eaa7c89cad9773124959195430a v1.5-dev8 is the first tag containing this comment, the fix should be backported to haproxy 1.5 and newer.
This commit is contained in:
parent
a331544c33
commit
7d58b4d156
@ -722,6 +722,7 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
|
||||
#ifdef USE_GETADDRINFO
|
||||
if (global.tune.options & GTUNE_USE_GAI) {
|
||||
struct addrinfo hints, *result;
|
||||
int success = 0;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
@ -733,23 +734,30 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
|
||||
if (getaddrinfo(str, NULL, &hints, &result) == 0) {
|
||||
if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
|
||||
sa->ss_family = result->ai_family;
|
||||
else if (sa->ss_family != result->ai_family)
|
||||
else if (sa->ss_family != result->ai_family) {
|
||||
freeaddrinfo(result);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch (result->ai_family) {
|
||||
case AF_INET:
|
||||
memcpy((struct sockaddr_in *)sa, result->ai_addr, result->ai_addrlen);
|
||||
set_host_port(sa, port);
|
||||
return sa;
|
||||
success = 1;
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy((struct sockaddr_in6 *)sa, result->ai_addr, result->ai_addrlen);
|
||||
set_host_port(sa, port);
|
||||
return sa;
|
||||
success = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
freeaddrinfo(result);
|
||||
|
||||
if (success)
|
||||
return sa;
|
||||
}
|
||||
#endif
|
||||
/* try to resolve an IPv4/IPv6 hostname */
|
||||
|
Loading…
x
Reference in New Issue
Block a user