Bug report
When using empty address for unix socket on Linux, the socket is bound to a random
address in the abstract namespace.
from unix(7):
Autobind feature
If a bind(2) call specifies addrlen as sizeof(sa_family_t), or the
SO_PASSCRED socket option was specified for a socket that was not ex‐
plicitly bound to an address, then the socket is autobound to an ab‐
stract address. The address consists of a null byte followed by 5
bytes in the character set [0-9a-f]. Thus, there is a limit of 2^20
autobind addresses. (From Linux 2.1.15, when the autobind feature was
added, 8 bytes were used, and the limit was thus 2^32 autobind ad‐
dresses. The change to 5 bytes came in Linux 2.3.15.)
Since python 3.9, when using empty socket address (""), bind() is called with
with path.len + offsetof(struct sockaddr_un, sun_path) + 1, so the socket is
bound to the specific address "\0" instead of a random address (e.g. "\075499").
This breaks code assuming that multiple sockets can be bound to a random address
at the same time.
In python 3.8 (not including this change):
$ python3.8
Python 3.8.13 (default, Jun 10 2022, 00:00:00)
[GCC 12.1.1 20220507 (Red Hat 12.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
>>> s.bind("")
>>> s.getsockname()
b'\x0075499'
With python 3.9 (including this change):
$ python3.9
Python 3.9.13 (main, Jun 9 2022, 00:00:00)
[GCC 12.1.1 20220507 (Red Hat 12.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
>>> s.bind("")
>>> s.getsockname()
b'\x00'
Your environment
- CPython versions tested on: python 3.9, python 3.10
- Operating system and architecture: Fedora 36, Ubuntu latest (GitHub actions)
The breaking change is f6b3a07, backported
to python 3.9. I suspect that change was not needed since it did not include
any test showing a real issue, but it is possible to fix handling of empty
unix socket address without reverting this change.
Bug report
When using empty address for unix socket on Linux, the socket is bound to a random
address in the abstract namespace.
from unix(7):
Since python 3.9, when using empty socket address (""), bind() is called with
with
path.len + offsetof(struct sockaddr_un, sun_path) + 1, so the socket isbound to the specific address "\0" instead of a random address (e.g. "\075499").
This breaks code assuming that multiple sockets can be bound to a random address
at the same time.
In python 3.8 (not including this change):
With python 3.9 (including this change):
Your environment
The breaking change is f6b3a07, backported
to python 3.9. I suspect that change was not needed since it did not include
any test showing a real issue, but it is possible to fix handling of empty
unix socket address without reverting this change.