Skip to content

Commit f534f65

Browse files
kuba-moodavem330
authored andcommitted
net: validate veth and vxcan peer ifindexes
veth and vxcan need to make sure the ifindexes of the peer are not negative, core does not validate this. Using iproute2 with user-space-level checking removed: Before: # ./ip link add index 10 type veth peer index -1 # ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether 52:54:00:74:b2:03 brd ff:ff:ff:ff:ff:ff 10: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 8a:90:ff:57:6d:5d brd ff:ff:ff:ff:ff:ff -1: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether ae:ed:18:e6:fa:7f brd ff:ff:ff:ff:ff:ff Now: $ ./ip link add index 10 type veth peer index -1 Error: ifindex can't be negative. This problem surfaced in net-next because an explicit WARN() was added, the root cause is older. Fixes: e6f8f1a ("veth: Allow to create peer link with given ifindex") Fixes: a8f820a ("can: add Virtual CAN Tunnel driver (vxcan)") Reported-by: syzbot+5ba06978f34abb058571@syzkaller.appspotmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c727c6f commit f534f65

File tree

4 files changed

+22
-16
lines changed

4 files changed

+22
-16
lines changed

drivers/net/can/vxcan.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
192192

193193
nla_peer = data[VXCAN_INFO_PEER];
194194
ifmp = nla_data(nla_peer);
195-
err = rtnl_nla_parse_ifla(peer_tb,
196-
nla_data(nla_peer) +
197-
sizeof(struct ifinfomsg),
198-
nla_len(nla_peer) -
199-
sizeof(struct ifinfomsg),
200-
NULL);
195+
err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
201196
if (err < 0)
202197
return err;
203198

drivers/net/veth.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,10 +1861,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
18611861

18621862
nla_peer = data[VETH_INFO_PEER];
18631863
ifmp = nla_data(nla_peer);
1864-
err = rtnl_nla_parse_ifla(peer_tb,
1865-
nla_data(nla_peer) + sizeof(struct ifinfomsg),
1866-
nla_len(nla_peer) - sizeof(struct ifinfomsg),
1867-
NULL);
1864+
err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
18681865
if (err < 0)
18691866
return err;
18701867

include/net/rtnetlink.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ int rtnl_delete_link(struct net_device *dev, u32 portid, const struct nlmsghdr *
190190
int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm,
191191
u32 portid, const struct nlmsghdr *nlh);
192192

193-
int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
194-
struct netlink_ext_ack *exterr);
193+
int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer,
194+
struct netlink_ext_ack *exterr);
195195
struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid);
196196

197197
#define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)

net/core/rtnetlink.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,13 +2268,27 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
22682268
return err;
22692269
}
22702270

2271-
int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
2272-
struct netlink_ext_ack *exterr)
2271+
int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer,
2272+
struct netlink_ext_ack *exterr)
22732273
{
2274-
return nla_parse_deprecated(tb, IFLA_MAX, head, len, ifla_policy,
2274+
const struct ifinfomsg *ifmp;
2275+
const struct nlattr *attrs;
2276+
size_t len;
2277+
2278+
ifmp = nla_data(nla_peer);
2279+
attrs = nla_data(nla_peer) + sizeof(struct ifinfomsg);
2280+
len = nla_len(nla_peer) - sizeof(struct ifinfomsg);
2281+
2282+
if (ifmp->ifi_index < 0) {
2283+
NL_SET_ERR_MSG_ATTR(exterr, nla_peer,
2284+
"ifindex can't be negative");
2285+
return -EINVAL;
2286+
}
2287+
2288+
return nla_parse_deprecated(tb, IFLA_MAX, attrs, len, ifla_policy,
22752289
exterr);
22762290
}
2277-
EXPORT_SYMBOL(rtnl_nla_parse_ifla);
2291+
EXPORT_SYMBOL(rtnl_nla_parse_ifinfomsg);
22782292

22792293
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
22802294
{

0 commit comments

Comments
 (0)