public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit
@ 2026-04-01  4:19 Anderson Nascimento
  2026-04-22 16:08 ` David Howells
  0 siblings, 1 reply; 6+ messages in thread
From: Anderson Nascimento @ 2026-04-01  4:19 UTC (permalink / raw)
  To: netdev
  Cc: Anderson Nascimento, dhowells, Marc Dionne, Jakub Kicinski,
	David S. Miller, Eric Dumazet, Paolo Abeni, linux-kernel,
	Jeffrey Altman, Simon Horman

Hello,

I have identified a reliable way to trigger a BUG() in the RxRPC
protocol at rxrpc_destroy_client_conn_ids(). This occurs because the
kernel IO thread can exit while there are still active connection
objects registered in the local IDR (local->conn_ids).

I did a quick analysis and the result is the following. When the IO
thread exits, it calls rxrpc_destroy_local(), which in turn calls
rxrpc_clean_up_local_conns(). However, that function only iterates
over the local->idle_client_conns list. If a connection was recently
created by rxrpc_connect_client_calls() (via
rxrpc_alloc_client_connection()) but has not yet been deactivated or
moved to the idle list, it is completely missed during this cleanup
phase.

Because the connection remains in the IDR, the subsequent call to
rxrpc_destroy_client_conn_ids() finds the entry, logs an "AF_RXRPC:
Leaked client conn" error, and hits a BUG().

I can reliably reproduce this using a client and server where the
server calls close() immediately after sendmsg().

My suggestion for a fix is to update rxrpc_clean_up_local_conns() to
check the local IDR instead of just the idle list, ensuring all
allocated connections are reaped during teardown. I don't have the
time to properly test a patch or verify if the teardown for a
brand-new conn differs significantly from an idle one, so I wanted to
report my quick analysis to the maintainers. I tested on Fedora 43 on
kernel 6.18.

420 void rxrpc_destroy_local(struct rxrpc_local *local)
421 {
...
433         rxrpc_clean_up_local_conns(local);
...
451         rxrpc_purge_client_connections(local);
...
453 }

813 void rxrpc_clean_up_local_conns(struct rxrpc_local *local)
814 {
815         struct rxrpc_connection *conn;
...
823         while ((conn = list_first_entry_or_null(&local->idle_client_conns,
824                                                 struct
rxrpc_connection, cache_link))) {
825                 list_del_init(&conn->cache_link);
826                 atomic_dec(&conn->active);
827                 trace_rxrpc_client(conn, -1, rxrpc_client_discard);
828                 rxrpc_unbundle_conn(conn);
829                 rxrpc_put_connection(conn, rxrpc_conn_put_local_dead);
830         }
...
833 }

54 static void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local)
55 {
56         struct rxrpc_connection *conn;
57         int id;
58
59         if (!idr_is_empty(&local->conn_ids)) {
60                 idr_for_each_entry(&local->conn_ids, conn, id) {
61                         pr_err("AF_RXRPC: Leaked client conn %p {%d}\n",
62                                conn, refcount_read(&conn->ref));
63                 }
64                 BUG();
65         }
66
67         idr_destroy(&local->conn_ids);
68 }

[88656.300130] rxrpc: AF_RXRPC: Leaked client conn 00000000cf1d5a14 {1}
[88656.300702] ------------[ cut here ]------------
[88656.301099] kernel BUG at net/rxrpc/conn_client.c:64!
[88656.301442] Oops: invalid opcode: 0000 [#17] SMP NOPTI
[88656.301765] CPU: 0 UID: 0 PID: 3989526 Comm: krxrpcio/7001 Tainted:
G      D W           6.18.13-200.fc43.x86_64 #1 PREEMPT(lazy)
[88656.302039] Tainted: [D]=DIE, [W]=WARN
[88656.302323] Hardware name: VMware, Inc. VMware Virtual
Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[88656.302599] RIP: 0010:rxrpc_purge_client_connections+0x58/0xa0 [rxrpc]

Regards,

-- 
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit
  2026-04-01  4:19 [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit Anderson Nascimento
@ 2026-04-22 16:08 ` David Howells
  2026-04-22 16:18   ` Anderson Nascimento
  2026-04-22 16:25   ` Anderson Nascimento
  0 siblings, 2 replies; 6+ messages in thread
