Skip to content

Commit 4ff66ca

Browse files
Christian Braunerdavem330
authored andcommitted
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 <[email protected]> Acked-by: Jiri Benc <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 762c330 commit 4ff66ca

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

net/core/rtnetlink.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,6 +1951,38 @@ static struct net *rtnl_link_get_net_capable(const struct sk_buff *skb,
19511951
return net;
19521952
}
19531953

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+
19541986
static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
19551987
{
19561988
if (dev) {
@@ -2553,6 +2585,10 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
25532585
if (err < 0)
25542586
goto errout;
25552587

2588+
err = rtnl_ensure_unique_netns(tb, extack, false);
2589+
if (err < 0)
2590+
goto errout;
2591+
25562592
if (tb[IFLA_IFNAME])
25572593
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
25582594
else
@@ -2649,6 +2685,10 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
26492685
if (err < 0)
26502686
return err;
26512687

2688+
err = rtnl_ensure_unique_netns(tb, extack, true);
2689+
if (err < 0)
2690+
return err;
2691+
26522692
if (tb[IFLA_IFNAME])
26532693
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
26542694

@@ -2802,6 +2842,10 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
28022842
if (err < 0)
28032843
return err;
28042844

2845+
err = rtnl_ensure_unique_netns(tb, extack, false);
2846+
if (err < 0)
2847+
return err;
2848+
28052849
if (tb[IFLA_IFNAME])
28062850
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
28072851
else
@@ -3045,6 +3089,10 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
30453089
if (err < 0)
30463090
return err;
30473091

3092+
err = rtnl_ensure_unique_netns(tb, extack, true);
3093+
if (err < 0)
3094+
return err;
3095+
30483096
if (tb[IFLA_IF_NETNSID]) {
30493097
netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]);
30503098
tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid);

0 commit comments

Comments
 (0)