Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtnetlink: require unique netns identifier

Since we've added support for IFLA_IF_NETNSID for RTM_{DEL,GET,SET,NEW}LINK
it is possible for userspace to send us requests with three different
properties to identify a target network namespace. This affects at least
RTM_{NEW,SET}LINK. Each of them could potentially refer to a different
network namespace which is confusing. For legacy reasons the kernel will
pick the IFLA_NET_NS_PID property first and then look for the
IFLA_NET_NS_FD property but there is no reason to extend this type of
behavior to network namespace ids. The regression potential is quite
minimal since the rtnetlink requests in question either won't allow
IFLA_IF_NETNSID requests before 4.16 is out (RTM_{NEW,SET}LINK) or don't
support IFLA_NET_NS_{PID,FD} (RTM_{DEL,GET}LINK) in the first place.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Acked-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Christian Brauner and committed by
David S. Miller
4ff66cae 762c330d

+48
+48
net/core/rtnetlink.c
··· 1951 1951 return net; 1952 1952 } 1953 1953 1954 + /* Verify that rtnetlink requests do not pass additional properties 1955 + * potentially referring to different network namespaces. 1956 + */ 1957 + static int rtnl_ensure_unique_netns(struct nlattr *tb[], 1958 + struct netlink_ext_ack *extack, 1959 + bool netns_id_only) 1960 + { 1961 + 1962 + if (netns_id_only) { 1963 + if (!tb[IFLA_NET_NS_PID] && !tb[IFLA_NET_NS_FD]) 1964 + return 0; 1965 + 1966 + NL_SET_ERR_MSG(extack, "specified netns attribute not supported"); 1967 + return -EOPNOTSUPP; 1968 + } 1969 + 1970 + if (tb[IFLA_IF_NETNSID] && (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD])) 1971 + goto invalid_attr; 1972 + 1973 + if (tb[IFLA_NET_NS_PID] && (tb[IFLA_IF_NETNSID] || tb[IFLA_NET_NS_FD])) 1974 + goto invalid_attr; 1975 + 1976 + if (tb[IFLA_NET_NS_FD] && (tb[IFLA_IF_NETNSID] || tb[IFLA_NET_NS_PID])) 1977 + goto invalid_attr; 1978 + 1979 + return 0; 1980 + 1981 + invalid_attr: 1982 + NL_SET_ERR_MSG(extack, "multiple netns identifying attributes specified"); 1983 + return -EINVAL; 1984 + } 1985 + 1954 1986 static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) 1955 1987 { 1956 1988 if (dev) { ··· 2585 2553 if (err < 0) 2586 2554 goto errout; 2587 2555 2556 + err = rtnl_ensure_unique_netns(tb, extack, false); 2557 + if (err < 0) 2558 + goto errout; 2559 + 2588 2560 if (tb[IFLA_IFNAME]) 2589 2561 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 2590 2562 else ··· 2682 2646 int netnsid = -1; 2683 2647 2684 2648 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack); 2649 + if (err < 0) 2650 + return err; 2651 + 2652 + err = rtnl_ensure_unique_netns(tb, extack, true); 2685 2653 if (err < 0) 2686 2654 return err; 2687 2655 ··· 2839 2799 replay: 2840 2800 #endif 2841 2801 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack); 2802 + if (err < 0) 2803 + return err; 2804 + 2805 + err = rtnl_ensure_unique_netns(tb, extack, false); 2842 2806 if (err < 0) 2843 2807 return err; 2844 2808 ··· 3086 3042 u32 ext_filter_mask = 0; 3087 3043 3088 3044 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack); 3045 + if (err < 0) 3046 + return err; 3047 + 3048 + err = rtnl_ensure_unique_netns(tb, extack, true); 3089 3049 if (err < 0) 3090 3050 return err; 3091 3051