From: David Howells @ 2026-04-22 16:08 UTC (permalink / raw)
  To: Anderson Nascimento
  Cc: dhowells, netdev, Marc Dionne, Jakub Kicinski, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-kernel, Jeffrey Altman,
	Simon Horman

Do you by any chance have a reproducer program for this?

David


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit
  2026-04-22 16:08 ` David Howells
@ 2026-04-22 16:18   ` Anderson Nascimento
  2026-04-22 16:25   ` Anderson Nascimento
  1 sibling, 0 replies; 6+ messages in thread
From: Anderson Nascimento @ 2026-04-22 16:18 UTC (permalink / raw)
  To: David Howells
  Cc: netdev, Marc Dionne, Jakub Kicinski, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-kernel, Jeffrey Altman,
	Simon Horman

Hi David,

On Wed, Apr 22, 2026 at 1:08 PM David Howells <dhowells@redhat.com> wrote:
>
> Do you by any chance have a reproducer program for this?

Yes, you can find it below. The code is not polished, but it works.

> David
>

#include <stdio.h>
#include <string.h>
#include <keyutils.h>

struct rxrpc_key_data_v1 {
uint16_t             security_index;
uint16_t             ticket_length;
uint32_t             expiry;
uint32_t             kvno;
uint8_t              session_key[8];
uint8_t              ticket[];
};

#define TICKET_LENGTH 16349

int main(int argc,char *argv[]){
struct rxrpc_key_data_v1 *v1;
key_serial_t key;
char *key_description = "afs@2";
char payload[16384 + 4 + 100];
char ticket[16384 + 4];
char session_key[8];
unsigned int plen;
uint32_t kver = 1;

memset(&payload, '\0', sizeof(payload));
memset(&ticket, '\0', sizeof(ticket));
memset(&session_key, '\0', sizeof(session_key));
memcpy(&payload, &kver, sizeof(kver));

v1 = (struct rxrpc_key_data_v1 *)((char *)&payload + sizeof(kver));

v1->security_index = 2;
v1->ticket_length = TICKET_LENGTH;
v1->kvno = 1;

memcpy(v1->session_key, session_key, sizeof(v1->session_key));
memcpy(v1->ticket, &ticket, TICKET_LENGTH);

plen = sizeof(kver) + sizeof(struct rxrpc_key_data_v1) + TICKET_LENGTH;

key = add_key("rxrpc", key_description, payload, plen,
KEY_SPEC_PROCESS_KEYRING);

keyctl(KEYCTL_READ, key, payload, 4096);

return 0;
}

It generates the following splat.

[  123.636173] ------------[ cut here ]------------
[  123.636176] WARNING: CPU: 2 PID: 1528 at net/rxrpc/key.c:778
rxrpc_read+0x109/0x5c0 [rxrpc]
[  123.636214] Modules linked in: fcrypt pcbc rxrpc ip6_udp_tunnel
krb5 udp_tunnel rfkill nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib
nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct
nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4
nf_tables intel_rapl_msr intel_rapl_common
intel_uncore_frequency_common intel_pmc_core pmt_telemetry
pmt_discovery pmt_class qrtr intel_pmc_ssram_telemetry intel_vsec rapl
vmw_balloon sunrpc vmxnet3 i2c_piix4 i2c_smbus binfmt_misc joydev loop
dm_multipath nfnetlink zram lz4hc_compress lz4_compress
vmw_vsock_vmci_transport vsock vmw_vmci xfs nvme nvme_core
polyval_clmulni ghash_clmulni_intel nvme_keyring vmwgfx nvme_auth hkdf
drm_ttm_helper ata_generic pata_acpi ttm serio_raw scsi_dh_rdac
scsi_dh_emc scsi_dh_alua i2c_dev fuse
[  123.636257] CPU: 2 UID: 1000 PID: 1528 Comm: poc Not tainted
6.18.13-200.fc43.x86_64 #1 PREEMPT(lazy)
[  123.636259] Hardware name: VMware, Inc. VMware Virtual
Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  123.636260] RIP: 0010:rxrpc_read+0x109/0x5c0 [rxrpc]
[  123.636284] Code: 03 66 83 f8 02 0f 85 5e 02 00 00 80 7b 02 00 74
9f f6 05 89 df 2a 00 04 0f 85 87 58 01 00 b8 28 00 00 00 b9 24 00 00
00 eb b1 <0f> 0b 48 c7 c0 fb ff ff ff 48 8b 54 24 40 65 48 2b 15 19 da
ea c3
[  123.636285] RSP: 0018:ffffc9000274bc70 EFLAGS: 00010202
[  123.636287] RAX: ffff8881082e0000 RBX: ffff888104a78e20 RCX: 0000000000000000
[  123.636288] RDX: 0000000000000000 RSI: ffff88810aeac000 RDI: ffff8881037bf1f4
[  123.636289] RBP: 0000000000004004 R08: 0000000000001000 R09: 0000000000000001
[  123.636289] R10: 0000000000000004 R11: ffff88810aeac000 R12: 0000000000000010
[  123.636290] R13: ffff88810aeac000 R14: 0000000000001000 R15: ffff8881023e9f00
[  123.636291] FS:  00007f6f8611d740(0000) GS:ffff8882af726000(0000)
knlGS:0000000000000000
[  123.636293] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  123.636293] CR2: 00007fff0bf73000 CR3: 0000000108146006 CR4: 00000000003706f0
[  123.636312] Call Trace:
[  123.636314]  <TASK>
[  123.636316]  ? keyctl_read_key+0xec/0x230
[  123.636320]  keyctl_read_key+0x131/0x230
[  123.636322]  do_syscall_64+0x7e/0x7f0
[  123.636325]  ? __folio_mod_stat+0x2d/0x90
[  123.636328]  ? set_ptes.isra.0+0x36/0x80
[  123.636329]  ? do_anonymous_page+0x100/0x520
[  123.636332]  ? __handle_mm_fault+0x551/0x6a0
[  123.636334]  ? count_memcg_events+0xd6/0x220
[  123.636337]  ? handle_mm_fault+0x248/0x360
[  123.636339]  ? do_user_addr_fault+0x21a/0x690
[  123.636341]  ? clear_bhb_loop+0x50/0xa0
[  123.636344]  ? clear_bhb_loop+0x50/0xa0
[  123.636345]  ? clear_bhb_loop+0x50/0xa0
[  123.636346]  ? clear_bhb_loop+0x50/0xa0
[  123.636347]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  123.636349] RIP: 0033:0x7f6f8621338d
[  123.636356] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e
fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24
08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 43 5a 0f 00 f7 d8 64 89
01 48
[  123.636357] RSP: 002b:00007fff0bf70528 EFLAGS: 00000246 ORIG_RAX:
00000000000000fa
[  123.636358] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f6f8621338d
[  123.636359] RDX: 00007fff0bf74640 RSI: 000000003809ba43 RDI: 000000000000000b
[  123.636360] RBP: 00007fff0bf70600 R08: 00000000fffffffe R09: 0000003000000008
[  123.636361] R10: 0000000000001000 R11: 0000000000000246 R12: 00007fff0bf787e8
[  123.636362] R13: 0000000000000001 R14: 00007f6f86361000 R15: 0000000000402df0
[  123.636364]  </TASK>
[  123.636365] ---[ end trace 0000000000000000 ]---




--
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit
  2026-04-22 16:08 ` David Howells
  2026-04-22 16:18   ` Anderson Nascimento
@ 2026-04-22 16:25   ` Anderson Nascimento
  2026-04-22 16:37     ` Anderson Nascimento
  1 sibling, 1 reply; 6+ messages in thread
From: Anderson Nascimento @ 2026-04-22 16:25 UTC (permalink / raw)
  To: David Howells
  Cc: netdev, Marc Dionne, Jakub Kicinski, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-kernel, Jeffrey Altman,
	Simon Horman

Hi David,

On Wed, Apr 22, 2026 at 1:08 PM David Howells <dhowells@redhat.com> wrote:
>
> Do you by any chance have a reproducer program for this?
>

Sorry, I mixed things up and ended up sending a different reproducer.
I do have it, I will test it now and send here in a few minutes.

> David
>


-- 
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit
  2026-04-22 16:25   ` Anderson Nascimento
