Skip to content

Commit 1a7d09a

Browse files
author
Paolo Abeni
committed
Merge tag 'nf-23-06-27' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
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: Paolo Abeni <pabeni@redhat.com>
2 parents 8a9922e + b389139 commit 1a7d09a

5 files changed

Lines changed: 60 additions & 8 deletions

File tree

include/linux/netfilter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ struct nfnl_ct_hook {
481481
};
482482
extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook;
483483

484-
/**
484+
/*
485485
* nf_skb_duplicated - TEE target has sent a packet
486486
*
487487
* 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;
492492
*/
493493
DECLARE_PER_CPU(bool, nf_skb_duplicated);
494494

495-
/**
495+
/*
496496
* Contains bitmask of ctnetlink event subscribers, if any.
497497
* Can't be pernet due to NETLINK_LISTEN_ALL_NSID setsockopt flag.
498498
*/

lib/ts_bm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
6060
struct ts_bm *bm = ts_config_priv(conf);
6161
unsigned int i, text_len, consumed = state->offset;
6262
const u8 *text;
63-
int shift = bm->patlen - 1, bs;
63+
int bs;
6464
const u8 icase = conf->flags & TS_IGNORECASE;
6565

6666
for (;;) {
67+
int shift = bm->patlen - 1;
68+
6769
text_len = conf->get_next_block(consumed, &text, conf, state);
6870

6971
if (unlikely(text_len == 0))

net/netfilter/nf_conntrack_proto_dccp.c

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,19 @@ static bool dccp_error(const struct dccp_hdr *dh,
432432
struct sk_buff *skb, unsigned int dataoff,
433433
const struct nf_hook_state *state)
434434
{
435+
static const unsigned long require_seq48 = 1 << DCCP_PKT_REQUEST |
436+
1 << DCCP_PKT_RESPONSE |
437+
1 << DCCP_PKT_CLOSEREQ |
438+
1 << DCCP_PKT_CLOSE |
439+
1 << DCCP_PKT_RESET |
440+
1 << DCCP_PKT_SYNC |
441+
1 << DCCP_PKT_SYNCACK;
435442
unsigned int dccp_len = skb->len - dataoff;
436443
unsigned int cscov;
437444
const char *msg;
445+
u8 type;
446+
447+
BUILD_BUG_ON(DCCP_PKT_INVALID >= BITS_PER_LONG);
438448

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

462-
if (dh->dccph_type >= DCCP_PKT_INVALID) {
472+
type = dh->dccph_type;
473+
if (type >= DCCP_PKT_INVALID) {
463474
msg = "nf_ct_dccp: reserved packet type ";
464475
goto out_invalid;
465476
}
477+
478+
if (test_bit(type, &require_seq48) && !dh->dccph_x) {
479+
msg = "nf_ct_dccp: type lacks 48bit sequence numbers";
480+
goto out_invalid;
481+
}
482+
466483
return false;
467484
out_invalid:
468485
nf_l4proto_log_invalid(skb, state, IPPROTO_DCCP, "%s", msg);
469486
return true;
470487
}
471488

489+
struct nf_conntrack_dccp_buf {
490+
struct dccp_hdr dh; /* generic header part */
491+
struct dccp_hdr_ext ext; /* optional depending dh->dccph_x */
492+
union { /* depends on header type */
493+
struct dccp_hdr_ack_bits ack;
494+
struct dccp_hdr_request req;
495+
struct dccp_hdr_response response;
496+
struct dccp_hdr_reset rst;
497+
} u;
498+
};
499+
500+
static struct dccp_hdr *
501+
dccp_header_pointer(const struct sk_buff *skb, int offset, const struct dccp_hdr *dh,
502+
struct nf_conntrack_dccp_buf *buf)
503+
{
504+
unsigned int hdrlen = __dccp_hdr_len(dh);
505+
506+
if (hdrlen > sizeof(*buf))
507+
return NULL;
508+
509+
return skb_header_pointer(skb, offset, hdrlen, buf);
510+
}
511+
472512
int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
473513
unsigned int dataoff,
474514
enum ip_conntrack_info ctinfo,
475515
const struct nf_hook_state *state)
476516
{
477517
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
478-
struct dccp_hdr _dh, *dh;
518+
struct nf_conntrack_dccp_buf _dh;
479519
u_int8_t type, old_state, new_state;
480520
enum ct_dccp_roles role;
481521
unsigned int *timeouts;
522+
struct dccp_hdr *dh;
482523

483-
dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
524+
dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh);
484525
if (!dh)
485526
return NF_DROP;
486527

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

531+
/* pull again, including possible 48 bit sequences and subtype header */
532+
dh = dccp_header_pointer(skb, dataoff, dh, &_dh);
533+
if (!dh)
534+
return NF_DROP;
535+
490536
type = dh->dccph_type;
491537
if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh, state))
492538
return -NF_ACCEPT;

net/netfilter/nf_conntrack_sip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
611611
start += strlen(name);
612612
*val = simple_strtoul(start, &end, 0);
613613
if (start == end)
614-
return 0;
614+
return -1;
615615
if (matchoff && matchlen) {
616616
*matchoff = start - dptr;
617617
*matchlen = end - start;

net/netfilter/nf_tables_api.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5343,6 +5343,8 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
53435343
nft_set_trans_unbind(ctx, set);
53445344
if (nft_set_is_anonymous(set))
53455345
nft_deactivate_next(ctx->net, set);
5346+
else
5347+
list_del_rcu(&binding->list);
53465348

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

0 commit comments

Comments
 (0)