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.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 61ac8d06292c..2bd9c5f7627d 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -689,10 +689,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
689 [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN }, 689 [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
690 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, 690 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
691 [IFLA_MTU] = { .type = NLA_U32 }, 691 [IFLA_MTU] = { .type = NLA_U32 },
692 [IFLA_LINK] = { .type = NLA_U32 },
692 [IFLA_TXQLEN] = { .type = NLA_U32 }, 693 [IFLA_TXQLEN] = { .type = NLA_U32 },
693 [IFLA_WEIGHT] = { .type = NLA_U32 }, 694 [IFLA_WEIGHT] = { .type = NLA_U32 },
694 [IFLA_OPERSTATE] = { .type = NLA_U8 }, 695 [IFLA_OPERSTATE] = { .type = NLA_U8 },
695 [IFLA_LINKMODE] = { .type = NLA_U8 }, 696 [IFLA_LINKMODE] = { .type = NLA_U8 },
697 [IFLA_LINKINFO] = { .type = NLA_NESTED },
696 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 698 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
697}; 699};
698 700
@@ -720,6 +722,21 @@ static struct net *get_net_ns_by_pid(pid_t pid)
720 return net; 722 return net;
721} 723}
722 724
725static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
726{
727 if (dev) {
728 if (tb[IFLA_ADDRESS] &&
729 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
730 return -EINVAL;
731
732 if (tb[IFLA_BROADCAST] &&
733 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
734 return -EINVAL;
735 }
736
737 return 0;
738}
739
723static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, 740static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
724 struct nlattr **tb, char *ifname, int modified) 741 struct nlattr **tb, char *ifname, int modified)
725{ 742{
@@ -892,12 +909,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
892 goto errout; 909 goto errout;
893 } 910 }
894 911
895 if (tb[IFLA_ADDRESS] && 912 if ((err = validate_linkmsg(dev, tb)) < 0)
896 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
897 goto errout_dev;
898
899 if (tb[IFLA_BROADCAST] &&
900 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
901 goto errout_dev; 913 goto errout_dev;
902 914
903 err = do_setlink(dev, ifm, tb, ifname, 0); 915 err = do_setlink(dev, ifm, tb, ifname, 0);
@@ -1018,6 +1030,9 @@ replay:
1018 else 1030 else
1019 dev = NULL; 1031 dev = NULL;
1020 1032
1033 if ((err = validate_linkmsg(dev, tb)) < 0)
1034 return err;
1035
1021 if (tb[IFLA_LINKINFO]) { 1036 if (tb[IFLA_LINKINFO]) {
1022 err = nla_parse_nested(linkinfo, IFLA_INFO_MAX, 1037 err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
1023 tb[IFLA_LINKINFO], ifla_info_policy); 1038 tb[IFLA_LINKINFO], ifla_info_policy);