@ 2026-04-22 16:37     ` Anderson Nascimento
  2026-04-23 14:48       ` arjan
  0 siblings, 1 reply; 6+ messages in thread
From: Anderson Nascimento @ 2026-04-22 16:37 UTC (permalink / raw)
  To: David Howells
  Cc: netdev, Marc Dionne, Jakub Kicinski, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-kernel, Jeffrey Altman,
	Simon Horman

On Wed, Apr 22, 2026 at 1:25 PM Anderson Nascimento
<anderson@allelesecurity.com> wrote:
>
> Hi David,
>
> On Wed, Apr 22, 2026 at 1:08 PM David Howells <dhowells@redhat.com> wrote:
> >
> > Do you by any chance have a reproducer program for this?
> >
>
> Sorry, I mixed things up and ended up sending a different reproducer.
> I do have it, I will test it now and send here in a few minutes.

You can find the reproducers below. I run them simultaneously in a
bash while loop on two different SSH shells. I can trigger running
only one server and one client, but when I discovered the bug I was
running 2 servers and 2 clients simultaneously. You can try both, and
here it doesn't take long to trigger it. My virtual machine is
configured to have 4 cores.

while true; do ./server; done
while true; do ./client; done

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/rxrpc.h>
#include <pthread.h>

#define RXRPC_ADD_CHARGE_ACCEPT(control, ctrllen) \
do { \
struct cmsghdr *__cmsg; \
__cmsg = (void *)(control) + (ctrllen); \
__cmsg->cmsg_len = CMSG_LEN(0); \
__cmsg->cmsg_level = SOL_RXRPC; \
__cmsg->cmsg_type = RXRPC_CHARGE_ACCEPT; \
(ctrllen) += __cmsg->cmsg_len; \
\
} while (0)

