Issue 25541: Wrong usage of sockaddr_un struct for abstract namespace unix sockets (original) (raw)

Created on 2015-11-03 11:08 by soutys, last changed 2022-04-11 14:58 by admin.

Messages (8)
msg253981 - (view) Author: PrzemeK (soutys) Date: 2015-11-03 11:15
Case: http://stackoverflow.com/questions/33465094/connection-refused-when-using-abstract-namespace-unix-sockets The code that does not work (python3 example): ... sock_path = b"/var/tmp/sock.tmp" server.bind(b"\0" + sock_path) ... and strace shows: connect(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 20) = -1 ECONNREFUSED (Connection refused) For C-written client strace shows: connect(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 110) = 0 The code that actually works (python3 example): ... sun_path_len = 108 sock_path = b"/var/tmp/sock.tmp" server.bind(b"\0" + sock_path + (b"\0" * (sun_path_len - len(sock_path) - 1))) ... and strace shows: bind(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 110) = 0 110 it's the correst size of a struct. There's no hint at https://docs.python.org/3/library/socket.html#socket-families for that. Test files (servers and clients): https://gist.github.com/soutys/ffbe2e76a86835a9cc6b
msg253982 - (view) Author: PrzemeK (soutys) Date: 2015-11-03 11:23
Errata - 1st paragraph should be: The code that does not work (python3 example): ... sock_path = b"/var/tmp/sock.tmp" server.bind(b"\0" + sock_path) ... and strace shows: bind(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"...}, 20) = 0
msg341637 - (view) Author: anthony shaw (anthonypjshaw) * (Python triager) Date: 2019-05-06 20:15
hi, which version of Python were you using to do this? Please could you provide the full code snippet to reproduce the issue. The following example binds to the correct namespace from socket import * sock = socket(AF_UNIX, SOCK_STREAM) sock.bind("\0/var/tmp/sock.tmp")
msg341641 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2019-05-06 20:32
Looks like the issue was originally reported against Python 3.4.
msg341686 - (view) Author: PrzemeK (soutys) Date: 2019-05-07 06:49
Yep, it was 3.4 then... but I think problem still exists tl;dr: For abstract sockets (only?) filling struct with zeros is meaningful. long: * Python (cli) -> Python (srv) = works * C (cli) -> C (srv) = works * C (cli) -> Python (srv) = does NOT work * Python (cli) -> C (srv) = does NOT work (strace dumps below) $ gcc --version gcc (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0 $ uname -a Linux ajzus 4.15.0-48-generic #51-Ubuntu SMP Wed Apr 3 08:28:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux $ python3.7 --version Python 3.7.1 // 1st console $ gcc -g -Wall -Wextra -pedantic -o abs_srv abs_srv.c $ strace ./abs_srv ... socket(AF_UNIX, SOCK_STREAM, 0) = 3 bind(3, {sa_family=AF_UNIX, sun_path=@"/var/tmp/sock.tmp\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, 110) = 0 listen(3, 5) = 0 accept(3, NULL, NULL // waiting // 2nd console $ ls /var/tmp/*.sock ls: cannot access '/var/tmp/*.sock': No such file or directory $ strace python3.7 abs_cli.py ... socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 3 connect(3, {sa_family=AF_UNIX, sun_path=@"/var/tmp/sock.tmp"}, 20) = -1 ECONNREFUSED (Connection refused)
msg341688 - (view) Author: PrzemeK (soutys) Date: 2019-05-07 06:59
Gist: https://gist.github.com/soutys/ffbe2e76a86835a9cc6b More: Padding `sun_path` with zeros for python cli code: ... client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) client.connect("\0/var/tmp/sock.tmp" + "\0" * 90) ... gives strace like: ... socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 3 connect(3, {sa_family=AF_UNIX, sun_path=@"/var/tmp/sock.tmp\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, 110) = 0 write(1, "Ready.\n", 7Ready. ) = 7 ... = works
msg341971 - (view) Author: anthony shaw (anthonypjshaw) * (Python triager) Date: 2019-05-09 07:49
thanks, your code example zero-pads the socket address, and looking at the socketmodule.c code it does some padding under certain circumstances. https://github.com/python/cpython/blob/master/Modules/socketmodule.c#L1318-L1330 The Unix man page specify the same requirement you've noticed: When binding a socket to a pathname, a few rules should be observed for maximum portability and ease of coding: * The pathname in sun_path should be null-terminated. * The length of the pathname, including the terminating null byte, should not exceed the size of sun_path. * The addrlen argument that describes the enclosing sockaddr_un structure should have a value of at least: offsetof(struct sockaddr_un, sun_path)+strlen(addr.sun_path)+1 or, more simply, addrlen can be specified as sizeof(struct sock‐ addr_un).
msg341972 - (view) Author: anthony shaw (anthonypjshaw) * (Python triager) Date: 2019-05-09 08:04
The existing tests in place add the null-termination bytes in the test string: def testLinuxAbstractNamespace(self): address = b"\x00python-test-hello\x00\xff" with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s1: s1.bind(address) s1.listen() with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s2: s2.connect(s1.getsockname()) with s1.accept()[0] as s3: self.assertEqual(s1.getsockname(), address) self.assertEqual(s2.getpeername(), address) So that answers your initial question, it does work, but you have to add the null termination bytes in the address string. This isn't documented, so the documentation needs fixing.
History
Date User Action Args
2022-04-11 14:58:23 admin set github: 69727
2019-05-09 08:04:48 anthonypjshaw set versions: + Python 3.8, - Python 2.7, Python 3.4, Python 3.7
2019-05-09 08:04:33 anthonypjshaw set messages: +
2019-05-09 07:49:58 anthonypjshaw set messages: +
2019-05-07 06:59:38 soutys set messages: +
2019-05-07 06:49:15 soutys set messages: + versions: + Python 3.7
2019-05-06 20:33:14 scoder set nosy: - scoder
2019-05-06 20:32:36 scoder set nosy:pitrou, scoder, soutys, anthonypjshawmessages: +
2019-05-06 20:15:06 anthonypjshaw set nosy: + anthonypjshaw, scodermessages: +
2015-11-06 23:46:00 terry.reedy set nosy: + pitrou
2015-11-03 11:23:44 soutys set messages: +
2015-11-03 11:15:21 soutys set messages: +
2015-11-03 11:08:21 soutys create