Re: [PATCH] ipmi: ssif_bmc: keep device alive across remove

From: Chad Aldreda

Date: Mon Nov 09 2026 - 10:10:14 EST


On Wed, 5 Aug 2026, Qing Ming wrote:
> Allocate ssif_bmc_ctx explicitly and hold a reference for each successful
> open. Mark the device dead before deregistering the miscdevice, wake
> blocked operations, report a hangup to poll, and make empty reads and new
> writes return -ENODEV after removal.

Tested on mainline d48723711bae (v7.4-rc1-672), where this still applies,
in QEMU with KASAN, lockdep, kmemleak and DEBUG_OBJECTS_TIMERS. There is
no SSIF hardware involved: a test-only I2C adapter module with target
support binds the driver, sends single-part write requests and reads
back the responses the way a host would.

Without the patch, sysfs unbind, delete_device or removing the adapter
with /dev/ipmi-ssif-host open gives slab-use-after-free reports in
ssif_bmc_poll(), ssif_bmc_read(), ssif_bmc_write() and
ssif_bmc_release(). A read(), poll() or write() blocked across the
removal is not woken, and hits freed memory when it is signalled.

With the patch there are no KASAN, lockdep or kmemleak reports. After
each of the three removals, poll() returns POLLERR|POLLHUP, and read()
and write() return -ENODEV. Operations blocked across each removal wake
up: read(), and a write() blocked behind an unsent response, return
-ENODEV, and poll() returns POLLERR|POLLHUP.

Normal use still works: a second open gets -EBUSY, a blocking read() and
poll() are woken by a new request, the request arrives intact, and the
host reads back a response of the length written to the node (the stub
checks the length, not the bytes). These also ran clean:
an unbind with the response timer armed, an unbind and bind with the old
file still open (the old file gets -ENODEV and the new one works),
closing with an unread request, probe failures from target registration
and from misc_register(), and 200 unbind/bind cycles against six
processes opening, polling, reading and writing while requests are sent
and responses read. The same stress run on the unpatched kernel produces
KASAN reports.

Separate from this patch, and the same with or without it: removing the
device before any request has arrived gives a debugobjects WARN,
"ODEBUG: assert_init not available ... object type: timer_list".
remove() calls timer_delete_sync() on response_timer, which is only
set up in handle_request(); the call came in with 7fc3e2546cf3 ("ipmi:
ssif_bmc: cancel response timer on remove"). There is no KASAN report.
>From reading the code, setting the timer up in probe would avoid it; I
have not tried that.

Not tested: real hardware (the stub delivers target events from
process context, not an interrupt), multi-part requests and responses,
PEC, epoll, the driver's KUnit tests, and module unload (the driver was
built in). The stress run used non-blocking file operations only.

The harness and this report were produced with an AI assistant (Claude
Opus 5.5), which also did the earlier runs, including the unpatched
comparison. I ran the final version on the patched kernel myself and
got the same results. The harness is available on request.

Tested-by: Chad Aldreda <ca@xxxxxxxxxxxxxx>