int sk;

void *__close(void *a){

close(sk);

return NULL;
}

int main(void){
struct sockaddr_rxrpc sockaddr_rxrpc_server;
struct msghdr msg;
struct iovec iov;
char buffer_msg_control[4096];
size_t control_len = 0;
pthread_t th[2];

memset(&sockaddr_rxrpc_server,'\0',sizeof(sockaddr_rxrpc_server));
memset(&buffer_msg_control,'\0',sizeof(buffer_msg_control));
memset(&msg,'\0',sizeof(msg));
memset(&iov,'\0',sizeof(iov));

sk = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);

sockaddr_rxrpc_server.srx_family = AF_RXRPC;
sockaddr_rxrpc_server.srx_service = 1234;
sockaddr_rxrpc_server.transport_type = SOCK_DGRAM;
sockaddr_rxrpc_server.transport_len =
sizeof(sockaddr_rxrpc_server.transport.sin);

sockaddr_rxrpc_server.transport.family = AF_INET;
        sockaddr_rxrpc_server.transport.sin.sin_port = htons(7000);

bind(sk, (struct sockaddr *)&sockaddr_rxrpc_server,
sizeof(sockaddr_rxrpc_server));

listen(sk,10);

RXRPC_ADD_CHARGE_ACCEPT(buffer_msg_control, control_len);

msg.msg_control = buffer_msg_control;
msg.msg_controllen = control_len;

sendmsg(sk, &msg, 0);

pthread_create(&th[0],NULL,&__close,NULL);

pthread_join(th[0],NULL);

return 0;
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/rxrpc.h>

static const unsigned char local_addr[4] = { 127, 0, 0, 1 };

#define RXRPC_ADD_CALLID(control, ctrllen, id) \
do { \
struct cmsghdr *__cmsg; \
__cmsg = (void *)(control) + (ctrllen); \
__cmsg->cmsg_len = CMSG_LEN(sizeof(unsigned long)); \
__cmsg->cmsg_level = SOL_RXRPC; \
__cmsg->cmsg_type = RXRPC_USER_CALL_ID; \
*(unsigned long *)CMSG_DATA(__cmsg) = (id); \
(ctrllen) += __cmsg->cmsg_len; \
\
} while (0)

