Commit a7650238a0cf82d84d1d7aff4383f84807616d8f
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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; |