From a6f73f61147048187908299ae911c5ad498d813a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:47:26 +0100 Subject: [PATCH] [3.9] bpo-37013: Fix the error handling in socket.if_indextoname() (GH-13503) (GH-112600) * Fix a crash when pass UINT_MAX. * Fix an integer overflow on 64-bit non-Windows platforms. (cherry picked from commit 0daf555c6fb3feba77989382135a58215e1d70a5) Co-authored-by: Zackery Spytz --- Lib/test/test_socket.py | 13 ++++++++++ ...3-12-01-16-09-59.gh-issue-81194.FFad1c.rst | 3 +++ Modules/socketmodule.c | 24 ++++++++++++------- 3 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 127d61cb6a8..043e5543889 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1070,7 +1070,20 @@ def testInterfaceNameIndex(self): 'socket.if_indextoname() not available.') def testInvalidInterfaceIndexToName(self): self.assertRaises(OSError, socket.if_indextoname, 0) + self.assertRaises(OverflowError, socket.if_indextoname, -1) + self.assertRaises(OverflowError, socket.if_indextoname, 2**1000) self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF') + if hasattr(socket, 'if_nameindex'): + indices = dict(socket.if_nameindex()) + for index in indices: + index2 = index + 2**32 + if index2 not in indices: + with self.assertRaises((OverflowError, OSError)): + socket.if_indextoname(index2) + for index in 2**32-1, 2**64-1: + if index not in indices: + with self.assertRaises((OverflowError, OSError)): + socket.if_indextoname(index) @unittest.skipUnless(hasattr(socket, 'if_nametoindex'), 'socket.if_nametoindex() not available.') diff --git a/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst new file mode 100644 index 00000000000..feb7a8643b9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst @@ -0,0 +1,3 @@ +Fix a crash in :func:`socket.if_indextoname` with specific value (UINT_MAX). +Fix an integer overflow in :func:`socket.if_indextoname` on 64-bit +non-Windows platforms. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 133470f9b81..9e0223b1272 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -6890,17 +6890,23 @@ Returns the interface index corresponding to the interface name if_name."); static PyObject * socket_if_indextoname(PyObject *self, PyObject *arg) { -#ifdef MS_WINDOWS - NET_IFINDEX index; -#else - unsigned long index; -#endif - char name[IF_NAMESIZE + 1]; - - index = PyLong_AsUnsignedLong(arg); - if (index == (unsigned long) -1) + unsigned long index_long = PyLong_AsUnsignedLong(arg); + if (index_long == (unsigned long) -1 && PyErr_Occurred()) { return NULL; + } +#ifdef MS_WINDOWS + NET_IFINDEX index = (NET_IFINDEX)index_long; +#else + unsigned int index = (unsigned int)index_long; +#endif + + if ((unsigned long)index != index_long) { + PyErr_SetString(PyExc_OverflowError, "index is too large"); + return NULL; + } + + char name[IF_NAMESIZE + 1]; if (if_indextoname(index, name) == NULL) { PyErr_SetFromErrno(PyExc_OSError); return NULL;