aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 63ce2283a456..37c7936124e6 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1898,10 +1898,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
1898 if (tb[IFLA_IF_NETNSID]) { 1898 if (tb[IFLA_IF_NETNSID]) {
1899 netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); 1899 netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]);
1900 tgt_net = get_target_net(skb->sk, netnsid); 1900 tgt_net = get_target_net(skb->sk, netnsid);
1901 if (IS_ERR(tgt_net)) { 1901 if (IS_ERR(tgt_net))
1902 tgt_net = net; 1902 return PTR_ERR(tgt_net);
1903 netnsid = -1;
1904 }
1905 } 1903 }
1906 1904
1907 if (tb[IFLA_EXT_MASK]) 1905 if (tb[IFLA_EXT_MASK])
@@ -2837,6 +2835,12 @@ struct net_device *rtnl_create_link(struct net *net,
2837 else if (ops->get_num_rx_queues) 2835 else if (ops->get_num_rx_queues)
2838 num_rx_queues = ops->get_num_rx_queues(); 2836 num_rx_queues = ops->get_num_rx_queues();
2839 2837
2838 if (num_tx_queues < 1 || num_tx_queues > 4096)
2839 return ERR_PTR(-EINVAL);
2840
2841 if (num_rx_queues < 1 || num_rx_queues > 4096)
2842 return ERR_PTR(-EINVAL);
2843
2840 dev = alloc_netdev_mqs(ops->priv_size, ifname, name_assign_type, 2844 dev = alloc_netdev_mqs(ops->priv_size, ifname, name_assign_type,
2841 ops->setup, num_tx_queues, num_rx_queues); 2845 ops->setup, num_tx_queues, num_rx_queues);
2842 if (!dev) 2846 if (!dev)
@@ -3744,16 +3748,27 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
3744 int err = 0; 3748 int err = 0;
3745 int fidx = 0; 3749 int fidx = 0;
3746 3750
3747 err = nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, 3751 /* A hack to preserve kernel<->userspace interface.
3748 IFLA_MAX, ifla_policy, NULL); 3752 * Before Linux v4.12 this code accepted ndmsg since iproute2 v3.3.0.
3749 if (err < 0) { 3753 * However, ndmsg is shorter than ifinfomsg thus nlmsg_parse() bails.
3750 return -EINVAL; 3754 * So, check for ndmsg with an optional u32 attribute (not used here).
3751 } else if (err == 0) { 3755 * Fortunately these sizes don't conflict with the size of ifinfomsg
3752 if (tb[IFLA_MASTER]) 3756 * with an optional attribute.
3753 br_idx = nla_get_u32(tb[IFLA_MASTER]); 3757 */
3754 } 3758 if (nlmsg_len(cb->nlh) != sizeof(struct ndmsg) &&
3759 (nlmsg_len(cb->nlh) != sizeof(struct ndmsg) +
3760 nla_attr_size(sizeof(u32)))) {
3761 err = nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb,
3762 IFLA_MAX, ifla_policy, NULL);
3763 if (err < 0) {
3764 return -EINVAL;
3765 } else if (err == 0) {
3766 if (tb[IFLA_MASTER])
3767 br_idx = nla_get_u32(tb[IFLA_MASTER]);
3768 }
3755 3769
3756 brport_idx = ifm->ifi_index; 3770 brport_idx = ifm->ifi_index;
3771 }
3757 3772
3758 if (br_idx) { 3773 if (br_idx) {
3759 br_dev = __dev_get_by_index(net, br_idx); 3774 br_dev = __dev_get_by_index(net, br_idx);