Commit 399a14ec authored by Florian Westphal's avatar Florian Westphal Committed by Jakub Kicinski

netfilter: nf_tables: fix crash when nf_trace is enabled

do not access info->pkt when info->trace is not 1.
nft_traceinfo is not initialized, except when tracing is enabled.

The 'nft_trace_enabled' static key cannot be used for this, we must
always check info->trace first.

Pass nft_pktinfo directly to avoid this.

Fixes: e34b9ed9 ("netfilter: nf_tables: avoid skb access on nf_stolen")
Reported-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 2e64fe46
...@@ -34,25 +34,23 @@ static noinline void __nft_trace_packet(struct nft_traceinfo *info, ...@@ -34,25 +34,23 @@ static noinline void __nft_trace_packet(struct nft_traceinfo *info,
nft_trace_notify(info); nft_trace_notify(info);
} }
static inline void nft_trace_packet(struct nft_traceinfo *info, static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
struct nft_traceinfo *info,
const struct nft_chain *chain, const struct nft_chain *chain,
const struct nft_rule_dp *rule, const struct nft_rule_dp *rule,
enum nft_trace_types type) enum nft_trace_types type)
{ {
if (static_branch_unlikely(&nft_trace_enabled)) { if (static_branch_unlikely(&nft_trace_enabled)) {
const struct nft_pktinfo *pkt = info->pkt;
info->nf_trace = pkt->skb->nf_trace; info->nf_trace = pkt->skb->nf_trace;
info->rule = rule; info->rule = rule;
__nft_trace_packet(info, chain, type); __nft_trace_packet(info, chain, type);
} }
} }
static inline void nft_trace_copy_nftrace(struct nft_traceinfo *info) static inline void nft_trace_copy_nftrace(const struct nft_pktinfo *pkt,
struct nft_traceinfo *info)
{ {
if (static_branch_unlikely(&nft_trace_enabled)) { if (static_branch_unlikely(&nft_trace_enabled)) {
const struct nft_pktinfo *pkt = info->pkt;
if (info->trace) if (info->trace)
info->nf_trace = pkt->skb->nf_trace; info->nf_trace = pkt->skb->nf_trace;
} }
...@@ -96,7 +94,6 @@ static noinline void __nft_trace_verdict(struct nft_traceinfo *info, ...@@ -96,7 +94,6 @@ static noinline void __nft_trace_verdict(struct nft_traceinfo *info,
const struct nft_chain *chain, const struct nft_chain *chain,
const struct nft_regs *regs) const struct nft_regs *regs)
{ {
const struct nft_pktinfo *pkt = info->pkt;
enum nft_trace_types type; enum nft_trace_types type;
switch (regs->verdict.code) { switch (regs->verdict.code) {
...@@ -110,7 +107,9 @@ static noinline void __nft_trace_verdict(struct nft_traceinfo *info, ...@@ -110,7 +107,9 @@ static noinline void __nft_trace_verdict(struct nft_traceinfo *info,
break; break;
default: default:
type = NFT_TRACETYPE_RULE; type = NFT_TRACETYPE_RULE;
info->nf_trace = pkt->skb->nf_trace;
if (info->trace)
info->nf_trace = info->pkt->skb->nf_trace;
break; break;
} }
...@@ -271,10 +270,10 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) ...@@ -271,10 +270,10 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
switch (regs.verdict.code) { switch (regs.verdict.code) {
case NFT_BREAK: case NFT_BREAK:
regs.verdict.code = NFT_CONTINUE; regs.verdict.code = NFT_CONTINUE;
nft_trace_copy_nftrace(&info); nft_trace_copy_nftrace(pkt, &info);
continue; continue;
case NFT_CONTINUE: case NFT_CONTINUE:
nft_trace_packet(&info, chain, rule, nft_trace_packet(pkt, &info, chain, rule,
NFT_TRACETYPE_RULE); NFT_TRACETYPE_RULE);
continue; continue;
} }
...@@ -318,7 +317,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) ...@@ -318,7 +317,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
goto next_rule; goto next_rule;
} }
nft_trace_packet(&info, basechain, NULL, NFT_TRACETYPE_POLICY); nft_trace_packet(pkt, &info, basechain, NULL, NFT_TRACETYPE_POLICY);
if (static_branch_unlikely(&nft_counters_enabled)) if (static_branch_unlikely(&nft_counters_enabled))
nft_update_chain_stats(basechain, pkt); nft_update_chain_stats(basechain, pkt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment