From a28aa6e24f4d12bdf0532f2108348bc588f797ed Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Mon, 23 Jan 2023 15:03:26 -0800 Subject: [PATCH] gh-100795: Don't call freeaddrinfo on failure. (GH-101252) 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 Co-authored-by: Sergey G. Brester Co-authored-by: Oleg Iarygin --- .../Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst | 3 +++ Modules/socketmodule.c | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst diff --git a/Misc/NEWS.d/next/Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst b/Misc/NEWS.d/next/Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst new file mode 100644 index 00000000000000..4cb56ea0f0e58d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst @@ -0,0 +1,3 @@ +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. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 6a9ac2ceb734e8..0762a8df8663d2 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1053,6 +1053,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int 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; } @@ -1163,6 +1164,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int #endif Py_END_ALLOW_THREADS if (error) { + res = NULL; // no-op, remind us that it is invalid; gh-100795 set_gaierror(error); return -1; } @@ -6514,6 +6516,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) error = getaddrinfo(hptr, pptr, &hints, &res0); Py_END_ALLOW_THREADS if (error) { + res0 = NULL; // gh-100795 set_gaierror(error); goto err; } @@ -6608,6 +6611,7 @@ socket_getnameinfo(PyObject *self, PyObject *args) error = getaddrinfo(hostp, pbuf, &hints, &res); Py_END_ALLOW_THREADS if (error) { + res = NULL; // gh-100795 set_gaierror(error); goto fail; }