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

Commit d809ec89 authored by Timo Teräs's avatar Timo Teräs Committed by David S. Miller
Browse files

xfrm: do not assume that template resolving always returns xfrms



xfrm_resolve_and_create_bundle() assumed that, if policies indicated
presence of xfrms, bundle template resolution would always return
some xfrms. This is not true for 'use' level policies which can
result in no xfrm's being applied if there is no suitable xfrm states.
This fixes a crash by this incorrect assumption.

Reported-by: default avatarGeorge Spelvin <linux@horizon.com>
Bisected-by: default avatarGeorge Spelvin <linux@horizon.com>
Tested-by: default avatarGeorge Spelvin <linux@horizon.com>
Signed-off-by: default avatarTimo Teräs <timo.teras@iki.fi>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ab83a389
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,

	/* Try to instantiate a bundle */
	err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
	if (err < 0) {
		if (err != -EAGAIN)
	if (err <= 0) {
		if (err != 0 && err != -EAGAIN)
			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
		return ERR_PTR(err);
	}
@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir,
			goto make_dummy_bundle;
		dst_hold(&xdst->u.dst);
		return oldflo;
	} else if (new_xdst == NULL) {
		num_xfrms = 0;
		if (oldflo == NULL)
			goto make_dummy_bundle;
		xdst->num_xfrms = 0;
		dst_hold(&xdst->u.dst);
		return oldflo;
	}

	/* Kill the previous bundle */
@@ -1760,6 +1767,10 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl,
				xfrm_pols_put(pols, num_pols);
				err = PTR_ERR(xdst);
				goto dropdst;
			} else if (xdst == NULL) {
				num_xfrms = 0;
				drop_pols = num_pols;
				goto no_transform;
			}

			spin_lock_bh(&xfrm_policy_sk_bundle_lock);