From 528a74a1ad25fe8524b48d0c0a8919bc0fe5cefa Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 17 Feb 2019 03:27:57 +0900 Subject: [PATCH] socket-util: re-implement socket_address_parse_netlink() by using extract_first_word() This drops support of trailing white space when a multicast group is specified. Fixes one of issues in #11738. --- src/basic/socket-util.c | 21 +++++++++++++++------ src/test/test-socket-util.c | 25 ++++++++++++++++++++----- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 91bf801cdf2..a8c9115dc20 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -235,23 +235,32 @@ int socket_address_parse_and_warn(SocketAddress *a, const char *s) { } int socket_address_parse_netlink(SocketAddress *a, const char *s) { - int family; + _cleanup_free_ char *word = NULL; unsigned group = 0; - _cleanup_free_ char *sfamily = NULL; + int family, r; + assert(a); assert(s); zero(*a); a->type = SOCK_RAW; - errno = 0; - if (sscanf(s, "%ms %u", &sfamily, &group) < 1) - return errno > 0 ? -errno : -EINVAL; + r = extract_first_word(&s, &word, NULL, 0); + if (r < 0) + return r; + if (r == 0) + return -EINVAL; - family = netlink_family_from_string(sfamily); + family = netlink_family_from_string(word); if (family < 0) return -EINVAL; + if (!isempty(s)) { + r = safe_atou(s, &group); + if (r < 0) + return r; + } + a->sockaddr.nl.nl_family = AF_NETLINK; a->sockaddr.nl.nl_groups = group; diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 07ff4878340..cd4e7848944 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -164,21 +164,36 @@ static void test_socket_address_parse_netlink(void) { assert_se(socket_address_parse_netlink(&a, "junk") < 0); assert_se(socket_address_parse_netlink(&a, "") < 0); + assert_se(socket_address_parse_netlink(&a, "route") >= 0); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 0); + assert_se(a.protocol == NETLINK_ROUTE); assert_se(socket_address_parse_netlink(&a, "route") >= 0); assert_se(socket_address_parse_netlink(&a, "route 10") >= 0); - assert_se(a.sockaddr.sa.sa_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 10); assert_se(a.protocol == NETLINK_ROUTE); /* With spaces and tabs */ assert_se(socket_address_parse_netlink(&a, " kobject-uevent ") >= 0); - assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10 \t") >= 0); - assert_se(a.sockaddr.sa.sa_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 0); + assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); + assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10") >= 0); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 10); assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); - assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10") >= 0); - assert_se(a.sockaddr.sa.sa_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 10); assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); + /* trailing space is not supported */ + assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10 ") < 0); + + /* Group must be unsigned */ + assert_se(socket_address_parse_netlink(&a, "kobject-uevent -1") < 0); + /* oss-fuzz #6884 */ assert_se(socket_address_parse_netlink(&a, "\xff") < 0); } -- 2.47.3