FAILED: patch "[PATCH] netfilter: nf_conntrack: defer invalid log until after unlock" failed to apply to 6.1-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 2d19b95c9723001f214f7a47d67b09f46238f200
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026081731-reflux-overcrowd-ff11@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2d19b95c9723001f214f7a47d67b09f46238f200 Mon Sep 17 00:00:00 2001
From: Zihan Xi <[email protected]>
Date: Sat, 1 Aug 2026 14:27:17 +0000
Subject: [PATCH] netfilter: nf_conntrack: defer invalid log until after unlock
TCP and SCTP conntrack paths can emit invalid-packet logs while ct->lock is still held.
When invalid logging is routed to nfnetlink_log and conntrack export is enabled, the log path can re-enter conntrack netlink glue and dump the same conntrack again. Protocol attribute dumping may take ct->lock, so logging while holding that lock can deadlock.
Defer the TCP invalid logs by storing only the minimal log context while ct->lock is held and emitting the log after unlocking. Also make the TCP timeout-lowering invalid path return whether a log is needed, then emit that log after unlocking.
Do the same for the SCTP invalid state-transition log that can be reached while ct->lock is held.
Add a lockdep assertion to nf_ct_l4proto_log_invalid() so future callers that log invalid conntracks while holding ct->lock are caught outside TCP and SCTP as well.
net/netfilter/nf_conntrack_proto.c +6 -0
@@ -79,6 +79,12 @@ void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,struct net *net;va_list args; +/* nfnetlink_log may re-enter conntrack attribute dumping and try to +* take ct->lock again via helpers such as tcp_to_nlattr(), so invalid +* conntrack logs must only be emitted after dropping ct->lock. +*/ +lockdep_assert_not_held (&ct->lock); + net =nf_ct_net (ct);if (likely (net->ct.sysctl_log_invalid ==0 ))return ;
net/netfilter/nf_conntrack_proto_sctp.c +8 -4
@@ -336,10 +336,12 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,struct sctphdr _sctph;const struct sctp_chunkhdr *sch;struct sctp_chunkhdr _sch; +bool log_invalid = false;u_int32_t offset, count;unsigned int *timeouts;unsigned long map[256 /sizeof (unsigned long )] = {0 };bool ignore = false; +u8 invalid_type =0 ;if (sctp_error (skb, dataoff, state))return -NF_ACCEPT ;
@@ -451,10 +453,8 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,/* Invalid */ if (new_state ==SCTP_CONNTRACK_MAX ) { -nf_ct_l4proto_log_invalid (skb, ct, state, -"Invalid, old_state %d, dir %d, type %d" , - old_state, dir, sch->type); - + log_invalid = true; + invalid_type = sch->type; goto out_unlock; }
@@ -529,6 +529,10 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, out_unlock:spin_unlock_bh (&ct->lock); +if (log_invalid) +nf_ct_l4proto_log_invalid (skb, ct, state, +"Invalid, old_state %d, dir %d, type %d" , + old_state, dir, invalid_type); out:return -NF_ACCEPT ; }
net/netfilter/nf_conntrack_proto_tcp.c +88 -44
225 lines not on this page · raw message
Sasha Levin
maintainerPATCH 1/2 netfilter: conntrack: sctp: use nf log infrastructure for invalid packets
From: Florian Westphal <[email protected]>
[ Upstream commit f71cb8f45d092a1805e9ad474b6c6a17219cede5 ]
The conntrack logging facilities include useful info such as in/out interface names and packet headers.
Use those in more places instead of pr_debug calls. Furthermore, several pr_debug calls can be removed, they are useless on production machines due to the sheer volume of log messages.
Stable-dep-of: 2d19b95c9723 ("netfilter: nf_conntrack: defer invalid log until after unlock")
--- net/netfilter/nf_conntrack_proto_sctp.c | 44 +++++++++---------------- 1 file changed, 15 insertions(+), 29 deletions(-)
net/netfilter/nf_conntrack_proto_sctp.c +15 -29
@@ -152,7 +152,8 @@ for ((offset) = (dataoff) + sizeof(struct sctphdr), (count) = 0; \static int do_basic_checks (struct nf_conn *ct,const struct sk_buff *skb,unsigned int dataoff, -unsigned long *map) +unsigned long *map, +const struct nf_hook_state *state) {u_int32_t offset, count;struct sctp_chunkhdr _sch, *sch;
@@ -161,8 +162,6 @@ static int do_basic_checks(struct nf_conn *ct, flag =0 ; for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { -pr_debug ("Chunk Num: %d Type: %d\n" , count, sch->type); -if (sch->type ==SCTP_CID_INIT || sch->type ==SCTP_CID_INIT_ACK || sch->type ==SCTP_CID_SHUTDOWN_COMPLETE )
@@ -177,7 +176,9 @@ static int do_basic_checks(struct nf_conn *ct, sch->type == SCTP_CID_COOKIE_ECHO || flag) && count != 0) || !sch->length) { -pr_debug ("Basic checks failed\n" ); +nf_ct_l4proto_log_invalid (skb, ct, state, +"%s failed. chunk num %d, type %d, len %d flag %d\n" , + __func__, count, sch->type, sch->length, flag);return 1 ; }
@@ -185,7 +186,6 @@ static int do_basic_checks(struct nf_conn *ct,set_bit (sch->type, map); } -pr_debug ("Basic checks passed\n" );return count ==0 ; }
@@ -195,64 +195,47 @@ static int sctp_new_state(enum ip_conntrack_dir dir, {int i; -pr_debug ("Chunk type: %d\n" , chunk_type); -switch (chunk_type) {case SCTP_CID_INIT : -pr_debug ("SCTP_CID_INIT\n" ); i =0 ;break ;case SCTP_CID_INIT_ACK : -pr_debug ("SCTP_CID_INIT_ACK\n" ); i =1 ;break ;case SCTP_CID_ABORT : -pr_debug ("SCTP_CID_ABORT\n" ); i =2 ;break ;case SCTP_CID_SHUTDOWN : -pr_debug ("SCTP_CID_SHUTDOWN\n" ); i =3 ;break ;case SCTP_CID_SHUTDOWN_ACK : -pr_debug ("SCTP_CID_SHUTDOWN_ACK\n" ); i =4 ;break ;case SCTP_CID_ERROR : -pr_debug ("SCTP_CID_ERROR\n" ); i =5 ;break ;case SCTP_CID_COOKIE_ECHO : -pr_debug ("SCTP_CID_COOKIE_ECHO\n" ); i =6 ;break ;case SCTP_CID_COOKIE_ACK : -pr_debug ("SCTP_CID_COOKIE_ACK\n" ); i =7 ;break ;case SCTP_CID_SHUTDOWN_COMPLETE : -pr_debug ("SCTP_CID_SHUTDOWN_COMPLETE\n" ); i =8 ;break ;case SCTP_CID_HEARTBEAT : -pr_debug ("SCTP_CID_HEARTBEAT" ); i =9 ;break ;case SCTP_CID_HEARTBEAT_ACK : -pr_debug ("SCTP_CID_HEARTBEAT_ACK" ); i =10 ;break ;default :/* Other chunks like DATA or SACK do not change the state */ -pr_debug ("Unknown chunk type, Will stay in %s\n" , - sctp_conntrack_names[cur_state]); +pr_debug ("Unknown chunk type %d, Will stay in %s\n" , + chunk_type, sctp_conntrack_names[cur_state]);return cur_state; } -pr_debug ("dir: %d cur_state: %s chunk_type: %d new_state: %s\n" , - dir, sctp_conntrack_names[cur_state], chunk_type, - sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]); -return sctp_conntracks[dir][i][cur_state]; }
@@ -369,7 +352,7 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,if (sh ==NULL ) goto out; -if (do_basic_checks (ct, skb, dataoff, map) !=0 ) +if (do_basic_checks (ct, skb, dataoff, map, state) !=0 ) goto out;if (!nf_ct_is_confirmed (ct)) {
@@ -392,7 +375,9 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, !test_bit(SCTP_CID_HEARTBEAT, map) && !test_bit(SCTP_CID_HEARTBEAT_ACK, map) && sh->vtag != ct->proto.sctp.vtag[dir]) { -pr_debug ("Verification tag check failed\n" ); +nf_ct_l4proto_log_invalid (skb, ct, state, +"verification tag check failed %x vs %x for dir %d" , + sh->vtag, ct->proto.sctp.vtag[dir], dir); goto out; }
@@ -470,9 +455,10 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,/* Invalid */ if (new_state ==SCTP_CONNTRACK_MAX ) { -pr_debug ("nf_conntrack_sctp: Invalid dir=%i ctype=%u " -"conntrack=%u\n" , - dir, sch->type, old_state); +nf_ct_l4proto_log_invalid (skb, ct, state, +"Invalid, old_state %d, dir %d, type %d" , + old_state, dir, sch->type); + goto out_unlock; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 netfilter: nf_conntrack: defer invalid log until after unlock
From: Zihan Xi <[email protected]>
[ Upstream commit 2d19b95c9723001f214f7a47d67b09f46238f200 ]
TCP and SCTP conntrack paths can emit invalid-packet logs while ct->lock is still held.
When invalid logging is routed to nfnetlink_log and conntrack export is enabled, the log path can re-enter conntrack netlink glue and dump the same conntrack again. Protocol attribute dumping may take ct->lock, so logging while holding that lock can deadlock.
Defer the TCP invalid logs by storing only the minimal log context while ct->lock is held and emitting the log after unlocking. Also make the TCP timeout-lowering invalid path return whether a log is needed, then emit that log after unlocking.
Do the same for the SCTP invalid state-transition log that can be reached while ct->lock is held.
Add a lockdep assertion to nf_ct_l4proto_log_invalid() so future callers that log invalid conntracks while holding ct->lock are caught outside TCP and SCTP as well.
--- net/netfilter/nf_conntrack_proto.c | 6 ++ net/netfilter/nf_conntrack_proto_sctp.c | 12 ++- net/netfilter/nf_conntrack_proto_tcp.c | 132 ++++++++++++++++-------- 3 files changed, 102 insertions(+), 48 deletions(-)
net/netfilter/nf_conntrack_proto.c +6 -0
@@ -79,6 +79,12 @@ void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,struct net *net;va_list args; +/* nfnetlink_log may re-enter conntrack attribute dumping and try to +* take ct->lock again via helpers such as tcp_to_nlattr(), so invalid +* conntrack logs must only be emitted after dropping ct->lock. +*/ +lockdep_assert_not_held (&ct->lock); + net =nf_ct_net (ct);if (likely (net->ct.sysctl_log_invalid ==0 ))return ;
net/netfilter/nf_conntrack_proto_sctp.c +8 -4
@@ -340,10 +340,12 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,struct sctphdr _sctph;const struct sctp_chunkhdr *sch;struct sctp_chunkhdr _sch; +bool log_invalid = false;u_int32_t offset, count;unsigned int *timeouts;unsigned long map[256 /sizeof (unsigned long )] = {0 };bool ignore = false; +u8 invalid_type =0 ;if (sctp_error (skb, dataoff, state))return -NF_ACCEPT ;
@@ -455,10 +457,8 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,/* Invalid */ if (new_state ==SCTP_CONNTRACK_MAX ) { -nf_ct_l4proto_log_invalid (skb, ct, state, -"Invalid, old_state %d, dir %d, type %d" , - old_state, dir, sch->type); - + log_invalid = true; + invalid_type = sch->type; goto out_unlock; }
@@ -533,6 +533,10 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, out_unlock:spin_unlock_bh (&ct->lock); +if (log_invalid) +nf_ct_l4proto_log_invalid (skb, ct, state, +"Invalid, old_state %d, dir %d, type %d" , + old_state, dir, invalid_type); out:return -NF_ACCEPT ; }
net/netfilter/nf_conntrack_proto_tcp.c +88 -44
225 lines not on this page · raw message
Signature · 1 line
2.53.0