Skip to content

Commit e77ea97

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Florian Westphal says: ==================== netfilter updates for net Three late fixes for netfilter: 1) If nf_queue user requests packet truncation below size of l3 header, we corrupt the skb, then crash. Reject such requests. 2) add cond_resched() calls when doing cycle detection in the nf_tables graph. This avoids softlockup warning with certain rulesets. 3) Reject rulesets that use nftables 'queue' expression in family/chain combinations other than those that are supported. Currently the ruleset will load, but when userspace attempts to reinject you get WARN splat + packet drops. * git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nft_queue: only allow supported familes and hooks netfilter: nf_tables: add rescheduling points during loop detection walks netfilter: nf_queue: do not allow packet truncation below transport header offset ==================== Link: https://lore.kernel.org/r/20220726192056.13497-1-fw@strlen.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents e53f529 + 47f4f51 commit e77ea97

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3340,6 +3340,8 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
33403340
if (err < 0)
33413341
return err;
33423342
}
3343+
3344+
cond_resched();
33433345
}
33443346

33453347
return 0;
@@ -9367,9 +9369,13 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
93679369
break;
93689370
}
93699371
}
9372+
9373+
cond_resched();
93709374
}
93719375

93729376
list_for_each_entry(set, &ctx->table->sets, list) {
9377+
cond_resched();
9378+
93739379
if (!nft_is_active_next(ctx->net, set))
93749380
continue;
93759381
if (!(set->flags & NFT_SET_MAP) ||

net/netfilter/nfnetlink_queue.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,11 +843,16 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
843843
}
844844

845845
static int
846-
nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e, int diff)
846+
nfqnl_mangle(void *data, unsigned int data_len, struct nf_queue_entry *e, int diff)
847847
{
848848
struct sk_buff *nskb;
849849

850850
if (diff < 0) {
851+
unsigned int min_len = skb_transport_offset(e->skb);
852+
853+
if (data_len < min_len)
854+
return -EINVAL;
855+
851856
if (pskb_trim(e->skb, data_len))
852857
return -ENOMEM;
853858
} else if (diff > 0) {

net/netfilter/nft_queue.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,31 @@ static void nft_queue_sreg_eval(const struct nft_expr *expr,
6868
regs->verdict.code = ret;
6969
}
7070

71+
static int nft_queue_validate(const struct nft_ctx *ctx,
72+
const struct nft_expr *expr,
73+
const struct nft_data **data)
74+
{
75+
static const unsigned int supported_hooks = ((1 << NF_INET_PRE_ROUTING) |
76+
(1 << NF_INET_LOCAL_IN) |
77+
(1 << NF_INET_FORWARD) |
78+
(1 << NF_INET_LOCAL_OUT) |
79+
(1 << NF_INET_POST_ROUTING));
80+
81+
switch (ctx->family) {
82+
case NFPROTO_IPV4:
83+
case NFPROTO_IPV6:
84+
case NFPROTO_INET:
85+
case NFPROTO_BRIDGE:
86+
break;
87+
case NFPROTO_NETDEV: /* lacks okfn */
88+
fallthrough;
89+
default:
90+
return -EOPNOTSUPP;
91+
}
92+
93+
return nft_chain_validate_hooks(ctx->chain, supported_hooks);
94+
}
95+
7196
static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
7297
[NFTA_QUEUE_NUM] = { .type = NLA_U16 },
7398
[NFTA_QUEUE_TOTAL] = { .type = NLA_U16 },
@@ -164,6 +189,7 @@ static const struct nft_expr_ops nft_queue_ops = {
164189
.eval = nft_queue_eval,
165190
.init = nft_queue_init,
166191
.dump = nft_queue_dump,
192+
.validate = nft_queue_validate,
167193
.reduce = NFT_REDUCE_READONLY,
168194
};
169195

@@ -173,6 +199,7 @@ static const struct nft_expr_ops nft_queue_sreg_ops = {
173199
.eval = nft_queue_sreg_eval,
174200
.init = nft_queue_sreg_init,
175201
.dump = nft_queue_sreg_dump,
202+
.validate = nft_queue_validate,
176203
.reduce = NFT_REDUCE_READONLY,
177204
};
178205

0 commit comments

Comments
 (0)