From 08224f38acdf5e391dda43e4e004e4ddc5c00302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 9 Sep 2020 23:49:51 +0200 Subject: [PATCH] Use sockaddr_un_set_path() in socket_address_parse() Two functional changes: - "/" is now refused. The test is adjusted. - The trailing NUL is *not* included in the returned size for abstract size. The comments in sockaddr_un_set_path() indicate that this is the right thing to do, and the code in socket_address_parse() wasn't doing that. --- src/shared/socket-netlink.c | 33 +++++++-------------------------- src/test/test-socket-netlink.c | 2 +- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/shared/socket-netlink.c b/src/shared/socket-netlink.c index 76b68dfa1c..23970dbe55 100644 --- a/src/shared/socket-netlink.c +++ b/src/shared/socket-netlink.c @@ -62,37 +62,18 @@ int socket_address_parse(SocketAddress *a, const char *s) { assert(a); assert(s); - if (*s == '/') { + if (IN_SET(*s, '/', '@')) { /* AF_UNIX socket */ + struct sockaddr_un un; - size_t l = strlen(s); - if (l >= sizeof(a->sockaddr.un.sun_path)) /* Note that we refuse non-NUL-terminated sockets when - * parsing (the kernel itself is less strict here in what it - * accepts) */ - return -EINVAL; + r = sockaddr_un_set_path(&un, s); + if (r < 0) + return r; *a = (SocketAddress) { - .sockaddr.un.sun_family = AF_UNIX, - .size = offsetof(struct sockaddr_un, sun_path) + l + 1, + .sockaddr.un = un, + .size = r, }; - memcpy(a->sockaddr.un.sun_path, s, l); - - } else if (*s == '@') { - /* Abstract AF_UNIX socket */ - - size_t l = strlen(s+1); - if (l >= sizeof(a->sockaddr.un.sun_path) - 1) /* Note that we refuse non-NUL-terminated sockets here - * when parsing, even though abstract namespace sockets - * explicitly allow embedded NUL bytes and don't consider - * them special. But it's simply annoying to debug such - * sockets. */ - return -EINVAL; - - *a = (SocketAddress) { - .sockaddr.un.sun_family = AF_UNIX, - .size = offsetof(struct sockaddr_un, sun_path) + 1 + l, - }; - memcpy(a->sockaddr.un.sun_path+1, s+1, l); } else if (startswith(s, "vsock:")) { /* AF_VSOCK socket in vsock:cid:port notation */ diff --git a/src/test/test-socket-netlink.c b/src/test/test-socket-netlink.c index ac191851fa..afb7038621 100644 --- a/src/test/test-socket-netlink.c +++ b/src/test/test-socket-netlink.c @@ -76,7 +76,7 @@ static void test_socket_address_parse(void) { test_socket_address_parse_one("[::1]:1234%xxxxasdf", -ENODEV, 0, NULL); test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL); test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL); - test_socket_address_parse_one("/", 0, AF_UNIX, NULL); + test_socket_address_parse_one("/", -EINVAL, 0, NULL); test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL); {