Commit 1a7d09a7 authored by Paolo Abeni's avatar Paolo Abeni
Browse files
Pablo Neira Ayuso says:

====================
Netfilter fixes for net

The following patchset contains Netfilter fixes for net:

1) Reset shift on Boyer-Moore string match for each block,
   from Jeremy Sowden.

2) Fix acccess to non-linear area in DCCP conntrack helper,
   from Florian Westphal.

3) Fix kernel-doc warnings, by Randy Dunlap.

4) Bail out if expires= does not show in SIP helper message,
   or make ct_sip_parse_numerical_param() tristate and report
   error if expires= cannot be parsed.

5) Unbind non-anonymous set in case rule construction fails.

6) Fix underflow in chain reference counter in case set element
   already exists or it cannot be created.

netfilter pull request 23-06-27

====================

Link: https://lore.kernel.org/r/20230627065304.66394-1-pablo@netfilter.org


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 8a9922e7 b389139f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -481,7 +481,7 @@ struct nfnl_ct_hook {
};
extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook;

/**
/*
 * nf_skb_duplicated - TEE target has sent a packet
 *
 * When a xtables target sends a packet, the OUTPUT and POSTROUTING
@@ -492,7 +492,7 @@ extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook;
 */
DECLARE_PER_CPU(bool, nf_skb_duplicated);

/**
/*
 * Contains bitmask of ctnetlink event subscribers, if any.
 * Can't be pernet due to NETLINK_LISTEN_ALL_NSID setsockopt flag.
 */
+3 −1
Original line number Diff line number Diff line
@@ -60,10 +60,12 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
	struct ts_bm *bm = ts_config_priv(conf);
	unsigned int i, text_len, consumed = state->offset;
	const u8 *text;
	int shift = bm->patlen - 1, bs;
	int bs;
	const u8 icase = conf->flags & TS_IGNORECASE;

	for (;;) {
		int shift = bm->patlen - 1;

		text_len = conf->get_next_block(consumed, &text, conf, state);

		if (unlikely(text_len == 0))
+49 −3
Original line number Diff line number Diff line
@@ -432,9 +432,19 @@ static bool dccp_error(const struct dccp_hdr *dh,
		       struct sk_buff *skb, unsigned int dataoff,
		       const struct nf_hook_state *state)
{
	static const unsigned long require_seq48 = 1 << DCCP_PKT_REQUEST |
						   1 << DCCP_PKT_RESPONSE |
						   1 << DCCP_PKT_CLOSEREQ |
						   1 << DCCP_PKT_CLOSE |
						   1 << DCCP_PKT_RESET |
						   1 << DCCP_PKT_SYNC |
						   1 << DCCP_PKT_SYNCACK;
	unsigned int dccp_len = skb->len - dataoff;
	unsigned int cscov;
	const char *msg;
	u8 type;

	BUILD_BUG_ON(DCCP_PKT_INVALID >= BITS_PER_LONG);

	if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
	    dh->dccph_doff * 4 > dccp_len) {
@@ -459,34 +469,70 @@ static bool dccp_error(const struct dccp_hdr *dh,
		goto out_invalid;
	}

	if (dh->dccph_type >= DCCP_PKT_INVALID) {
	type = dh->dccph_type;
	if (type >= DCCP_PKT_INVALID) {
		msg = "nf_ct_dccp: reserved packet type ";
		goto out_invalid;
	}

	if (test_bit(type, &require_seq48) && !dh->dccph_x) {
		msg = "nf_ct_dccp: type lacks 48bit sequence numbers";
		goto out_invalid;
	}

	return false;
out_invalid:
	nf_l4proto_log_invalid(skb, state, IPPROTO_DCCP, "%s", msg);
	return true;
}

struct nf_conntrack_dccp_buf {
	struct dccp_hdr dh;	 /* generic header part */
	struct dccp_hdr_ext ext; /* optional depending dh->dccph_x */
	union {			 /* depends on header type */
		struct dccp_hdr_ack_bits ack;
		struct dccp_hdr_request req;
		struct dccp_hdr_response response;
		struct dccp_hdr_reset rst;
	} u;
};

static struct dccp_hdr *
dccp_header_pointer(const struct sk_buff *skb, int offset, const struct dccp_hdr *dh,
		    struct nf_conntrack_dccp_buf *buf)
{
	unsigned int hdrlen = __dccp_hdr_len(dh);

	if (hdrlen > sizeof(*buf))
		return NULL;

	return skb_header_pointer(skb, offset, hdrlen, buf);
}

int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
			     unsigned int dataoff,
			     enum ip_conntrack_info ctinfo,
			     const struct nf_hook_state *state)
{
	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
	struct dccp_hdr _dh, *dh;
	struct nf_conntrack_dccp_buf _dh;
	u_int8_t type, old_state, new_state;
	enum ct_dccp_roles role;
	unsigned int *timeouts;
	struct dccp_hdr *dh;

	dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
	dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh);
	if (!dh)
		return NF_DROP;

	if (dccp_error(dh, skb, dataoff, state))
		return -NF_ACCEPT;

	/* pull again, including possible 48 bit sequences and subtype header */
	dh = dccp_header_pointer(skb, dataoff, dh, &_dh);
	if (!dh)
		return NF_DROP;

	type = dh->dccph_type;
	if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh, state))
		return -NF_ACCEPT;
+1 −1
Original line number Diff line number Diff line
@@ -611,7 +611,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
	start += strlen(name);
	*val = simple_strtoul(start, &end, 0);
	if (start == end)
		return 0;
		return -1;
	if (matchoff && matchlen) {
		*matchoff = start - dptr;
		*matchlen = end - start;
+5 −1
Original line number Diff line number Diff line
@@ -5343,6 +5343,8 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
		nft_set_trans_unbind(ctx, set);
		if (nft_set_is_anonymous(set))
			nft_deactivate_next(ctx->net, set);
		else
			list_del_rcu(&binding->list);

		set->use--;
		break;
@@ -6769,7 +6771,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
err_element_clash:
	kfree(trans);
err_elem_free:
	nft_set_elem_destroy(set, elem.priv, true);
	nf_tables_set_elem_destroy(ctx, set, elem.priv);
	if (obj)
		obj->use--;
err_parse_data:
	if (nla[NFTA_SET_ELEM_DATA] != NULL)
		nft_data_release(&elem.data.val, desc.type);