Commit c2dad11e authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Steffen Klassert
Browse files

xfrm: add extack to xfrm_alloc_userspi

parent bd122403
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1681,8 +1681,9 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net,
int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
void xfrm_policy_hash_rebuild(struct net *net);
u32 xfrm_get_acqseq(void);
int verify_spi_info(u8 proto, u32 min, u32 max);
int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack);
int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi,
		   struct netlink_ext_ack *extack);
struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
				 u8 mode, u32 reqid, u32 if_id, u8 proto,
				 const xfrm_address_t *daddr,
+2 −2
Original line number Diff line number Diff line
@@ -1377,13 +1377,13 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, const struct sadb_
		max_spi = range->sadb_spirange_max;
	}

	err = verify_spi_info(x->id.proto, min_spi, max_spi);
	err = verify_spi_info(x->id.proto, min_spi, max_spi, NULL);
	if (err) {
		xfrm_state_put(x);
		return err;
	}

	err = xfrm_alloc_spi(x, min_spi, max_spi);
	err = xfrm_alloc_spi(x, min_spi, max_spi, NULL);
	resp_skb = err ? ERR_PTR(err) : pfkey_xfrm_state2msg(x);

	if (IS_ERR(resp_skb)) {
+16 −5
Original line number Diff line number Diff line
@@ -2017,7 +2017,7 @@ u32 xfrm_get_acqseq(void)
}
EXPORT_SYMBOL(xfrm_get_acqseq);

int verify_spi_info(u8 proto, u32 min, u32 max)
int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack)
{
	switch (proto) {
	case IPPROTO_AH:
@@ -2026,22 +2026,28 @@ int verify_spi_info(u8 proto, u32 min, u32 max)

	case IPPROTO_COMP:
		/* IPCOMP spi is 16-bits. */
		if (max >= 0x10000)
		if (max >= 0x10000) {
			NL_SET_ERR_MSG(extack, "IPCOMP SPI must be <= 65535");
			return -EINVAL;
		}
		break;

	default:
		NL_SET_ERR_MSG(extack, "Invalid protocol, must be one of AH, ESP, IPCOMP");
		return -EINVAL;
	}

	if (min > max)
	if (min > max) {
		NL_SET_ERR_MSG(extack, "Invalid SPI range: min > max");
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL(verify_spi_info);

int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high,
		   struct netlink_ext_ack *extack)
{
	struct net *net = xs_net(x);
	unsigned int h;
@@ -2053,8 +2059,10 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
	u32 mark = x->mark.v & x->mark.m;

	spin_lock_bh(&x->lock);
	if (x->km.state == XFRM_STATE_DEAD)
	if (x->km.state == XFRM_STATE_DEAD) {
		NL_SET_ERR_MSG(extack, "Target ACQUIRE is in DEAD state");
		goto unlock;
	}

	err = 0;
	if (x->id.spi)
@@ -2065,6 +2073,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
	if (minspi == maxspi) {
		x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family);
		if (x0) {
			NL_SET_ERR_MSG(extack, "Requested SPI is already in use");
			xfrm_state_put(x0);
			goto unlock;
		}
@@ -2089,6 +2098,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
		spin_unlock_bh(&net->xfrm.xfrm_state_lock);

		err = 0;
	} else {
		NL_SET_ERR_MSG(extack, "No SPI available in the requested range");
	}

unlock:
+5 −3
Original line number Diff line number Diff line
@@ -1523,7 +1523,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
	u32 if_id = 0;

	p = nlmsg_data(nlh);
	err = verify_spi_info(p->info.id.proto, p->min, p->max);
	err = verify_spi_info(p->info.id.proto, p->min, p->max, extack);
	if (err)
		goto out_noput;

@@ -1551,10 +1551,12 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
				  &p->info.saddr, 1,
				  family);
	err = -ENOENT;
	if (!x)
	if (!x) {
		NL_SET_ERR_MSG(extack, "Target ACQUIRE not found");
		goto out_noput;
	}

	err = xfrm_alloc_spi(x, p->min, p->max);
	err = xfrm_alloc_spi(x, p->min, p->max, extack);
	if (err)
		goto out;