Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7650238 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 571dcfde aa68c20f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4309,11 +4309,16 @@ 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)
			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;
+5 −0
Original line number Diff line number Diff line
@@ -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;
@@ -7677,6 +7679,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;
+1 −0
Original line number Diff line number Diff line
@@ -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 },
};
+18 −5
Original line number Diff line number Diff line
@@ -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;

	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 (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) {
@@ -2798,6 +2805,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 +2878,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;