Skip to content

Commit 24c7a64

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net 1) Fix crash with malformed ebtables blob which do not provide all entry points, from Florian Westphal. 2) Fix possible TCP connection clogging up with default 5-days timeout in conntrack, from Florian. 3) Fix crash in nf_tables tproxy with unsupported chains, also from Florian. 4) Do not allow to update implicit chains. 5) Make table handle allocation per-netns to fix data race. 6) Do not truncated payload length and offset, and checksum offset. Instead report EINVAl. 7) Enable chain stats update via static key iff no error occurs. 8) Restrict osf expression to ip, ip6 and inet families. 9) Restrict tunnel expression to netdev family. 10) Fix crash when trying to bind again an already bound chain. 11) Flowtable garbage collector might leave behind pending work to delete entries. This patch comes with a previous preparation patch as dependency. 12) Allow net.netfilter.nf_conntrack_frag6_high_thresh to be lowered, from Eric Dumazet. * git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_defrag_ipv6: allow nf_conntrack_frag6_high_thresh increases netfilter: flowtable: fix stuck flows on cleanup due to pending work netfilter: flowtable: add function to invoke garbage collection immediately netfilter: nf_tables: disallow binding to already bound chain netfilter: nft_tunnel: restrict it to netdev family netfilter: nft_osf: restrict osf to ipv4, ipv6 and inet families netfilter: nf_tables: do not leave chain stats enabled on error netfilter: nft_payload: do not truncate csum_offset and csum_type netfilter: nft_payload: report ERANGE for too long offset and length netfilter: nf_tables: make table handle allocation per-netns friendly netfilter: nf_tables: disallow updates of implicit chain netfilter: nft_tproxy: restrict to prerouting hook netfilter: conntrack: work around exceeded receive window netfilter: ebtables: reject blobs that don't provide all entry points ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents b09da01 + 00cd7bf commit 24c7a64

File tree

16 files changed

+109
-56
lines changed

16 files changed

+109
-56
lines changed

include/linux/netfilter_bridge/ebtables.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,6 @@ struct ebt_table {
9494
struct ebt_replace_kernel *table;
9595
unsigned int valid_hooks;
9696
rwlock_t lock;
97-
/* e.g. could be the table explicitly only allows certain
98-
* matches, targets, ... 0 == let it in */
99-
int (*check)(const struct ebt_table_info *info,
100-
unsigned int valid_hooks);
10197
/* the data used by the kernel */
10298
struct ebt_table_info *private;
10399
struct nf_hook_ops *ops;

include/net/netfilter/nf_flow_table.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ void flow_offload_refresh(struct nf_flowtable *flow_table,
270270

271271
struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table,
272272
struct flow_offload_tuple *tuple);
273+
void nf_flow_table_gc_run(struct nf_flowtable *flow_table);
273274
void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable,
274275
struct net_device *dev);
275276
void nf_flow_table_cleanup(struct net_device *dev);
@@ -306,6 +307,8 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable,
306307
struct flow_offload *flow);
307308

308309
void nf_flow_table_offload_flush(struct nf_flowtable *flowtable);
310+
void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable);
311+
309312
int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
310313
struct net_device *dev,
311314
enum flow_block_command cmd);

include/net/netfilter/nf_tables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,7 @@ struct nftables_pernet {
16521652
struct list_head module_list;
16531653
struct list_head notify_list;
16541654
struct mutex commit_mutex;
1655+
u64 table_handle;
16551656
unsigned int base_seq;
16561657
u8 validate_state;
16571658
};

net/bridge/netfilter/ebtable_broute.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,10 @@ static struct ebt_replace_kernel initial_table = {
3636
.entries = (char *)&initial_chain,
3737
};
3838

39-
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
40-
{
41-
if (valid_hooks & ~(1 << NF_BR_BROUTING))
42-
return -EINVAL;
43-
return 0;
44-
}
45-
4639
static const struct ebt_table broute_table = {
4740
.name = "broute",
4841
.table = &initial_table,
4942
.valid_hooks = 1 << NF_BR_BROUTING,
50-
.check = check,
5143
.me = THIS_MODULE,
5244
};
5345

net/bridge/netfilter/ebtable_filter.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = {
4343
.entries = (char *)initial_chains,
4444
};
4545

46-
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
47-
{
48-
if (valid_hooks & ~FILTER_VALID_HOOKS)
49-
return -EINVAL;
50-
return 0;
51-
}
52-
5346
static const struct ebt_table frame_filter = {
5447
.name = "filter",
5548
.table = &initial_table,
5649
.valid_hooks = FILTER_VALID_HOOKS,
57-
.check = check,
5850
.me = THIS_MODULE,
5951
};
6052

