During testing on win32, util/getaddrinfo failed with NULL hint info
r = evutil_getaddrinfo("www.google.com", NULL, NULL, &ai);
throwing a critical heap exception when evutil_freeaddrinfo is called.
This is because of improper use of freeaddrinfo when nodes within the
ai structure are allocated using mm_malloc or mm_calloc
(EVUTIL_AI_LIBEVENT_ALLOCATED)
This adds the flag in apply_socktype_protocol_hack and walks the linked
list in evutil_freeaddrinfo removing linked list nodes that are custom
allocated before calling freeaddrinfo.
fixes#1058
GetTempFileNameA() takes an optional prefix, and a "unique" long value
which can optionally be zero, which causes it to automatically
increment until a not-yet-existing filename is found.
When libevent creates many AF_UNIX socketpairs on windows,
it slows down dramatically, due to always using the same blank prefix,
and GetTempFileNameA() needing to iterate through all the existing
socketpair filenames. With a present and varying prefix, it will have
much less need to iterate.
It was also possible for a race with other processes also using
blank-prefix tmpfile names to result in both trying to start using
the same name at the same time (because libevent deletes the file
and then re-creates it as a unix socket), which should now be
much less likely.
Unfortuantely, "much" is just a factor of 32k, because the prefix
is only 3 characters, and windows filesystems are case-insensitive,
so doing better would require more sophisticated windows API usage
and charset trickyness.
evutil.c:2559:1: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
#0 0x4f2be0 in EVUTIL_ISXDIGIT_ libevent/evutil.c:2559:1
#1 0x4bd689 in regname_ok libevent/http.c:4838:7
#2 0x4bc16b in parse_authority libevent/http.c:4958:9
#3 0x4bb8b5 in evhttp_uri_parse_with_flags libevent/http.c:5103:7
#4 0x4bb762 in evhttp_uri_parse libevent/http.c:5050:9
#5 0x4b8f41 in evhttp_parse_query_impl libevent/http.c:3505:9
#6 0x4b8ed7 in evhttp_parse_query libevent/http.c:3569:9
Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23291
Report: https://oss-fuzz.com/testcase-detail/5670743106125824
MinGW 32-bit 5.3.0 does not defines it and our appveyour [1] build
reports this instantly:
evutil.c: In function 'evutil_make_listen_socket_ipv6only':
evutil.c:392:40: error: 'IPV6_V6ONLY' undeclared (first use in this function)
return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one,
[1]: https://www.appveyor.com/docs/windows-images-software/#mingw-msys-cygwin
Another solution will be to use mingw64 which has it, but I guess we do
want that #ifdef anyway.
According to RFC3493 and most Linux distributions, default value is to
work in IPv4-mapped mode. If there is a requirement to bind same port
on same ip addresses but different handlers for both IPv4 and IPv6,
it is required to set IPV6_V6ONLY socket option to be sure that the
code works as expected without affected by bindv6only sysctl setting
in system.
See an example working with this patch:
https://gist.github.com/demirten/023008a63cd966e48b0ebcf9af7fc113Closes: #640 (cherry-pick)
During testing on solaris 11.3, util/getaddrinfo failed at:
memset(&hints, 0, sizeof(hints));
hints.ai_flags = EVUTIL_AI_NUMERICHOST;
r = evutil_getaddrinfo("1.2.3.4", NULL, &hints, &ai);
tt_assert(ai_find_by_protocol(ai, IPPROTO_TCP));
And this is because solaris's getaddrinfo() returns:
$6 = {
ai_flags = 32,
ai_family = 2,
ai_socktype = 0,
ai_protocol = 0, <-- no proto
ai_addrlen = 16,
ai_canonname = 0x0,
ai_addr = 0x815d658,
ai_next = 0x0 <-- nothing else
}
So we should emulate this too.
Plus introduce helper that will search through all results, not only first one.
Fixes: util/getaddrinfo
Fixes: #354
@asn-the-goblin-slayer:
"Length between '[' and ']' is cast to signed 32 bit integer on line 1815. Is
the length is more than 2<<31 (INT_MAX), len will hold a negative value.
Consequently, it will pass the check at line 1816. Segfault happens at line
1819.
Generate a resolv.conf with generate-resolv.conf, then compile and run
poc.c. See entry-functions.txt for functions in tor that might be
vulnerable.
Please credit 'Guido Vranken' for this discovery through the Tor bug bounty
program."
Reproducer for gdb (https://gist.github.com/azat/be2b0d5e9417ba0dfe2c):
start
p (1ULL<<31)+1ULL
# $1 = 2147483649
p malloc(sizeof(struct sockaddr))
# $2 = (void *) 0x646010
p malloc(sizeof(int))
# $3 = (void *) 0x646030
p malloc($1)
# $4 = (void *) 0x7fff76a2a010
p memset($4, 1, $1)
# $5 = 1990369296
p (char *)$4
# $6 = 0x7fff76a2a010 '\001' <repeats 200 times>...
set $6[0]='['
set $6[$1]=']'
p evutil_parse_sockaddr_port($4, $2, $3)
# $7 = -1
Before:
$ gdb bin/http-connect < gdb
(gdb) $1 = 2147483649
(gdb) (gdb) $2 = (void *) 0x646010
(gdb) (gdb) $3 = (void *) 0x646030
(gdb) (gdb) $4 = (void *) 0x7fff76a2a010
(gdb) (gdb) $5 = 1990369296
(gdb) (gdb) $6 = 0x7fff76a2a010 '\001' <repeats 200 times>...
(gdb) (gdb) (gdb) (gdb)
Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () at memcpy-sse2-unaligned.S:36
After:
$ gdb bin/http-connect < gdb
(gdb) $1 = 2147483649
(gdb) (gdb) $2 = (void *) 0x646010
(gdb) (gdb) $3 = (void *) 0x646030
(gdb) (gdb) $4 = (void *) 0x7fff76a2a010
(gdb) (gdb) $5 = 1990369296
(gdb) (gdb) $6 = 0x7fff76a2a010 '\001' <repeats 200 times>...
(gdb) (gdb) (gdb) (gdb) $7 = -1
(gdb) (gdb) quit
Fixes: #318
This makes the code build on other systems that also don't have
SO_REUSEADDR without requiring special code.
[ azat: partially revert WIN32 check since SO_REUSEADDR on win32 differs from
unix semantics. ]
Closes#275
These types are not part of POSIX. As we only use them in a small number
of places, we'd better replace them by C standard types. This makes a
larger part of the code build for CloudABI.
* Fixed an issue with evutil_ersatz_socketpair_, listen_addr could all
be compared against with agarbage values. So just memset it before
using it anywhere.
* Nick might punch me in the face, but if we have stdint.h; (as in
EVENT__HAVE_STDINT_H is defined), might as well use those instead of
the manual [U]INT[X}_MAX/MIN muck in there now.