Re: [PATCH v2] serial: 8250: fix use-after-free in IRQ chain handling
From: 王曌龙
Date: Thu May 28 2026 - 22:08:44 EST
Hi Qiliang
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221579
This patch does not fix the reported issue.
I tested it with the Bugzilla reproducer, and the "Unbalanced enable for IRQ"
warning is still reproducible.
```
chmod +x /tmp/run-tty-open-race.sh
/tmp/run-tty-open-race.sh
racing simultaneous open/close on /dev/ttyS1 and /dev/ttyS3, 100000 iterations
[ 61.937561][ T915] ------------[ cut here ]------------
[ 61.938276][ T915] Unbalanced enable for IRQ 3
[ 61.938828][ T915] WARNING: kernel/irq/manage.c:774 at __enable_irq+0x33/0x60, CPU#1: tty-open-race/915
[ 61.939978][ T915] Modules linked in: af_packet(E) kvm_amd(E) nfnetlink(E) ahci(E) libahci(E) libata(E) lpc_ich(E) virtio_net(E) net_failover(E) failover(E) sunrpc(E) dm_mod(E) raid1(E) binfmt_misc(E) md_mod(E) 9p(E) 9pnet_virtio(E) 9pnet(E) ext4(E) netfs(E) virtio_scsi(E) scsi_mod(E) crc16(E) mbcache(E) jbd2(E) virtio_blk(E) scsi_common(E) virtiofs(E) fuse(E) vmw_vsock_virtio_transport(E) vmw_vsock_virtio_transport_common(E) vsock(E)
[ 61.944542][ T915] CPU: 1 UID: 0 PID: 915 Comm: tty-open-race Tainted: G E 7.1.0-rc5-trim+ #14 PREEMPT(full) 43dd8c1eb10e193a5538796ee5a4e7f9cf3e86f3
[ 61.946304][ T915] Tainted: [E]=UNSIGNED_MODULE
[ 61.946866][ T915] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Arch Linux 1.17.0-2-2 04/01/2014
[ 61.948045][ T915] RIP: 0010:__enable_irq+0x39/0x60
[ 61.948650][ T915] Code: 85 c0 74 19 83 f8 01 74 0e 83 e8 01 89 87 80 00 00 00 e9 d5 52 c8 ff f6 47 7d 08 74 17 48 8d 05 ed 01 2c 02 8b 77 2c 48 89 c7 <67> 48 0f b9 3a e9 b8 52 c8 ff 81 4f 78 00 04 00 00 ba 01 00 00 00
[ 61.950925][ T915] RSP: 0018:ffffc90000f67858 EFLAGS: 00010046
[ 61.951634][ T915] RAX: ffffffff8373f030 RBX: 0000000000000001 RCX: ffff888108912380
[ 61.952574][ T915] RDX: 0000000000000001 RSI: 0000000000000003 RDI: ffffffff8373f030
[ 61.953508][ T915] RBP: 0000000000000003 R08: ffff888108912300 R09: 0000000000000001
[ 61.954438][ T915] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246
[ 61.955367][ T915] R13: ffff8881242ef000 R14: 0000000000000001 R15: 0000000000000002
[ 61.956309][ T915] FS: 00007fba5a6106c0(0000) GS:ffff8881eec34000(0000) knlGS:0000000000000000
[ 61.957351][ T915] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 61.958122][ T915] CR2: 000000001d2b1258 CR3: 000000010e5cf000 CR4: 0000000000750ef0
[ 61.959056][ T915] PKRU: 55555554
[ 61.959501][ T915] Call Trace:
[ 61.959913][ T915] <TASK>
[ 61.960262][ T915] enable_irq+0x7e/0x100
[ 61.960769][ T915] serial8250_do_startup+0x7ce/0xa80
[ 61.961395][ T915] uart_port_startup+0x13d/0x440
[ 61.961981][ T915] uart_port_activate+0x5b/0xb0
[ 61.962551][ T915] tty_port_open+0x90/0x110
[ 61.963089][ T915] ? srso_alias_return_thunk+0x5/0xfbef5
[ 61.963747][ T915] uart_open+0x1e/0x30
```
The problem is that the first-port path still drops hash_mutex before
request_irq() completes:
i->head = &up->list;
mutex_unlock(&hash_mutex);
request_irq(..., i);
After i->head is published, another port sharing the IRQ can still join the
chain and run the shared-IRQ THRE test while the IRQ core is starting the
interrupt for the first port.
So the lock has to cover the first request_irq() completion. Covering only
the i->head check and list_add() is not sufficient.
Test result: still fails with the Bugzilla reproducer.
Thanks,
Wang Zhaolong