From: Zbigniew Jędrzejewski-Szmek Date: Thu, 3 Sep 2020 08:05:12 +0000 (+0200) Subject: shared/socket-netlink: only allow ifindex if explicitly supported X-Git-Tag: v247-rc1~261^2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=25b2d602b91a5b9225e3f7c72d77e51face237ad;p=thirdparty%2Fsystemd.git shared/socket-netlink: only allow ifindex if explicitly supported Instead of ignoring ifindex if not wanted, refuse it is the caller does not allow it. --- diff --git a/src/shared/socket-netlink.c b/src/shared/socket-netlink.c index 6c121a4c9aa..4b52fa3097c 100644 --- a/src/shared/socket-netlink.c +++ b/src/shared/socket-netlink.c @@ -345,10 +345,14 @@ int in_addr_port_ifindex_name_from_string_auto( /* This accepts the following: * 192.168.0.1:53#example.com - * [2001:4860:4860::8888]:53%eth0#example.com */ - - /* if ret_port is NULL, then strings with port cannot be specified. - * Also, if ret_server_name is NULL, then server_name cannot be specified. */ + * [2001:4860:4860::8888]:53%eth0#example.com + * + * If ret_port is NULL, then the port cannot be specified. + * If ret_ifindex is NULL, then the interface index cannot be specified. + * If ret_server_name is NULL, then server_name cannot be specified. + * + * ret_family is always AF_INET or AF_INET6. + */ m = strchr(s, '#'); if (m) { @@ -369,15 +373,15 @@ int in_addr_port_ifindex_name_from_string_auto( m = strchr(s, '%'); if (m) { + if (!ret_ifindex) + return -EINVAL; + if (isempty(m + 1)) return -EINVAL; - if (ret_ifindex) { - /* If we shall return the interface index, try to parse it */ - ifindex = resolve_interface(NULL, m + 1); - if (ifindex < 0) - return ifindex; - } + ifindex = resolve_interface(NULL, m + 1); + if (ifindex < 0) + return ifindex; s = buf2 = strndup(s, m - s); if (!buf2) diff --git a/src/test/test-socket-netlink.c b/src/test/test-socket-netlink.c index f03e455d0ee..200af19a456 100644 --- a/src/test/test-socket-netlink.c +++ b/src/test/test-socket-netlink.c @@ -293,18 +293,59 @@ static void test_in_addr_ifindex_name_from_string_auto(void) { } static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str, int family, uint16_t port, int ifindex, const char *server_name) { - _cleanup_free_ char *name = NULL, *x = NULL; union in_addr_union a; uint16_t p; int f, i; + char *fake; - assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, &name) >= 0); - assert_se(family == f); - assert_se(port == p); - assert_se(ifindex == i); - assert_se(streq_ptr(server_name, name)); - assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, i, name, &x) >= 0); - assert_se(streq(str, x)); + log_info("%s: %s", __func__, str); + + { + _cleanup_free_ char *name = NULL, *x = NULL; + assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, &name) == 0); + assert_se(family == f); + assert_se(port == p); + assert_se(ifindex == i); + assert_se(streq_ptr(server_name, name)); + assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, i, name, &x) >= 0); + assert_se(streq(str, x)); + } + + if (port > 0) + assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, NULL, &i, &fake) == -EINVAL); + else { + _cleanup_free_ char *name = NULL, *x = NULL; + assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, NULL, &i, &name) == 0); + assert_se(family == f); + assert_se(ifindex == i); + assert_se(streq_ptr(server_name, name)); + assert_se(in_addr_port_ifindex_name_to_string(f, &a, 0, i, name, &x) >= 0); + assert_se(streq(str, x)); + } + + if (ifindex > 0) + assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, NULL, &fake) == -EINVAL); + else { + _cleanup_free_ char *name = NULL, *x = NULL; + assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, NULL, &name) == 0); + assert_se(family == f); + assert_se(port == p); + assert_se(streq_ptr(server_name, name)); + assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, 0, name, &x) >= 0); + assert_se(streq(str, x)); + } + + if (server_name) + assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, NULL) == -EINVAL); + else { + _cleanup_free_ char *x = NULL; + assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, NULL) == 0); + assert_se(family == f); + assert_se(port == p); + assert_se(ifindex == i); + assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, i, NULL, &x) >= 0); + assert_se(streq(str, x)); + } } static void test_in_addr_port_ifindex_name_from_string_auto(void) {