diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/rtnetlink.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e170179cc66f..2bd9c5f7627d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -722,6 +722,21 @@ static struct net *get_net_ns_by_pid(pid_t pid) | |||
722 | return net; | 722 | return net; |
723 | } | 723 | } |
724 | 724 | ||
725 | static 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 | |||
725 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 740 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, |
726 | struct nlattr **tb, char *ifname, int modified) | 741 | struct nlattr **tb, char *ifname, int modified) |
727 | { | 742 | { |
@@ -894,12 +909,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
894 | goto errout; | 909 | goto errout; |
895 | } | 910 | } |
896 | 911 | ||
897 | if (tb[IFLA_ADDRESS] && | 912 | if ((err = validate_linkmsg(dev, tb)) < 0) |
898 | nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) | ||
899 | goto errout_dev; | ||
900 | |||
901 | if (tb[IFLA_BROADCAST] && | ||
902 | nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) | ||
903 | goto errout_dev; | 913 | goto errout_dev; |
904 | 914 | ||
905 | err = do_setlink(dev, ifm, tb, ifname, 0); | 915 | err = do_setlink(dev, ifm, tb, ifname, 0); |
@@ -1020,6 +1030,9 @@ replay: | |||
1020 | else | 1030 | else |
1021 | dev = NULL; | 1031 | dev = NULL; |
1022 | 1032 | ||
1033 | if ((err = validate_linkmsg(dev, tb)) < 0) | ||
1034 | return err; | ||
1035 | |||
1023 | if (tb[IFLA_LINKINFO]) { | 1036 | if (tb[IFLA_LINKINFO]) { |
1024 | err = nla_parse_nested(linkinfo, IFLA_INFO_MAX, | 1037 | err = nla_parse_nested(linkinfo, IFLA_INFO_MAX, |
1025 | tb[IFLA_LINKINFO], ifla_info_policy); | 1038 | tb[IFLA_LINKINFO], ifla_info_policy); |