Commit 35c715c3 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Steffen Klassert says:

====================
pull request (net): ipsec 2021-01-21

1) Fix a rare panic on SMP systems when packet reordering
   happens between anti replay check and update.
   From Shmulik Ladkani.

2) Fix disable_xfrm sysctl when used on xfrm interfaces.
   From Eyal Birger.

3) Fix a race in PF_KEY when the availability of crypto
   algorithms is set. From Cong Wang.

4) Fix a return value override in the xfrm policy selftests.
   From Po-Hsu Lin.

5) Fix an integer wraparound in xfrm_policy_addr_delta.
   From Visa Hankala.

* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec:
  xfrm: Fix wraparound in xfrm_policy_addr_delta()
  selftests: xfrm: fix test return value override issue in xfrm_policy.sh
  af_key: relax availability checks for skb size calculation
  xfrm: fix disable_xfrm sysctl when used on xfrm interfaces
  xfrm: Fix oops in xfrm_replay_advance_bmp
====================

Link: https://lore.kernel.org/r/20210121121558.621339-1-steffen.klassert@secunet.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1c45ba93 da64ae2d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -2902,7 +2902,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
			break;
		if (!aalg->pfkey_supported)
			continue;
		if (aalg_tmpl_set(t, aalg) && aalg->available)
		if (aalg_tmpl_set(t, aalg))
			sz += sizeof(struct sadb_comb);
	}
	return sz + sizeof(struct sadb_prop);
@@ -2920,7 +2920,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
		if (!ealg->pfkey_supported)
			continue;

		if (!(ealg_tmpl_set(t, ealg) && ealg->available))
		if (!(ealg_tmpl_set(t, ealg)))
			continue;

		for (k = 1; ; k++) {
@@ -2931,7 +2931,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
			if (!aalg->pfkey_supported)
				continue;

			if (aalg_tmpl_set(t, aalg) && aalg->available)
			if (aalg_tmpl_set(t, aalg))
				sz += sizeof(struct sadb_comb);
		}
	}
+1 −1
Original line number Diff line number Diff line
@@ -660,7 +660,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
		/* only the first xfrm gets the encap type */
		encap_type = 0;

		if (async && x->repl->recheck(x, skb, seq)) {
		if (x->repl->recheck(x, skb, seq)) {
			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
			goto drop_unlock;
		}
+20 −10
Original line number Diff line number Diff line
@@ -793,15 +793,22 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a,
				  const xfrm_address_t *b,
				  u8 prefixlen, u16 family)
{
	u32 ma, mb, mask;
	unsigned int pdw, pbi;
	int delta = 0;

	switch (family) {
	case AF_INET:
		if (sizeof(long) == 4 && prefixlen == 0)
			return ntohl(a->a4) - ntohl(b->a4);
		return (ntohl(a->a4) & ((~0UL << (32 - prefixlen)))) -
		       (ntohl(b->a4) & ((~0UL << (32 - prefixlen))));
		if (prefixlen == 0)
			return 0;
		mask = ~0U << (32 - prefixlen);
		ma = ntohl(a->a4) & mask;
		mb = ntohl(b->a4) & mask;
		if (ma < mb)
			delta = -1;
		else if (ma > mb)
			delta = 1;
		break;
	case AF_INET6:
		pdw = prefixlen >> 5;
		pbi = prefixlen & 0x1f;
@@ -812,10 +819,13 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a,
				return delta;
		}
		if (pbi) {
			u32 mask = ~0u << (32 - pbi);

			delta = (ntohl(a->a6[pdw]) & mask) -
				(ntohl(b->a6[pdw]) & mask);
			mask = ~0U << (32 - pbi);
			ma = ntohl(a->a6[pdw]) & mask;
			mb = ntohl(b->a6[pdw]) & mask;
			if (ma < mb)
				delta = -1;
			else if (ma > mb)
				delta = 1;
		}
		break;
	default:
@@ -3078,8 +3088,8 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
		xflo.flags = flags;

		/* To accelerate a bit...  */
		if ((dst_orig->flags & DST_NOXFRM) ||
		    !net->xfrm.policy_count[XFRM_POLICY_OUT])
		if (!if_id && ((dst_orig->flags & DST_NOXFRM) ||
			       !net->xfrm.policy_count[XFRM_POLICY_OUT]))
			goto nopol;

		xdst = xfrm_bundle_lookup(net, fl, family, dir, &xflo, if_id);
+44 −1
Original line number Diff line number Diff line
@@ -202,7 +202,7 @@ check_xfrm() {
	# 1: iptables -m policy rule count != 0
	rval=$1
	ip=$2
	lret=0
	local lret=0

	ip netns exec ns1 ping -q -c 1 10.0.2.$ip > /dev/null

@@ -287,6 +287,47 @@ check_hthresh_repeat()
	return 0
}

# insert non-overlapping policies in a random order and check that
# all of them can be fetched using the traffic selectors.
check_random_order()
{
	local ns=$1
	local log=$2

	for i in $(seq 100); do
		ip -net $ns xfrm policy flush
		for j in $(seq 0 16 255 | sort -R); do
			ip -net $ns xfrm policy add dst $j.0.0.0/24 dir out priority 10 action allow
		done
		for j in $(seq 0 16 255); do
			if ! ip -net $ns xfrm policy get dst $j.0.0.0/24 dir out > /dev/null; then
				echo "FAIL: $log" 1>&2
				return 1
			fi
		done
	done

	for i in $(seq 100); do
		ip -net $ns xfrm policy flush
		for j in $(seq 0 16 255 | sort -R); do
			local addr=$(printf "e000:0000:%02x00::/56" $j)
			ip -net $ns xfrm policy add dst $addr dir out priority 10 action allow
		done
		for j in $(seq 0 16 255); do
			local addr=$(printf "e000:0000:%02x00::/56" $j)
			if ! ip -net $ns xfrm policy get dst $addr dir out > /dev/null; then
				echo "FAIL: $log" 1>&2
				return 1
			fi
		done
	done

	ip -net $ns xfrm policy flush

	echo "PASS: $log"
	return 0
}

#check for needed privileges
if [ "$(id -u)" -ne 0 ];then
	echo "SKIP: Need root privileges"
@@ -438,6 +479,8 @@ check_exceptions "exceptions and block policies after htresh change to normal"

check_hthresh_repeat "policies with repeated htresh change"

check_random_order ns3 "policies inserted in random order"

for i in 1 2 3 4;do ip netns del ns$i;done

exit $ret