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

ipsec-next

Steffen Klassert says:

====================
pull request (net-next): ipsec-next 2021-08-27

1) Remove an unneeded extra variable in esp4 esp_ssg_unref.
   From Corey Minyard.

2) Add a configuration option to change the default behaviour
   to block traffic if there is no matching policy.
   Joint work with Christian Langrock and Antony Antony.

3) Fix a shift-out-of-bounce bug reported from syzbot.
   From Pavel Skripkin.

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

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a5504093 5d8dbb7f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -65,6 +65,13 @@ struct netns_xfrm {
	u32			sysctl_aevent_rseqth;
	int			sysctl_larval_drop;
	u32			sysctl_acq_expires;

	u8			policy_default;
#define XFRM_POL_DEFAULT_IN	1
#define XFRM_POL_DEFAULT_OUT	2
#define XFRM_POL_DEFAULT_FWD	4
#define XFRM_POL_DEFAULT_MASK	7

#ifdef CONFIG_SYSCTL
	struct ctl_table_header	*sysctl_hdr;
#endif
+30 −6
Original line number Diff line number Diff line
@@ -1075,6 +1075,22 @@ xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, un
}

#ifdef CONFIG_XFRM
static inline bool
xfrm_default_allow(struct net *net, int dir)
{
	u8 def = net->xfrm.policy_default;

	switch (dir) {
	case XFRM_POLICY_IN:
		return def & XFRM_POL_DEFAULT_IN ? false : true;
	case XFRM_POLICY_OUT:
		return def & XFRM_POL_DEFAULT_OUT ? false : true;
	case XFRM_POLICY_FWD:
		return def & XFRM_POL_DEFAULT_FWD ? false : true;
	}
	return false;
}

int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
			unsigned short family);

@@ -1088,9 +1104,13 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
	if (sk && sk->sk_policy[XFRM_POLICY_IN])
		return __xfrm_policy_check(sk, ndir, skb, family);

	if (xfrm_default_allow(net, dir))
		return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
		       (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
		       __xfrm_policy_check(sk, ndir, skb, family);
	else
		return (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
		       __xfrm_policy_check(sk, ndir, skb, family);
}

static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
@@ -1142,9 +1162,13 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
	struct net *net = dev_net(skb->dev);

	if (xfrm_default_allow(net, XFRM_POLICY_FWD))
		return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
			(skb_dst(skb)->flags & DST_NOXFRM) ||
			__xfrm_route_forward(skb, family);
	else
		return (skb_dst(skb)->flags & DST_NOXFRM) ||
			__xfrm_route_forward(skb, family);
}

static inline int xfrm4_route_forward(struct sk_buff *skb)
+11 −0
Original line number Diff line number Diff line
@@ -213,6 +213,11 @@ enum {
	XFRM_MSG_GETSPDINFO,
#define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO

	XFRM_MSG_SETDEFAULT,
#define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT
	XFRM_MSG_GETDEFAULT,
#define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT

	XFRM_MSG_MAPPING,
#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
	__XFRM_MSG_MAX
@@ -508,6 +513,12 @@ struct xfrm_user_offload {
#define XFRM_OFFLOAD_IPV6	1
#define XFRM_OFFLOAD_INBOUND	2

struct xfrm_userpolicy_default {
#define XFRM_USERPOLICY_DIRMASK_MAX	(sizeof(__u8) * 8)
	__u8				dirmask;
	__u8				action;
};

#ifndef __KERNEL__
/* backwards compatibility for userspace */
#define XFRMGRP_ACQUIRE		1
+1 −3
Original line number Diff line number Diff line
@@ -97,7 +97,6 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,

static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
{
	struct esp_output_extra *extra = esp_tmp_extra(tmp);
	struct crypto_aead *aead = x->data;
	int extralen = 0;
	u8 *iv;
@@ -105,9 +104,8 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
	struct scatterlist *sg;

	if (x->props.flags & XFRM_STATE_ESN)
		extralen += sizeof(*extra);
		extralen += sizeof(struct esp_output_extra);

	extra = esp_tmp_extra(tmp);
	iv = esp_tmp_iv(aead, tmp, extralen);
	req = esp_tmp_req(aead, iv);

+16 −0
Original line number Diff line number Diff line
@@ -3157,6 +3157,11 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
	return dst;

nopol:
	if (!(dst_orig->dev->flags & IFF_LOOPBACK) &&
	    !xfrm_default_allow(net, dir)) {
		err = -EPERM;
		goto error;
	}
	if (!(flags & XFRM_LOOKUP_ICMP)) {
		dst = dst_orig;
		goto ok;
@@ -3545,6 +3550,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
	}

	if (!pol) {
		if (!xfrm_default_allow(net, dir)) {
			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
			return 0;
		}

		if (sp && secpath_has_nontransport(sp, 0, &xerr_idx)) {
			xfrm_secpath_reject(xerr_idx, skb, &fl);
			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
@@ -3599,6 +3609,12 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
				tpp[ti++] = &pols[pi]->xfrm_vec[i];
		}
		xfrm_nr = ti;

		if (!xfrm_default_allow(net, dir) && !xfrm_nr) {
			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
			goto reject;
		}

		if (npols > 1) {
			xfrm_tmpl_sort(stp, tpp, xfrm_nr, family);
			tpp = stp;
Loading