int main(void){
struct msghdr msg;
struct sockaddr_rxrpc sockaddr_rxrpc_local;
struct sockaddr_rxrpc sockaddr_rxrpc_client;
char buffer_msg_control[4096];
size_t control_len;
int sk;

memset(&sockaddr_rxrpc_local,'\0',sizeof(sockaddr_rxrpc_local));
memset(&sockaddr_rxrpc_client,'\0',sizeof(sockaddr_rxrpc_client));
memset(&buffer_msg_control,'\0',sizeof(buffer_msg_control));
memset(&msg,'\0',sizeof(msg));

sk = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);

sockaddr_rxrpc_local.srx_family = AF_RXRPC;
sockaddr_rxrpc_local.srx_service = 0;
sockaddr_rxrpc_local.transport_type = SOCK_DGRAM;
sockaddr_rxrpc_local.transport_len = sizeof(sockaddr_rxrpc_local.transport.sin);

sockaddr_rxrpc_local.transport.family = AF_INET;
sockaddr_rxrpc_local.transport.sin.sin_port = htons(7001);

memcpy(&sockaddr_rxrpc_local.transport.sin.sin_addr, &local_addr, 4);

bind(sk, (struct sockaddr *)&sockaddr_rxrpc_local,
sizeof(sockaddr_rxrpc_local));

sockaddr_rxrpc_client.srx_family = AF_RXRPC;
sockaddr_rxrpc_client.srx_service = 1234;
sockaddr_rxrpc_client.transport_type = SOCK_DGRAM;
sockaddr_rxrpc_client.transport_len =
sizeof(sockaddr_rxrpc_client.transport.sin);
sockaddr_rxrpc_client.transport.family = AF_INET;
sockaddr_rxrpc_client.transport.sin.sin_port = htons(7000);

memcpy(&sockaddr_rxrpc_client.transport.sin.sin_addr, &local_addr, 4);

connect(sk, (struct sockaddr *)&sockaddr_rxrpc_client,
sizeof(sockaddr_rxrpc_client));

control_len = 0;
RXRPC_ADD_CALLID(buffer_msg_control, control_len, 0x1234);

msg.msg_control = buffer_msg_control;
msg.msg_controllen = control_len;

sendmsg(sk, &msg, 0);

return 0;
}

The report I have just triggered.

