[lvc-project] [PATCH] media: rc: Fix use-after-free when racing vfd_write() with disconnect
Fedor Pchelkin
pchelkin at ispras.ru
Fri Jul 25 22:52:40 MSK 2025
On Thu, 24. Jul 16:15, Sergey Larshin wrote:
> > Жизненный цикл ictx контролируется с помощью счётчика ссылок &ictx->users.
> > Если счётчик в imon_disconnect() становится равным нулю после декремента,
> > то объект освобождается.
>
> Cпасибо за материалы, изучив логику ictx->users, пришёл к выводу, что проблема не во
> всём ctx — он защищён корректно. Однако два его поля — usbdev_intf0 и
> usbdev_intf1 — не защищены. При disconnect() они уменьшается счётчик
> ссылок на устройство в зависимости от номера интерфейса.
>
> В imon_probe в зависимости от номера интерфейса вызываются функции
> imon_init_intf0 или imon_init_intf1, каждая из которых увеличивает
> счётчик ссылок на usb_device на один.
>
> В imon_disconnect счётчик уменьшается на один, независимо от
> ictx->users, что приводит к освобождению usbdev_intf0 или
> usbdev_intf1 через вызов usb_put_dev(). В то время как vfd_write
> продолжает работу.
>
> Решений может быть несколько:
> - Делать usb_put_dev, когда отчищаем icxt (падение не воспроизвелось
> в течении 40 минут)
> if (refcount_dec_and_test(&ictx->users)) {
> if (ictx->usbdev_intf0)
> usb_put_dev(ictx->usbdev_intf0);
> if (ictx->usbdev_intf1)
> usb_put_dev(ictx->usbdev_intf1);
> free_imon_context(ictx);
> }
> - Сделать lock в disconnect()
IMHO взятие лока при выставлении флага в disconnect и занесение проверки
этого флага под тот же мьютекс в lcd_write()/vfd_write() решает проблему
достаточно понятным образом, ведь эти функции берут мьютекс на всё время
своего выполнения.
(и я правда не понимаю возни с smp_load_acquire и прочими усложнениями,
если всё равно предложенный патч сейчас делает странный хак с взятием и
моментальным снятием мьютекса в disconnect)
Нужно только подумать о том, что происходит в display_open().
More information about the lvc-project
mailing list