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>
This commit is contained in:
commit
a7650238a0
@ -4309,11 +4309,16 @@ static int be_ndo_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh)
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
||||||
|
if (!br_spec)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
nla_for_each_nested(attr, br_spec, rem) {
|
nla_for_each_nested(attr, br_spec, rem) {
|
||||||
if (nla_type(attr) != IFLA_BRIDGE_MODE)
|
if (nla_type(attr) != IFLA_BRIDGE_MODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (nla_len(attr) < sizeof(mode))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
mode = nla_get_u16(attr);
|
mode = nla_get_u16(attr);
|
||||||
if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
|
if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -7669,6 +7669,8 @@ static int ixgbe_ndo_bridge_setlink(struct net_device *dev,
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
||||||
|
if (!br_spec)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
nla_for_each_nested(attr, br_spec, rem) {
|
nla_for_each_nested(attr, br_spec, rem) {
|
||||||
__u16 mode;
|
__u16 mode;
|
||||||
@ -7677,6 +7679,9 @@ static int ixgbe_ndo_bridge_setlink(struct net_device *dev,
|
|||||||
if (nla_type(attr) != IFLA_BRIDGE_MODE)
|
if (nla_type(attr) != IFLA_BRIDGE_MODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (nla_len(attr) < sizeof(mode))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
mode = nla_get_u16(attr);
|
mode = nla_get_u16(attr);
|
||||||
if (mode == BRIDGE_MODE_VEPA) {
|
if (mode == BRIDGE_MODE_VEPA) {
|
||||||
reg = 0;
|
reg = 0;
|
||||||
|
@ -280,6 +280,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = {
|
|||||||
[IFLA_BRPORT_MODE] = { .type = NLA_U8 },
|
[IFLA_BRPORT_MODE] = { .type = NLA_U8 },
|
||||||
[IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
|
[IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
|
||||||
[IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
|
[IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
|
||||||
|
[IFLA_BRPORT_FAST_LEAVE]= { .type = NLA_U8 },
|
||||||
[IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
|
[IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
|
||||||
[IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
|
[IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
|
||||||
};
|
};
|
||||||
|
@ -2685,13 +2685,20 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
|
|||||||
int idx = 0;
|
int idx = 0;
|
||||||
u32 portid = NETLINK_CB(cb->skb).portid;
|
u32 portid = NETLINK_CB(cb->skb).portid;
|
||||||
u32 seq = cb->nlh->nlmsg_seq;
|
u32 seq = cb->nlh->nlmsg_seq;
|
||||||
struct nlattr *extfilt;
|
|
||||||
u32 filter_mask = 0;
|
u32 filter_mask = 0;
|
||||||
|
|
||||||
extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
|
if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) {
|
||||||
IFLA_EXT_MASK);
|
struct nlattr *extfilt;
|
||||||
if (extfilt)
|
|
||||||
filter_mask = nla_get_u32(extfilt);
|
extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
|
||||||
|
IFLA_EXT_MASK);
|
||||||
|
if (extfilt) {
|
||||||
|
if (nla_len(extfilt) < sizeof(filter_mask))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
filter_mask = nla_get_u32(extfilt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
for_each_netdev_rcu(net, dev) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
@ -2798,6 +2805,9 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||||||
if (br_spec) {
|
if (br_spec) {
|
||||||
nla_for_each_nested(attr, br_spec, rem) {
|
nla_for_each_nested(attr, br_spec, rem) {
|
||||||
if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
|
if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
|
||||||
|
if (nla_len(attr) < sizeof(flags))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
have_flags = true;
|
have_flags = true;
|
||||||
flags = nla_get_u16(attr);
|
flags = nla_get_u16(attr);
|
||||||
break;
|
break;
|
||||||
@ -2868,6 +2878,9 @@ static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||||||
if (br_spec) {
|
if (br_spec) {
|
||||||
nla_for_each_nested(attr, br_spec, rem) {
|
nla_for_each_nested(attr, br_spec, rem) {
|
||||||
if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
|
if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
|
||||||
|
if (nla_len(attr) < sizeof(flags))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
have_flags = true;
|
have_flags = true;
|
||||||
flags = nla_get_u16(attr);
|
flags = nla_get_u16(attr);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user