[  473.601077] rxrpc: AF_RXRPC: Leaked client conn 00000000bf02a6a7 {1}
[  473.601115] ------------[ cut here ]------------
[  473.601117] kernel BUG at net/rxrpc/conn_client.c:64!
[  473.601169] Oops: invalid opcode: 0000 [#1] SMP NOPTI
[  473.601180] CPU: 0 UID: 0 PID: 1107239 Comm: krxrpcio/7001 Not
tainted 6.18.13-200.fc43.x86_64 #1 PREEMPT(lazy)
[  473.601193] Hardware name: VMware, Inc. VMware Virtual
Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  473.601205] RIP: 0010:rxrpc_purge_client_connections+0x58/0xa0 [rxrpc]
[  473.601261] Code: 28 01 00 00 00 74 25 31 c0 48 8d 74 24 0c 48 89
cf 89 44 24 0c 48 89 0c 24 e8 d4 ec c2 c1 48 89 c6 48 85 c0 0f 85 49
dd 01 00 <0f> 0b 31 f6 48 89 cf 48 89 0c 24 e8 c8 aa c4 c1 48 8b 0c 24
85 c0
[  473.601280] RSP: 0018:ffffc900159cfdd8 EFLAGS: 00010246
[  473.601288] RAX: 0000000000000000 RBX: ffff88810a6b4800 RCX: 0000000000000000
[  473.601297] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88810a6b4920
[  473.601305] RBP: ffff888123398000 R08: ffffc900159cfdb8 R09: ffff88810a6b4928
[  473.601313] R10: 0000000000000018 R11: 0000000040000000 R12: ffff88810a9cda00
[  473.601322] R13: ffff88810a6b4800 R14: ffffc900159cfe70 R15: ffff88812d0c2800
[  473.601330] FS:  0000000000000000(0000) GS:ffff8882af626000(0000)
knlGS:0000000000000000
[  473.601339] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  473.601347] CR2: 00007faf20630030 CR3: 000000000382e002 CR4: 00000000003706f0
[  473.601380] Call Trace:
[  473.601387]  <TASK>
[  473.601393]  rxrpc_destroy_local+0xc9/0xe0 [rxrpc]
[  473.601443]  rxrpc_io_thread+0x65d/0x750 [rxrpc]
[  473.601487]  ? __pfx_rxrpc_io_thread+0x10/0x10 [rxrpc]
[  473.601527]  kthread+0xfc/0x240
[  473.601536]  ? __pfx_kthread+0x10/0x10
[  473.601542]  ret_from_fork+0xf4/0x110
[  473.601550]  ? __pfx_kthread+0x10/0x10
[  473.601558]  ret_from_fork_asm+0x1a/0x30
[  473.601574]  </TASK>
[  473.601578] Modules linked in: vsock_diag fcrypt pcbc rxrpc
ip6_udp_tunnel krb5 udp_tunnel rfkill nft_fib_inet nft_fib_ipv4
nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6
nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6
nf_defrag_ipv4 nf_tables intel_rapl_msr intel_rapl_common
intel_uncore_frequency_common intel_pmc_core pmt_telemetry
pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec rapl
vmw_balloon sunrpc qrtr vmxnet3 i2c_piix4 i2c_smbus binfmt_misc joydev
loop dm_multipath nfnetlink zram lz4hc_compress lz4_compress
vmw_vsock_vmci_transport vsock vmw_vmci xfs nvme nvme_core
nvme_keyring polyval_clmulni ghash_clmulni_intel nvme_auth vmwgfx hkdf
drm_ttm_helper ata_generic ttm pata_acpi serio_raw scsi_dh_rdac
scsi_dh_emc scsi_dh_alua i2c_dev fuse
[  473.601690] ---[ end trace 0000000000000000 ]---
[  473.601698] RIP: 0010:rxrpc_purge_client_connections+0x58/0xa0 [rxrpc]
[  473.601794] Code: 28 01 00 00 00 74 25 31 c0 48 8d 74 24 0c 48 89
cf 89 44 24 0c 48 89 0c 24 e8 d4 ec c2 c1 48 89 c6 48 85 c0 0f 85 49
dd 01 00 <0f> 0b 31 f6 48 89 cf 48 89 0c 24 e8 c8 aa c4 c1 48 8b 0c 24
85 c0
[  473.601813] RSP: 0018:ffffc900159cfdd8 EFLAGS: 00010246
[  473.601820] RAX: 0000000000000000 RBX: ffff88810a6b4800 RCX: 0000000000000000
[  473.601829] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88810a6b4920
[  473.601837] RBP: ffff888123398000 R08: ffffc900159cfdb8 R09: ffff88810a6b4928
[  473.601845] R10: 0000000000000018 R11: 0000000040000000 R12: ffff88810a9cda00
[  473.602211] R13: ffff88810a6b4800 R14: ffffc900159cfe70 R15: ffff88812d0c2800
[  473.602599] FS:  0000000000000000(0000) GS:ffff8882af626000(0000)
knlGS:0000000000000000
[  473.603301] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  473.604869] CR2: 00007faf20630030 CR3: 000000000382e002 CR4: 00000000003706f0

Best regards,
-- 
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit
  2026-04-22 16:37     ` Anderson Nascimento
@ 2026-04-23 14:48       ` arjan
  0 siblings, 0 replies; 6+ messages in thread
From: arjan @ 2026-04-23 14:48 UTC (permalink / raw)
  To: netdev
  Cc: anderson, dhowells, marc.dionne, kuba, pabeni, linux-kernel,
	jaltman, horms, Arjan van de Ven

From: Arjan van de Ven <arjan@linux.intel.com>

This email is created by automation to help kernel developers deal
with a large volume of AI generated bug reports by decoding oopses
into more actionable information.


Decoded Backtrace