net/bridge/netfilter/ebtable_nat.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = {
4343
.entries = (char *)initial_chains,
4444
};
4545

46-
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
47-
{
48-
if (valid_hooks & ~NAT_VALID_HOOKS)
49-
return -EINVAL;
50-
return 0;
51-
}
52-
5346
static const struct ebt_table frame_nat = {
5447
.name = "nat",
5548
.table = &initial_table,
5649
.valid_hooks = NAT_VALID_HOOKS,
57-
.check = check,
5850
.me = THIS_MODULE,
5951
};
6052

net/bridge/netfilter/ebtables.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,8 +1040,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
10401040
goto free_iterate;
10411041
}
10421042

1043-
/* the table doesn't like it */
1044-
if (t->check && (ret = t->check(newinfo, repl->valid_hooks)))
1043+
if (repl->valid_hooks != t->valid_hooks)
10451044
goto free_unlock;
10461045

10471046
if (repl->num_counters && repl->num_counters != t->private->nentries) {
@@ -1231,11 +1230,6 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
12311230
if (ret != 0)
12321231
goto free_chainstack;
12331232

1234-
if (table->check && table->check(newinfo, table->valid_hooks)) {
1235-
ret = -EINVAL;
1236-
goto free_chainstack;
1237-
}
1238-
12391233
table->private = newinfo;
12401234
rwlock_init(&table->lock);
12411235
mutex_lock(&ebt_mutex);

net/ipv6/netfilter/nf_conntrack_reasm.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ static int nf_ct_frag6_sysctl_register(struct net *net)
8686
table[1].extra2 = &nf_frag->fqdir->high_thresh;
8787
table[2].data = &nf_frag->fqdir->high_thresh;
8888
table[2].extra1 = &nf_frag->fqdir->low_thresh;
89-
table[2].extra2 = &nf_frag->fqdir->high_thresh;
9089

9190
hdr = register_net_sysctl(net, "net/netfilter", table);
9291
if (hdr == NULL)

net/netfilter/nf_conntrack_proto_tcp.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,37 @@ static bool tcp_in_window(struct nf_conn *ct,
655655
tn->tcp_be_liberal)
656656
res = true;
657657
if (!res) {
658+
bool seq_ok = before(seq, sender->td_maxend + 1);
659+
660+
if (!seq_ok) {
661+
u32 overshot = end - sender->td_maxend + 1;
662+
bool ack_ok;
663+
664+
ack_ok = after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1);
665+
666+
if (in_recv_win &&
667+
ack_ok &&
668+
overshot <= receiver->td_maxwin &&
669+
before(sack, receiver->td_end + 1)) {
670+
/* Work around TCPs that send more bytes than allowed by
671+
* the receive window.
672+
*
673+
* If the (marked as invalid) packet is allowed to pass by
674+
* the ruleset and the peer acks this data, then its possible
675+
* all future packets will trigger 'ACK is over upper bound' check.
676+
*
677+
* Thus if only the sequence check fails then do update td_end so
678+
* possible ACK for this data can update internal state.
679+
*/
680+
sender->td_end = end;
681+
sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
682+
683+
nf_ct_l4proto_log_invalid(skb, ct, hook_state,
684+
"%u bytes more than expected", overshot);
685+
return res;
686+
}
687+
}
688+
658689
nf_ct_l4proto_log_invalid(skb, ct, hook_state,
659690
"%s",
660691
before(seq, sender->td_maxend + 1) ?

net/netfilter/nf_flow_table_core.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -437,12 +437,17 @@ static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
437437
}
438438
}
439439

440+
void nf_flow_table_gc_run(struct nf_flowtable *flow_table)
441+
{
442+
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
443+
}
444+
440445
static void nf_flow_offload_work_gc(struct work_struct *work)
441446
{
442447
struct nf_flowtable *flow_table;
443448

444449
flow_table = container_of(work, struct nf_flowtable, gc_work.work);
445-
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
450+
nf_flow_table_gc_run(flow_table);
446451
queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ);
447452
}
448453

@@ -600,11 +605,11 @@ void nf_flow_table_free(struct nf_flowtable *flow_table)
600605
mutex_unlock(&flowtable_lock);
601606

602607
cancel_delayed_work_sync(&flow_table->gc_work);
603-
nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
604-
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
605608
nf_flow_table_offload_flush(flow_table);
606-
if (nf_flowtable_hw_offload(flow_table))
607-
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
609+
/* ... no more pending work after this stage ... */
610+
nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
611+
nf_flow_table_gc_run(flow_table);
612+
nf_flow_table_offload_flush_cleanup(flow_table);
608613
rhashtable_destroy(&flow_table->rhashtable);
609614
}
610615
EXPORT_SYMBOL_GPL(nf_flow_table_free);

0 commit comments

Comments
 (0)