[Python-checkins] gh-94821: Fix autobind of empty unix domain address (GH-94826) (GH-94875)
ambv
webhook-mailer at python.org
Tue Jul 26 06:07:53 EDT 2022
https://github.com/python/cpython/commit/cd0a59f1fa32fc1e4730c52c761f4d0190833587
commit: cd0a59f1fa32fc1e4730c52c761f4d0190833587
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: ambv <lukasz at langa.pl>
date: 2022-07-26T12:07:41+02:00
summary:
gh-94821: Fix autobind of empty unix domain address (GH-94826) (GH-94875)
When binding a unix socket to an empty address on Linux, the socket is
automatically bound to an available address in the abstract namespace.
>>> s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
>>> s.bind("")
>>> s.getsockname()
b'\x0075499'
Since python 3.9, the socket is bound to the one address:
>>> s.getsockname()
b'\x00'
And trying to bind multiple sockets will fail with:
Traceback (most recent call last):
File "/home/nsoffer/src/cpython/Lib/test/test_socket.py", line 5553, in testAutobind
s2.bind("")
OSError: [Errno 98] Address already in use
Added 2 tests:
- Auto binding empty address on Linux
- Failing to bind an empty address on other platforms
Fixes f6b3a07b7df6 (bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866)
(cherry picked from commit c22f134211743cd5ad14cec1dd4f527bee542b4c)
Co-authored-by: Nir Soffer <nsoffer at redhat.com>
files:
A Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst
M Lib/test/test_socket.py
M Modules/socketmodule.c
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 5712b46f7f111..127d61cb6a89e 100755
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -5417,6 +5417,20 @@ def testBytearrayName(self):
s.bind(bytearray(b"\x00python\x00test\x00"))
self.assertEqual(s.getsockname(), b"\x00python\x00test\x00")
+ def testAutobind(self):
+ # Check that binding to an empty string binds to an available address
+ # in the abstract namespace as specified in unix(7) "Autobind feature".
+ abstract_address = b"^\0[0-9a-f]{5}"
+ with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s1:
+ s1.bind("")
+ self.assertRegex(s1.getsockname(), abstract_address)
+ # Each socket is bound to a different abstract address.
+ with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s2:
+ s2.bind("")
+ self.assertRegex(s2.getsockname(), abstract_address)
+ self.assertNotEqual(s1.getsockname(), s2.getsockname())
+
+
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'test needs socket.AF_UNIX')
class TestUnixDomain(unittest.TestCase):
@@ -5486,6 +5500,11 @@ def testUnencodableAddr(self):
self.addCleanup(support.unlink, path)
self.assertEqual(self.sock.getsockname(), path)
+ @unittest.skipIf(sys.platform == 'linux', 'Linux specific test')
+ def testEmptyAddress(self):
+ # Test that binding empty address fails.
+ self.assertRaises(OSError, self.sock.bind, "")
+
class BufferIOTest(SocketConnectedTest):
"""
diff --git a/Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst b/Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst
new file mode 100644
index 0000000000000..bf7885aef8cbf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst
@@ -0,0 +1,2 @@
+Fix binding of unix socket to empty address on Linux to use an available
+address from the abstract namespace, instead of "\0".
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 6d6c92e4c95d1..133470f9b8193 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1715,8 +1715,10 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
struct sockaddr_un* addr = &addrbuf->un;
#ifdef __linux__
- if (path.len > 0 && *(const char *)path.buf == 0) {
- /* Linux abstract namespace extension */
+ if (path.len == 0 || *(const char *)path.buf == 0) {
+ /* Linux abstract namespace extension:
+ - Empty address auto-binding to an abstract address
+ - Address that starts with null byte */
if ((size_t)path.len > sizeof addr->sun_path) {
PyErr_SetString(PyExc_OSError,
"AF_UNIX path too long");
More information about the Python-checkins
mailing list