Skip to content

Commit

Permalink
netfilter: tproxy: fix deadlock due to missing BH disable
Browse files Browse the repository at this point in the history
The xtables packet traverser performs an unconditional local_bh_disable(),
but the nf_tables evaluation loop does not.

Functions that are called from either xtables or nftables must assume
that they can be called in process context.

inet_twsk_deschedule_put() assumes that no softirq interrupt can occur.
If tproxy is used from nf_tables its possible that we'll deadlock
trying to aquire a lock already held in process context.

Add a small helper that takes care of this and use it.

Link: https://lore.kernel.org/netfilter-devel/[email protected]/
Fixes: 4ed8eb6 ("netfilter: nf_tables: Add native tproxy support")
Reported-and-tested-by: Major Dávid <[email protected]>
Signed-off-by: Florian Westphal <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
  • Loading branch information
Florian Westphal authored and ummakynes committed Mar 6, 2023
1 parent 9f7dd42 commit 4a02426
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 2 deletions.
7 changes: 7 additions & 0 deletions include/net/netfilter/nf_tproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ static inline bool nf_tproxy_sk_is_transparent(struct sock *sk)
return false;
}

static inline void nf_tproxy_twsk_deschedule_put(struct inet_timewait_sock *tw)
{
local_bh_disable();
inet_twsk_deschedule_put(tw);
local_bh_enable();
}

/* assign a socket to the skb -- consumes sk */
static inline void nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
{
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/netfilter/nf_tproxy_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ nf_tproxy_handle_time_wait4(struct net *net, struct sk_buff *skb,
hp->source, lport ? lport : hp->dest,
skb->dev, NF_TPROXY_LOOKUP_LISTENER);
if (sk2) {
inet_twsk_deschedule_put(inet_twsk(sk));
nf_tproxy_twsk_deschedule_put(inet_twsk(sk));
sk = sk2;
}
}
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/netfilter/nf_tproxy_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ nf_tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff,
lport ? lport : hp->dest,
skb->dev, NF_TPROXY_LOOKUP_LISTENER);
if (sk2) {
inet_twsk_deschedule_put(inet_twsk(sk));
nf_tproxy_twsk_deschedule_put(inet_twsk(sk));
sk = sk2;
}
}
Expand Down

0 comments on commit 4a02426

Please sign in to comment.