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


Steffen Klassert says:

====================
pull request (net): ipsec 2022-05-18

1) Fix "disable_policy" flag use when arriving from different devices.
   From Eyal Birger.

2) Fix error handling of pfkey_broadcast in function pfkey_process.
   From Jiasheng Jiang.

3) Check the encryption module availability consistency in pfkey.
   From Thomas Bartschies.

Please pull or let me know if there are problems.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 765d1216 015c44d7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct inet_skb_parm {
#define IPSKB_DOREDIRECT	BIT(5)
#define IPSKB_FRAG_PMTU		BIT(6)
#define IPSKB_L3SLAVE		BIT(7)
#define IPSKB_NOPOLICY		BIT(8)

	u16			frag_max_size;
};
+13 −1
Original line number Diff line number Diff line
@@ -1093,6 +1093,18 @@ static inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
	return false;
}

static inline bool __xfrm_check_dev_nopolicy(struct sk_buff *skb,
					     int dir, unsigned short family)
{
	if (dir != XFRM_POLICY_OUT && family == AF_INET) {
		/* same dst may be used for traffic originating from
		 * devices with different policy settings.
		 */
		return IPCB(skb)->flags & IPSKB_NOPOLICY;
	}
	return skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY);
}

static inline int __xfrm_policy_check2(struct sock *sk, int dir,
				       struct sk_buff *skb,
				       unsigned int family, int reverse)
@@ -1104,7 +1116,7 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
		return __xfrm_policy_check(sk, ndir, skb, family);

	return __xfrm_check_nopolicy(net, skb, dir) ||
	       (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
	       __xfrm_check_dev_nopolicy(skb, dir, family) ||
	       __xfrm_policy_check(sk, ndir, skb, family);
}

+18 −5
Original line number Diff line number Diff line
@@ -1726,6 +1726,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
	struct in_device *in_dev = __in_dev_get_rcu(dev);
	unsigned int flags = RTCF_MULTICAST;
	struct rtable *rth;
	bool no_policy;
	u32 itag = 0;
	int err;

@@ -1736,8 +1737,12 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
	if (our)
		flags |= RTCF_LOCAL;

	no_policy = IN_DEV_ORCONF(in_dev, NOPOLICY);
	if (no_policy)
		IPCB(skb)->flags |= IPSKB_NOPOLICY;

	rth = rt_dst_alloc(dev_net(dev)->loopback_dev, flags, RTN_MULTICAST,
			   IN_DEV_ORCONF(in_dev, NOPOLICY), false);
			   no_policy, false);
	if (!rth)
		return -ENOBUFS;

@@ -1796,7 +1801,7 @@ static int __mkroute_input(struct sk_buff *skb,
	struct rtable *rth;
	int err;
	struct in_device *out_dev;
	bool do_cache;
	bool do_cache, no_policy;
	u32 itag = 0;

	/* get a working reference to the output device */
@@ -1841,6 +1846,10 @@ static int __mkroute_input(struct sk_buff *skb,
		}
	}

	no_policy = IN_DEV_ORCONF(in_dev, NOPOLICY);
	if (no_policy)
		IPCB(skb)->flags |= IPSKB_NOPOLICY;

	fnhe = find_exception(nhc, daddr);
	if (do_cache) {
		if (fnhe)
@@ -1853,8 +1862,7 @@ static int __mkroute_input(struct sk_buff *skb,
		}
	}

	rth = rt_dst_alloc(out_dev->dev, 0, res->type,
			   IN_DEV_ORCONF(in_dev, NOPOLICY),
	rth = rt_dst_alloc(out_dev->dev, 0, res->type, no_policy,
			   IN_DEV_ORCONF(out_dev, NOXFRM));
	if (!rth) {
		err = -ENOBUFS;
@@ -2229,6 +2237,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
	struct rtable	*rth;
	struct flowi4	fl4;
	bool do_cache = true;
	bool no_policy;

	/* IP on this device is disabled. */

@@ -2347,6 +2356,10 @@ out: return err;
	RT_CACHE_STAT_INC(in_brd);

local_input:
	no_policy = IN_DEV_ORCONF(in_dev, NOPOLICY);
	if (no_policy)
		IPCB(skb)->flags |= IPSKB_NOPOLICY;

	do_cache &= res->fi && !itag;
	if (do_cache) {
		struct fib_nh_common *nhc = FIB_RES_NHC(*res);
@@ -2361,7 +2374,7 @@ out: return err;

	rth = rt_dst_alloc(ip_rt_get_dev(net, res),
			   flags | RTCF_LOCAL, res->type,
			   IN_DEV_ORCONF(in_dev, NOPOLICY), false);
			   no_policy, false);
	if (!rth)
		goto e_nobufs;

+7 −5
Original line number Diff line number Diff line
@@ -2826,8 +2826,10 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, const struct sadb
	void *ext_hdrs[SADB_EXT_MAX];
	int err;

	pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,
	err = pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,
			      BROADCAST_PROMISC_ONLY, NULL, sock_net(sk));
	if (err)
		return err;

	memset(ext_hdrs, 0, sizeof(ext_hdrs));
	err = parse_exthdrs(skb, hdr, ext_hdrs);
@@ -2898,7 +2900,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
			break;
		if (!aalg->pfkey_supported)
			continue;
		if (aalg_tmpl_set(t, aalg))
		if (aalg_tmpl_set(t, aalg) && aalg->available)
			sz += sizeof(struct sadb_comb);
	}
	return sz + sizeof(struct sadb_prop);
@@ -2916,7 +2918,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
		if (!ealg->pfkey_supported)
			continue;

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

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

			if (aalg_tmpl_set(t, aalg))
			if (aalg_tmpl_set(t, aalg) && aalg->available)
				sz += sizeof(struct sadb_comb);
		}
	}