]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/socket-netlink: only allow ifindex if explicitly supported
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 3 Sep 2020 08:05:12 +0000 (10:05 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 9 Sep 2020 22:46:44 +0000 (00:46 +0200)
Instead of ignoring ifindex if not wanted, refuse it is the caller
does not allow it.

src/shared/socket-netlink.c
src/test/test-socket-netlink.c

index 6c121a4c9aa059f0228a4708f64c13439a25af28..4b52fa3097c20624aa8ba64fa67dcacb540f1b12 100644 (file)
@@ -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)
index f03e455d0ee8c3c4c109fcad74b70234013d3774..200af19a456bc9f15ea186e1c94cfa487d8fcbe9 100644 (file)
@@ -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) {