}
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;
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);
}