bridge: Fix missing Netlink message validations
Subsystems (5)
cover 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.
Thomas Graf (5):
bridge: Validate IFLA_BRIDGE_FLAGS attribute length
net: Validate IFLA_BRIDGE_MODE attribute length
net: Check for presence of IFLA_AF_SPEC
bridge: Add missing policy entry for IFLA_BRPORT_FAST_LEAVE
bridge: Sanitize IFLA_EXT_MASK for AF_BRIDGE:RTM_GETLINK
drivers/net/ethernet/emulex/benet/be_main.c | 5 +++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 5 +++++ net/bridge/br_netlink.c | 1 + net/core/rtnetlink.c | 23 ++++++++++++++++++----- 4 files changed, 29 insertions(+), 5 deletions(-)
Signature · 1 line
1.9.3
PATCH 1/5 bridge: Validate IFLA_BRIDGE_FLAGS attribute length
Payload is currently accessed blindly and may exceed valid message boundaries.
--- net/core/rtnetlink.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/core/rtnetlink.c +6 -0
@@ -2798,6 +2798,9 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)if (br_spec) {nla_for_each_nested (attr, br_spec, rem) {if (nla_type (attr) ==IFLA_BRIDGE_FLAGS ) { +if (nla_len (attr) <sizeof (flags)) +return -EINVAL ; + have_flags = true; flags =nla_get_u16 (attr);break ;
@@ -2868,6 +2871,9 @@ static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)if (br_spec) {nla_for_each_nested (attr, br_spec, rem) {if (nla_type (attr) ==IFLA_BRIDGE_FLAGS ) { +if (nla_len (attr) <sizeof (flags)) +return -EINVAL ; + have_flags = true; flags =nla_get_u16 (attr);break ;
Signature · 1 line
1.9.3
PATCH 2/5 net: Validate IFLA_BRIDGE_MODE attribute length
In reply to Thomas GrafPayload is currently accessed blindly and may exceed valid message boundaries.
--- drivers/net/ethernet/emulex/benet/be_main.c | 3 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +++ 2 files changed, 6 insertions(+)
drivers/net/ethernet/emulex/benet/be_main.c +3 -0
@@ -4314,6 +4314,9 @@ static int be_ndo_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh)if (nla_type (attr) !=IFLA_BRIDGE_MODE )continue ; +if (nla_len (attr) <sizeof (mode)) +return -EINVAL ; + mode =nla_get_u16 (attr);if (mode !=BRIDGE_MODE_VEPA && mode !=BRIDGE_MODE_VEB )return -EINVAL ;
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +3 -0
@@ -7677,6 +7677,9 @@ static int ixgbe_ndo_bridge_setlink(struct net_device *dev,if (nla_type (attr) !=IFLA_BRIDGE_MODE )continue ; +if (nla_len (attr) <sizeof (mode)) +return -EINVAL ; + mode =nla_get_u16 (attr);if (mode ==BRIDGE_MODE_VEPA ) { reg =0 ;
Signature · 1 line
1.9.3
Re: [PATCH 2/5] net: Validate IFLA_BRIDGE_MODE attribute length
Quoted 8 lines · Thomas Graf
Payload is currently accessed blindly and may exceed valid message boundaries.
Fixes a77dcb8c8 ("be2net: set and query VEB/VEPA mode of the PF interface")Fixes 815cccbf1 ("ixgbe: add setlink, getlink support to ixgbe and ixgbevf")Cc Ajit Khaparde <[email protected]>Cc John Fastabend <[email protected]>Signed-off-by Thomas Graf <[email protected]>
Quoted 5 lines
--- drivers/net/ethernet/emulex/benet/be_main.c | 3 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +++ 2 files changed, 6 insertions(+)
Re: [PATCH 2/5] net: Validate IFLA_BRIDGE_MODE attribute length
In reply to Thomas GrafQuoted 8 lines · Thomas Graf
Payload is currently accessed blindly and may exceed valid message boundaries.
Fixes a77dcb8c8 ("be2net: set and query VEB/VEPA mode of the PF interface")Fixes 815cccbf1 ("ixgbe: add setlink, getlink support to ixgbe and ixgbevf")Cc Ajit Khaparde <[email protected]>Cc John Fastabend <[email protected]>Signed-off-by Thomas Graf <[email protected]>
Quoted 5 lines
--- drivers/net/ethernet/emulex/benet/be_main.c | 3 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +++ 2 files changed, 6 insertions(+)
Thanks Thomas.
Signature · 1 line
John Fastabend Intel Corporation
PATCH 3/5 net: Check for presence of IFLA_AF_SPEC
In reply to Thomas Grafndo_bridge_setlink() is currently only called on the slave if IFLA_AF_SPEC is set but this is a very fragile assumption and may change in the future.
--- drivers/net/ethernet/emulex/benet/be_main.c | 2 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 ++ 2 files changed, 4 insertions(+)
drivers/net/ethernet/emulex/benet/be_main.c +2 -0
@@ -4309,6 +4309,8 @@ static int be_ndo_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh)return -EOPNOTSUPP ; 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) {if (nla_type (attr) !=IFLA_BRIDGE_MODE )
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +2 -0
@@ -7669,6 +7669,8 @@ static int ixgbe_ndo_bridge_setlink(struct net_device *dev,return -EOPNOTSUPP ; 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) {__u16 mode;
Signature · 1 line
1.9.3
Re: [PATCH 3/5] net: Check for presence of IFLA_AF_SPEC
Quoted 4 lines · Thomas Graf
ndo_bridge_setlink()is currently only called on the slave ifIFLA_AF_SPECis set but this is a very fragile assumption and may change in the future.
Quoted 8 lines
Cc Ajit Khaparde <[email protected]>Cc John Fastabend <[email protected]>Signed-off-by Thomas Graf <[email protected]>--- drivers/net/ethernet/emulex/benet/be_main.c | 2 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 ++ 2 files changed, 4 insertions(+)
PATCH 4/5 bridge: Add missing policy entry for IFLA_BRPORT_FAST_LEAVE
In reply to Thomas Graf--- net/bridge/br_netlink.c | 1 + 1 file changed, 1 insertion(+)
net/bridge/br_netlink.c +1 -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_GUARD] = { .type = NLA_U8 }, [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, + [IFLA_BRPORT_FAST_LEAVE]= { .type = NLA_U8 }, [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, };
Signature · 1 line
1.9.3
PATCH 5/5 bridge: Sanitize IFLA_EXT_MASK for AF_BRIDGE:RTM_GETLINK
In reply to Thomas GrafOnly search for IFLA_EXT_MASK if the message actually carries a ifinfomsg header and validate minimal length requirements for IFLA_EXT_MASK.
--- net/core/rtnetlink.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
net/core/rtnetlink.c +12 -5
@@ -2685,13 +2685,20 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)int idx =0 ;u32 portid =NETLINK_CB (cb->skb).portid;u32 seq = cb->nlh->nlmsg_seq; -struct nlattr *extfilt;u32 filter_mask =0 ; - extfilt =nlmsg_find_attr (cb->nlh,sizeof (struct ifinfomsg ), -IFLA_EXT_MASK ); -if (extfilt) - filter_mask =nla_get_u32 (extfilt); +if (nlmsg_len (cb->nlh) >sizeof (struct ifinfomsg )) { +struct nlattr *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 ();for_each_netdev_rcu (net, dev) {
Signature · 1 line
1.9.3
Quoted 10 lines · Thomas Graf
Adds various missing length checks in the bridging code for Netlink messages and corresponding attributes provided by user space.
Thomas Graf (5):
bridge: ValidateIFLA_BRIDGE_FLAGSattribute length
net: ValidateIFLA_BRIDGE_MODEattribute length
net: Check for presence ofIFLA_AF_SPEC
bridge: Add missing policy entry forIFLA_BRPORT_FAST_LEAVE
bridge: SanitizeIFLA_EXT_MASKfor AF_BRIDGE:RTM_GETLINK
Quoted 6 lines
drivers/net/ethernet/emulex/benet/be_main.c | 5 +++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 5 +++++ net/bridge/br_netlink.c | 1 + net/core/rtnetlink.c | 23 ++++++++++++++++++----- 4 files changed, 29 insertions(+), 5 deletions(-)
+Jiri
Looks like a miss in bond_netlink also? Seems like writing a smatch or cocci check for this would be worthwhile.
Quoted 19 lines
drivers/net/bonding/bond_netlink.c +6
-1@@ -225,7 +225,12 @@ static int bond_changelink(struct net_device *bond_dev,bond_option_arp_ip_targets_clear (bond);nla_for_each_nested (attr, data[IFLA_BOND_ARP_IP_TARGET ], rem) { -__be32 target =nla_get_be32 (attr); +__be32 target; + +if (nla_len (attr) <sizeof (target)) +return -EINVAL ; + + target =nla_get_be32 (attr);bond_opt_initval (&newval, (__force u64 )target); err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS,
Signature · 1 line
John Fastabend Intel Corporation
Quoted 18 lines · John Fastabend
Quoted 10 lines · Thomas Graf
Adds various missing length checks in the bridging code for Netlink messages and corresponding attributes provided by user space.
Thomas Graf (5):
bridge: ValidateIFLA_BRIDGE_FLAGSattribute length
net: ValidateIFLA_BRIDGE_MODEattribute length
net: Check for presence ofIFLA_AF_SPEC
bridge: Add missing policy entry forIFLA_BRPORT_FAST_LEAVE
bridge: SanitizeIFLA_EXT_MASKfor AF_BRIDGE:RTM_GETLINKQuoted 6 lines
drivers/net/ethernet/emulex/benet/be_main.c | 5 +++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 5 +++++ net/bridge/br_netlink.c | 1 + net/core/rtnetlink.c | 23 ++++++++++++++++++----- 4 files changed, 29 insertions(+), 5 deletions(-)
Quoted 4 lines
+Jiri
Looks like a miss in
bond_netlinkalso? Seems like writing a smatch or cocci check for this would be worthwhile.
Thanks, I'll take a look.
The cocci check is somewhat difficult as validation is often centralized and decoupled from actual access to implement atomic operations. I'll give it a try though.
Quoted 21 lines · Thomas Graf
Quoted 20 lines · John Fastabend
Quoted 10 lines · Thomas Graf
Adds various missing length checks in the bridging code for Netlink messages and corresponding attributes provided by user space.
Thomas Graf (5):
bridge: ValidateIFLA_BRIDGE_FLAGSattribute length
net: ValidateIFLA_BRIDGE_MODEattribute length
net: Check for presence ofIFLA_AF_SPEC
bridge: Add missing policy entry forIFLA_BRPORT_FAST_LEAVE
bridge: SanitizeIFLA_EXT_MASKfor AF_BRIDGE:RTM_GETLINKQuoted 6 lines
drivers/net/ethernet/emulex/benet/be_main.c | 5 +++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 5 +++++ net/bridge/br_netlink.c | 1 + net/core/rtnetlink.c | 23 ++++++++++++++++++----- 4 files changed, 29 insertions(+), 5 deletions(-)+Jiri
Quoted 9 lines
Quoted 2 lines
Looks like a miss in
bond_netlinkalso? Seems like writing a smatch or cocci check for this would be worthwhile.Thanks, I'll take a look.
The cocci check is somewhat difficult as validation is often centralized and decoupled from actual access to implement atomic operations. I'll give it a try though.
Sounds good, if I get some time I could give it a try as well.
Also another missing one here or at least I'm not seeing it if its there,
Quoted 13 lines
net/ipv4/devinet.c +4
-1@@ -1687,8 +1687,11 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)BUG ();if (tb[IFLA_INET_CONF ]) { -nla_for_each_nested (a, tb[IFLA_INET_CONF ], rem) +nla_for_each_nested (a, tb[IFLA_INET_CONF ], rem) { +if (nla_len (a) <sizeof (u32)) +return -EINVAL ;ipv4_devconf_set (in_dev,nla_type (a),nla_get_u32 (a)); + } }
Signature · 1 line
John Fastabend Intel Corporation
Quoted 5 lines · John Fastabend
Quoted 5 lines
net/ipv4/devinet.c +0
-0@@ -1687,8 +1687,11 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)BUG ();
Quoted 7 lines
net/ipv4/devinet.c static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla) · line 1694
Quoted 7 lines
net/ipv4/devinet.c +4
-1if (tb[IFLA_INET_CONF ]) { -nla_for_each_nested (a, tb[IFLA_INET_CONF ], rem) +nla_for_each_nested (a, tb[IFLA_INET_CONF ], rem) { +if (nla_len (a) <sizeof (u32)) +return -EINVAL ;ipv4_devconf_set (in_dev,nla_type (a),nla_get_u32 (a)); + }
Looked into this and found a validation function inet_validate_link_af(). It's split to keep the updates atomic.
Quoted 6 lines · Thomas Graf
Quoted 5 lines · John Fastabend
Quoted 5 lines
net/ipv4/devinet.c +0
-0@@ -1687,8 +1687,11 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)BUG ();
Quoted 11 lines
Quoted 7 lines
net/ipv4/devinet.c static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla) · line 1694
Quoted 7 lines
net/ipv4/devinet.c +4
-1if (tb[IFLA_INET_CONF ]) { -nla_for_each_nested (a, tb[IFLA_INET_CONF ], rem) +nla_for_each_nested (a, tb[IFLA_INET_CONF ], rem) { +if (nla_len (a) <sizeof (u32)) +return -EINVAL ;ipv4_devconf_set (in_dev,nla_type (a),nla_get_u32 (a)); + }Looked into this and found a validation function
inet_validate_link_af(). It's split to keep the updates atomic.
Ah great thanks.
Signature · 1 line
John Fastabend Intel Corporation
David Miller
maintainerFrom: Thomas Graf <[email protected]>
Date: Wed, 26 Nov 2014 13:42:15 +0100
Quoted 2 lines
Adds various missing length checks in the bridging code for Netlink messages and corresponding attributes provided by user space.
Series applied, thanks Thomas.