mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 05:44:11 +00:00
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>
This commit is contained in:
commit
e77ea97d2b
3 changed files with 39 additions and 1 deletions
|
@ -3340,6 +3340,8 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
|
|||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -9367,9 +9369,13 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
list_for_each_entry(set, &ctx->table->sets, list) {
|
||||
cond_resched();
|
||||
|
||||
if (!nft_is_active_next(ctx->net, set))
|
||||
continue;
|
||||
if (!(set->flags & NFT_SET_MAP) ||
|
||||
|
|
|
@ -843,11 +843,16 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|||
}
|
||||
|
||||
static int
|
||||
nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e, int diff)
|
||||
nfqnl_mangle(void *data, unsigned int data_len, struct nf_queue_entry *e, int diff)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
if (diff < 0) {
|
||||
unsigned int min_len = skb_transport_offset(e->skb);
|
||||
|
||||
if (data_len < min_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (pskb_trim(e->skb, data_len))
|
||||
return -ENOMEM;
|
||||
} else if (diff > 0) {
|
||||
|
|
|
@ -68,6 +68,31 @@ static void nft_queue_sreg_eval(const struct nft_expr *expr,
|
|||
regs->verdict.code = ret;
|
||||
}
|
||||
|
||||
static int nft_queue_validate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr,
|
||||
const struct nft_data **data)
|
||||
{
|
||||
static const unsigned int supported_hooks = ((1 << NF_INET_PRE_ROUTING) |
|
||||
(1 << NF_INET_LOCAL_IN) |
|
||||
(1 << NF_INET_FORWARD) |
|
||||
(1 << NF_INET_LOCAL_OUT) |
|
||||
(1 << NF_INET_POST_ROUTING));
|
||||
|
||||
switch (ctx->family) {
|
||||
case NFPROTO_IPV4:
|
||||
case NFPROTO_IPV6:
|
||||
case NFPROTO_INET:
|
||||
case NFPROTO_BRIDGE:
|
||||
break;
|
||||
case NFPROTO_NETDEV: /* lacks okfn */
|
||||
fallthrough;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return nft_chain_validate_hooks(ctx->chain, supported_hooks);
|
||||
}
|
||||
|
||||
static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
|
||||
[NFTA_QUEUE_NUM] = { .type = NLA_U16 },
|
||||
[NFTA_QUEUE_TOTAL] = { .type = NLA_U16 },
|
||||
|
@ -164,6 +189,7 @@ static const struct nft_expr_ops nft_queue_ops = {
|
|||
.eval = nft_queue_eval,
|
||||
.init = nft_queue_init,
|
||||
.dump = nft_queue_dump,
|
||||
.validate = nft_queue_validate,
|
||||
.reduce = NFT_REDUCE_READONLY,
|
||||
};
|
||||
|
||||
|
@ -173,6 +199,7 @@ static const struct nft_expr_ops nft_queue_sreg_ops = {
|
|||
.eval = nft_queue_sreg_eval,
|
||||
.init = nft_queue_sreg_init,
|
||||
.dump = nft_queue_sreg_dump,
|
||||
.validate = nft_queue_validate,
|
||||
.reduce = NFT_REDUCE_READONLY,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue