When getaddrinfo returns an error, the output pointer is in an unknown state
Don't call freeaddrinfo on it. See the issue for discussion and details with
links to reasoning. _Most_ libc getaddrinfo implementations never modify the
output pointer unless they are returning success.
(cherry picked from commit
b724ac2fe7fbb5a7a33d639cad8e748f17b325e0)
Co-authored-by: Gregory P. Smith <greg@krypto.org>
Co-authored-by: Sergey G. Brester <github@sebres.de>
Co-authored-by: Oleg Iarygin <dralife@yandex.ru>
--- /dev/null
+Avoid potential unexpected ``freeaddrinfo`` call (double free) in :mod:`socket`
+when when a libc ``getaddrinfo()`` implementation leaves garbage in an output
+pointer when returning an error. Original patch by Sergey G. Brester.
subsequent call to getaddrinfo() does not destroy the
outcome of the first call. */
if (error) {
+ res = NULL; // no-op, remind us that it is invalid; gh-100795
set_gaierror(error);
return -1;
}
#endif
Py_END_ALLOW_THREADS
if (error) {
+ res = NULL; // no-op, remind us that it is invalid; gh-100795
set_gaierror(error);
return -1;
}
error = getaddrinfo(hptr, pptr, &hints, &res0);
Py_END_ALLOW_THREADS
if (error) {
+ res0 = NULL; // gh-100795
set_gaierror(error);
goto err;
}
error = getaddrinfo(hostp, pbuf, &hints, &res);
Py_END_ALLOW_THREADS
if (error) {
+ res = NULL; // gh-100795
set_gaierror(error);
goto fail;
}