--- rxrpc_destroy_client_conn_ids (inlined into rxrpc_purge_client_connections)
    Source: net/rxrpc/conn_client.c

 54 static void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local)
 55 {
 56     struct rxrpc_connection *conn;
 57     int id;
 58
 59     if (!idr_is_empty(&local->conn_ids)) {
 60         idr_for_each_entry(&local->conn_ids, conn, id) {
 61             pr_err("AF_RXRPC: Leaked client conn %p {%d}\n",
 62                    conn, refcount_read(&conn->ref));
 63         }
 64         BUG();   // <- crash here
 65     }
 66
 67     idr_destroy(&local->conn_ids);
 68 }

--- rxrpc_destroy_local
    Source: net/rxrpc/local_object.c

420 void rxrpc_destroy_local(struct rxrpc_local *local)
421 {
422     struct socket *socket = local->socket;
423     struct rxrpc_net *rxnet = local->rxnet;
    ...
427     local->dead = true;
    ...
433     rxrpc_clean_up_local_conns(local);
434     rxrpc_service_connection_reaper(&rxnet->service_conn_reaper);
435     ASSERT(!local->service);
    ...
450     rxrpc_purge_queue(&local->rx_queue);
451     rxrpc_purge_client_connections(local);   // <- call here
452     page_frag_cache_drain(&local->tx_alloc);
453 }

--- rxrpc_io_thread
    Source: net/rxrpc/io_thread.c

554     if (!list_empty(&local->new_client_calls))
555         rxrpc_connect_client_calls(local);
    ...
569     if (should_stop)
570         break;
    ...
596     __set_current_state(TASK_RUNNING);
598     rxrpc_destroy_local(local);   // <- call here
601     return 0;


Tentative Analysis

The crash fires the unconditional BUG() at net/rxrpc/conn_client.c:64
because local->conn_ids is non-empty when rxrpc_destroy_local() is
called by the krxrpcio I/O thread during socket teardown.

When a client sendmsg() queues a call, the I/O thread picks it up via
rxrpc_connect_client_calls(). That function allocates a client
connection (rxrpc_alloc_client_connection()), registers it in the
local->conn_ids IDR with refcount=1, stores it in bundle->conns[], and
moves the call from new_client_calls to bundle->waiting_calls.

Once new_client_calls is empty and kthread_should_stop() is true, the
I/O thread exits its loop and calls rxrpc_destroy_local(). Inside that
function, rxrpc_clean_up_local_conns() iterates only the
local->idle_client_conns list. A connection that is in bundle->conns[]
but has never been activated on a channel (and thus never went idle) is
completely missed. rxrpc_purge_client_connections() then finds the
connection still registered in conn_ids and fires BUG().

The coverage gap was introduced by commit 9d35d880e0e4 ("rxrpc: Move
client call connection to the I/O thread"), which created a new
"allocated in bundle, not yet idle" state for connections that the
existing idle-list cleanup does not handle.

Note: fc9de52de38f ("rxrpc: Fix missing locking causing hanging calls"),
already present in 6.18.13, fixes a related missing-lock bug in the
same code area but does not address this idle-list coverage gap.


Potential Solution

rxrpc_clean_up_local_conns() should be extended to also release
connections stored in bundle->conns[] that have not yet appeared on
idle_client_conns. After the existing idle-list loop, the function
should iterate over all entries in local->client_bundles (the RB-tree
of active bundles), call rxrpc_unbundle_conn() on each occupied
bundle->conns[] slot, and put the connection. This ensures
rxrpc_destroy_client_conn_ids() always finds an empty IDR.


More information

Oops-Analysis: http://oops.fenrus.org/reports/lkml/CAPhRvkyZGKHRTBhV3P2PCCRxmRKGEvJQ0W5a9SMW3qwS2hp2Qw/
Assisted-by: GitHub-Copilot:claude-sonnet-4.6 linux-kernel-oops-x86.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-23 14:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-01  4:19 [BUG] rxrpc: Client connection leak and BUG() call during kernel IO thread exit Anderson Nascimento
2026-04-22 16:08 ` David Howells
2026-04-22 16:18   ` Anderson Nascimento
2026-04-22 16:25   ` Anderson Nascimento
2026-04-22 16:37     ` Anderson Nascimento
2026-04-23 14:48       ` arjan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox