Commit a7650238a0cf82d84d1d7aff4383f84807616d8f

Authored by David S. Miller

Merge branch 'bridge_nl_validation'

Thomas Graf says:

====================
bridge: Fix missing Netlink message validations

Adds various missing length checks in the bridging code for Netlink
messages and corresponding attributes provided by user space.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files Side-by-side Diff

drivers/net/ethernet/emulex/benet/be_main.c
... ... @@ -4309,10 +4309,15 @@
4309 4309 return -EOPNOTSUPP;
4310 4310  
4311 4311 br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
  4312 + if (!br_spec)
  4313 + return -EINVAL;
4312 4314  
4313 4315 nla_for_each_nested(attr, br_spec, rem) {
4314 4316 if (nla_type(attr) != IFLA_BRIDGE_MODE)
4315 4317 continue;
  4318 +
  4319 + if (nla_len(attr) < sizeof(mode))
  4320 + return -EINVAL;
4316 4321  
4317 4322 mode = nla_get_u16(attr);
4318 4323 if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
... ... @@ -7669,6 +7669,8 @@
7669 7669 return -EOPNOTSUPP;
7670 7670  
7671 7671 br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
  7672 + if (!br_spec)
  7673 + return -EINVAL;
7672 7674  
7673 7675 nla_for_each_nested(attr, br_spec, rem) {
7674 7676 __u16 mode;
... ... @@ -7676,6 +7678,9 @@
7676 7678  
7677 7679 if (nla_type(attr) != IFLA_BRIDGE_MODE)
7678 7680 continue;
  7681 +
  7682 + if (nla_len(attr) < sizeof(mode))
  7683 + return -EINVAL;
7679 7684  
7680 7685 mode = nla_get_u16(attr);
7681 7686 if (mode == BRIDGE_MODE_VEPA) {
net/bridge/br_netlink.c
... ... @@ -280,6 +280,7 @@
280 280 [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
281 281 [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
282 282 [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
  283 + [IFLA_BRPORT_FAST_LEAVE]= { .type = NLA_U8 },
283 284 [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
284 285 [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
285 286 };
net/core/rtnetlink.c
... ... @@ -2685,14 +2685,21 @@
2685 2685 int idx = 0;
2686 2686 u32 portid = NETLINK_CB(cb->skb).portid;
2687 2687 u32 seq = cb->nlh->nlmsg_seq;
2688   - struct nlattr *extfilt;
2689 2688 u32 filter_mask = 0;
2690 2689  
2691   - extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
2692   - IFLA_EXT_MASK);
2693   - if (extfilt)
2694   - filter_mask = nla_get_u32(extfilt);
  2690 + if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) {
  2691 + struct nlattr *extfilt;
2695 2692  
  2693 + extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
  2694 + IFLA_EXT_MASK);
  2695 + if (extfilt) {
  2696 + if (nla_len(extfilt) < sizeof(filter_mask))
  2697 + return -EINVAL;
  2698 +
  2699 + filter_mask = nla_get_u32(extfilt);
  2700 + }
  2701 + }
  2702 +
2696 2703 rcu_read_lock();
2697 2704 for_each_netdev_rcu(net, dev) {
2698 2705 const struct net_device_ops *ops = dev->netdev_ops;
... ... @@ -2798,6 +2805,9 @@
2798 2805 if (br_spec) {
2799 2806 nla_for_each_nested(attr, br_spec, rem) {
2800 2807 if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
  2808 + if (nla_len(attr) < sizeof(flags))
  2809 + return -EINVAL;
  2810 +
2801 2811 have_flags = true;
2802 2812 flags = nla_get_u16(attr);
2803 2813 break;
... ... @@ -2868,6 +2878,9 @@
2868 2878 if (br_spec) {
2869 2879 nla_for_each_nested(attr, br_spec, rem) {
2870 2880 if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
  2881 + if (nla_len(attr) < sizeof(flags))
  2882 + return -EINVAL;
  2883 +
2871 2884 have_flags = true;
2872 2885 flags = nla_get_u16(attr);
2873 2886 break;