libertas_tf: same use-after-free as the recent lbs_free_adapter() fix?
From: Maoyi Xie
Date: Mon Jun 15 2026 - 10:41:39 EST
Hi all,
Commit 03cc8f90d053 ("wifi: libertas: fix use-after-free in lbs_free_adapter()")
recently switched timer_delete() to timer_delete_sync() in the libertas driver. I
think the libertas_tf driver has the same problem in lbtf_free_adapter(), and it was
not changed. I am not sure, so I would appreciate it if you could let me know whether
you agree.
lbtf_free_adapter() in drivers/net/wireless/marvell/libertas_tf/main.c does:
lbtf_free_cmd_buffer(priv);
timer_delete(&priv->command_timer);
timer_delete() does not wait for a running command_timer_fn() callback.
lbtf_free_adapter() is called on the teardown path right before priv is freed. In
lbtf_remove_card() it is followed by ieee80211_free_hw(hw), which frees priv
(priv == hw->priv); the probe error path does the same.
command_timer is armed by mod_timer(&priv->command_timer, ...) in
lbtf_submit_command() whenever a firmware command is sent. command_timer_fn() then
dereferences priv: it takes priv->driver_lock, reads priv->cur_cmd, sets
priv->cmd_timed_out and queues priv->cmd_work. So if a command times out as the
device is removed, command_timer_fn() can run while teardown frees priv, and it
reads freed memory.
This is the same shape as the lbs fix above. The smallest fix is to mirror it:
- timer_delete(&priv->command_timer);
+ timer_delete_sync(&priv->command_timer);
in lbtf_free_adapter(). That covers both teardown paths, since both call
lbtf_free_adapter() before the free. There is also a redundant
timer_delete(&priv->command_timer) in lbtf_remove_card() just before
lbtf_free_adapter(); it could be made _sync too, or dropped.
Does this look like a real issue? I do not have the hardware, so I cannot drive the
real removal path. I did confirm the use-after-free under KASAN with a small self test
that forces the same race: the timer callback reads priv->driver_lock after
timer_delete() and the free, and KASAN reports a slab-use-after-free. With
timer_delete_sync() it is clean. I wanted to ask before sending a patch. I am happy to
send one once you confirm.
Thanks,
Maoyi
https://maoyixie.com/