FAILED: patch "[PATCH] rxrpc: proc: size address buffers for %pISpc output" failed to apply to 6.6-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.6-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.6.y
git checkout FETCH_HEAD
git cherry-pick -x a44ce6aa2efb61fe44f2cfab72bb01544bbca272
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026041327-hydroxide-proofread-7f9e@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a44ce6aa2efb61fe44f2cfab72bb01544bbca272 Mon Sep 17 00:00:00 2001
From: Pengpeng Hou <[email protected]>
Date: Wed, 8 Apr 2026 13:12:49 +0100
Subject: [PATCH] rxrpc: proc: size address buffers for %pISpc output
The AF_RXRPC procfs helpers format local and remote socket addresses into fixed 50-byte stack buffers with "%pISpc".
That is too small for the longest current-tree IPv6-with-port form the formatter can produce. In lib/vsprintf.c, the compressed IPv6 path uses a dotted-quad tail not only for v4mapped addresses, but also for ISATAP addresses via ipv6_addr_is_isatap().
As a result, a case such as
[ffff:ffff:ffff:ffff:0:5efe:255.255.255.255]:65535
is possible with the current formatter. That is 50 visible characters, so 51 bytes including the trailing NUL, which does not fit in the existing char[50] buffers used by net/rxrpc/proc.c.
Size the buffers from the formatter's maximum textual form and switch the call sites to scnprintf().
Changes since v1:
- correct the changelog to cite the actual maximum current-tree case explicitly
- frame the proof around the ISATAP formatting path instead of the earlier mapped-v4 example
net/rxrpc/proc.c +18 -14
@@ -10,6 +10,10 @@#include <net/af_rxrpc.h> #include "ar-internal.h" +#define RXRPC_PROC_ADDRBUF_SIZE \ + (sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + \ + sizeof(":12345")) +static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES ] = { [RXRPC_CONN_UNUSED ] ="Unused " , [RXRPC_CONN_CLIENT_UNSECURED ] ="ClUnsec " ,
@@ -53,7 +57,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)struct rxrpc_net *rxnet =rxrpc_net (seq_file_net (seq));enum rxrpc_call_state state;rxrpc_seq_t tx_bottom; -char lbuff[50 ], rbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ], rbuff[RXRPC_PROC_ADDRBUF_SIZE ];long timeout =0 ;if (v == &rxnet->calls) {
@@ -69,11 +73,11 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v) local = call->local;if (local) -sprintf (lbuff,"%pISpc" , &local->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &local->srx.transport);else strcpy (lbuff,"no_local" ); -sprintf (rbuff,"%pISpc" , &call->dest_srx.transport); +scnprintf (rbuff,sizeof (rbuff),"%pISpc" , &call->dest_srx.transport); state =rxrpc_call_state (call);if (state !=RXRPC_CALL_SERVER_PREALLOC )
@@ -142,7 +146,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)struct rxrpc_connection *conn;struct rxrpc_net *rxnet =rxrpc_net (seq_file_net (seq));const char *state; -char lbuff[50 ], rbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ], rbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v == &rxnet->conn_proc_list) { seq_puts(seq,
@@ -161,8 +165,8 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v) goto print; } -sprintf (lbuff,"%pISpc" , &conn->local->srx.transport); -sprintf (rbuff,"%pISpc" , &conn->peer->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &conn->local->srx.transport); +scnprintf (rbuff,sizeof (rbuff),"%pISpc" , &conn->peer->srx.transport); print: state =rxrpc_is_conn_aborted (conn) ? rxrpc_call_completions[conn->completion] :
@@ -228,7 +232,7 @@ static int rxrpc_bundle_seq_show(struct seq_file *seq, void *v) {struct rxrpc_bundle *bundle;struct rxrpc_net *rxnet =rxrpc_net (seq_file_net (seq)); -char lbuff[50 ], rbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ], rbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v == &rxnet->bundle_proc_list) { seq_puts(seq,
@@ -242,8 +246,8 @@ static int rxrpc_bundle_seq_show(struct seq_file *seq, void *v) bundle = list_entry(v, struct rxrpc_bundle, proc_link); -sprintf (lbuff,"%pISpc" , &bundle->local->srx.transport); -sprintf (rbuff,"%pISpc" , &bundle->peer->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &bundle->local->srx.transport); +scnprintf (rbuff,sizeof (rbuff),"%pISpc" , &bundle->peer->srx.transport); seq_printf(seq, "UDP %-47.47s %-47.47s %4x %3u %3d" " %c%c%c %08x | %08x %08x %08x %08x %08x\n",
@@ -279,7 +283,7 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) {struct rxrpc_peer *peer;time64_t now; -char lbuff[50 ], rbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ], rbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v ==SEQ_START_TOKEN ) { seq_puts(seq,
@@ -290,9 +294,9 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) peer = list_entry(v, struct rxrpc_peer, hash_link); -sprintf (lbuff,"%pISpc" , &peer->local->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &peer->local->srx.transport); -sprintf (rbuff,"%pISpc" , &peer->srx.transport); +scnprintf (rbuff,sizeof (rbuff),"%pISpc" , &peer->srx.transport); now =ktime_get_seconds (); seq_printf(seq,
@@ -401,7 +405,7 @@ const struct seq_operations rxrpc_peer_seq_ops = {static int rxrpc_local_seq_show (struct seq_file *seq,void *v) {struct rxrpc_local *local; -char lbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v ==SEQ_START_TOKEN ) { seq_puts(seq,
@@ -412,7 +416,7 @@ static int rxrpc_local_seq_show(struct seq_file *seq, void *v) local = hlist_entry(v, struct rxrpc_local, link); -sprintf (lbuff,"%pISpc" , &local->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &local->srx.transport); seq_printf(seq, "UDP %-47.47s %3u %3u %3u\n",
Sasha Levin
maintainerPATCH 1/2 rxrpc: Don't need barrier for ->tx_bottom and ->acks_hard_ack
From: David Howells <[email protected]>
[ Upstream commit 6396b48ac0a77165f9c2c40ab03d6c8188c89739 ]
We don't need a barrier for the ->tx_bottom value (which indicates the lowest sequence still in the transmission queue) and the ->acks_hard_ack value (which tracks the DATA packets hard-ack'd by the latest ACK packet received and thus indicates which DATA packets can now be discarded) as the app thread doesn't use either value as a reference to memory to access. Rather, the app thread merely uses these as a guide to how much space is available in the transmission queue
Change the code to use READ/WRITE_ONCE() instead.
Also, change rxrpc_check_tx_space() to use the same value for tx_bottom throughout.
Stable-dep-of: a44ce6aa2efb ("rxrpc: proc: size address buffers for %pISpc output")
--- net/rxrpc/sendmsg.c | 8 +++++--- net/rxrpc/txbuf.c | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-)
net/rxrpc/sendmsg.c +5 -3
@@ -93,9 +93,11 @@ static int rxrpc_wait_to_be_connected(struct rxrpc_call *call, long *timeo)*/ static bool rxrpc_check_tx_space (struct rxrpc_call *call,rxrpc_seq_t *_tx_win) { +rxrpc_seq_t tx_bottom =READ_ONCE (call->tx_bottom); +if (_tx_win) - *_tx_win = call->tx_bottom; -return call->tx_prepared - call->tx_bottom <256 ; + *_tx_win = tx_bottom; +return call->tx_prepared - tx_bottom <256 ; }/*
@@ -137,7 +139,7 @@ static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx, rtt =2 ; timeout = rtt; - tx_start =smp_load_acquire (&call->acks_hard_ack); + tx_start =READ_ONCE (call->acks_hard_ack);for (;;) {set_current_state (TASK_UNINTERRUPTIBLE );
net/rxrpc/txbuf.c +2 -2
@@ -112,14 +112,14 @@ void rxrpc_shrink_call_tx_buffer(struct rxrpc_call *call)while ((txb =list_first_entry_or_null (&call->tx_buffer, struct rxrpc_txbuf, call_link))) { - hard_ack =smp_load_acquire (&call->acks_hard_ack); + hard_ack = call->acks_hard_ack;if (before (hard_ack, txb->seq))break ;if (txb->seq != call->tx_bottom +1 )rxrpc_see_txbuf (txb, rxrpc_txbuf_see_out_of_step); ASSERTCMP(txb->seq, ==, call->tx_bottom + 1); -smp_store_release (&call->tx_bottom, call->tx_bottom +1 ); +WRITE_ONCE (call->tx_bottom, call->tx_bottom +1 );list_del_rcu (&txb->call_link);trace_rxrpc_txqueue (call, rxrpc_txqueue_dequeue);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 rxrpc: proc: size address buffers for %pISpc output
From: Pengpeng Hou <[email protected]>
[ Upstream commit a44ce6aa2efb61fe44f2cfab72bb01544bbca272 ]
The AF_RXRPC procfs helpers format local and remote socket addresses into fixed 50-byte stack buffers with "%pISpc".
That is too small for the longest current-tree IPv6-with-port form the formatter can produce. In lib/vsprintf.c, the compressed IPv6 path uses a dotted-quad tail not only for v4mapped addresses, but also for ISATAP addresses via ipv6_addr_is_isatap().
As a result, a case such as
[ffff:ffff:ffff:ffff:0:5efe:255.255.255.255]:65535
is possible with the current formatter. That is 50 visible characters, so 51 bytes including the trailing NUL, which does not fit in the existing char[50] buffers used by net/rxrpc/proc.c.
Size the buffers from the formatter's maximum textual form and switch the call sites to scnprintf().
Changes since v1:
- correct the changelog to cite the actual maximum current-tree case explicitly
- frame the proof around the ISATAP formatting path instead of the earlier mapped-v4 example
--- net/rxrpc/proc.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
net/rxrpc/proc.c +15 -11
@@ -10,6 +10,10 @@#include <net/af_rxrpc.h> #include "ar-internal.h" +#define RXRPC_PROC_ADDRBUF_SIZE \ + (sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + \ + sizeof(":12345")) +static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES ] = { [RXRPC_CONN_UNUSED ] ="Unused " , [RXRPC_CONN_CLIENT_UNSECURED ] ="ClUnsec " ,
@@ -54,7 +58,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)enum rxrpc_call_state state;unsigned long timeout =0 ;rxrpc_seq_t acks_hard_ack; -char lbuff[50 ], rbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ], rbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v == &rxnet->calls) { seq_puts(seq,
@@ -69,11 +73,11 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v) local = call->local;if (local) -sprintf (lbuff,"%pISpc" , &local->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &local->srx.transport);else strcpy (lbuff,"no_local" ); -sprintf (rbuff,"%pISpc" , &call->dest_srx.transport); +scnprintf (rbuff,sizeof (rbuff),"%pISpc" , &call->dest_srx.transport); state =rxrpc_call_state (call);if (state !=RXRPC_CALL_SERVER_PREALLOC ) {
@@ -144,7 +148,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)struct rxrpc_connection *conn;struct rxrpc_net *rxnet =rxrpc_net (seq_file_net (seq));const char *state; -char lbuff[50 ], rbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ], rbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v == &rxnet->conn_proc_list) { seq_puts(seq,
@@ -163,8 +167,8 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v) goto print; } -sprintf (lbuff,"%pISpc" , &conn->local->srx.transport); -sprintf (rbuff,"%pISpc" , &conn->peer->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &conn->local->srx.transport); +scnprintf (rbuff,sizeof (rbuff),"%pISpc" , &conn->peer->srx.transport); print: state =rxrpc_is_conn_aborted (conn) ? rxrpc_call_completions[conn->completion] :
@@ -205,7 +209,7 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) {struct rxrpc_peer *peer;time64_t now; -char lbuff[50 ], rbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ], rbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v ==SEQ_START_TOKEN ) { seq_puts(seq,
@@ -218,9 +222,9 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v) peer = list_entry(v, struct rxrpc_peer, hash_link); -sprintf (lbuff,"%pISpc" , &peer->local->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &peer->local->srx.transport); -sprintf (rbuff,"%pISpc" , &peer->srx.transport); +scnprintf (rbuff,sizeof (rbuff),"%pISpc" , &peer->srx.transport); now =ktime_get_seconds (); seq_printf(seq,
@@ -330,7 +334,7 @@ const struct seq_operations rxrpc_peer_seq_ops = {static int rxrpc_local_seq_show (struct seq_file *seq,void *v) {struct rxrpc_local *local; -char lbuff[50 ]; +char lbuff[RXRPC_PROC_ADDRBUF_SIZE ];if (v ==SEQ_START_TOKEN ) { seq_puts(seq,
@@ -341,7 +345,7 @@ static int rxrpc_local_seq_show(struct seq_file *seq, void *v) local = hlist_entry(v, struct rxrpc_local, link); -sprintf (lbuff,"%pISpc" , &local->srx.transport); +scnprintf (lbuff,sizeof (lbuff),"%pISpc" , &local->srx.transport); seq_printf(seq, "UDP %-47.47s %3u %3u %3u\n",
Signature · 1 line
2.53.0