Skip to content

Autobind of empty unix socket on Linux broken since python 3.9#94821

@nirs

Description

@nirs

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.10only security fixes3.11only security fixes3.12only security fixes3.9 (EOL)end of lifetype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions