mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 04:23:35 +02:00
syzkaller reported use-after-free in load_firmware_cb() [1].
The reason is because the module allocated a struct tuner in tuner_probe(),
and then the module initialization failed, the struct tuner was released.
A worker which created during module initialization accesses this struct
tuner later, it caused use-after-free.
The process is as follows:
task-6504 worker_thread
tuner_probe <= alloc dvb_frontend [2]
...
request_firmware_nowait <= create a worker
...
tuner_remove <= free dvb_frontend
...
request_firmware_work_func <= the firmware is ready
load_firmware_cb <= but now the dvb_frontend has been freed
To fix the issue, check the dvd_frontend in load_firmware_cb(), if it is
null, report a warning and just return.
[1]:
==================================================================
BUG: KASAN: use-after-free in load_firmware_cb+0x1310/0x17a0
Read of size 8 at addr ffff8000d7ca2308 by task kworker/2:3/6504
Call trace:
load_firmware_cb+0x1310/0x17a0
request_firmware_work_func+0x128/0x220
process_one_work+0x770/0x1824
worker_thread+0x488/0xea0
kthread+0x300/0x430
ret_from_fork+0x10/0x20
Allocated by task 6504:
kzalloc
tuner_probe+0xb0/0x1430
i2c_device_probe+0x92c/0xaf0
really_probe+0x678/0xcd0
driver_probe_device+0x280/0x370
__device_attach_driver+0x220/0x330
bus_for_each_drv+0x134/0x1c0
__device_attach+0x1f4/0x410
device_initial_probe+0x20/0x30
bus_probe_device+0x184/0x200
device_add+0x924/0x12c0
device_register+0x24/0x30
i2c_new_device+0x4e0/0xc44
v4l2_i2c_new_subdev_board+0xbc/0x290
v4l2_i2c_new_subdev+0xc8/0x104
em28xx_v4l2_init+0x1dd0/0x3770
Freed by task 6504:
kfree+0x238/0x4e4
tuner_remove+0x144/0x1c0
i2c_device_remove+0xc8/0x290
__device_release_driver+0x314/0x5fc
device_release_driver+0x30/0x44
bus_remove_device+0x244/0x490
device_del+0x350/0x900
device_unregister+0x28/0xd0
i2c_unregister_device+0x174/0x1d0
v4l2_device_unregister+0x224/0x380
em28xx_v4l2_init+0x1d90/0x3770
The buggy address belongs to the object at ffff8000d7ca2000
which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 776 bytes inside of
2048-byte region [ffff8000d7ca2000, ffff8000d7ca2800)
The buggy address belongs to the page:
page:ffff7fe00035f280 count:1 mapcount:0 mapping:ffff8000c001f000 index:0x0
flags: 0x7ff800000000100(slab)
raw: 07ff800000000100 ffff7fe00049d880 0000000300000003 ffff8000c001f000
raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8000d7ca2200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8000d7ca2280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff8000d7ca2300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8000d7ca2380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8000d7ca2400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
[2]
Actually, it is allocated for struct tuner, and dvb_frontend is inside.
Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||
|---|---|---|
| .. | ||
| e4000_priv.h | ||
| e4000.c | ||
| e4000.h | ||
| fc001x-common.h | ||
| fc0011.c | ||
| fc0011.h | ||
| fc0012-priv.h | ||
| fc0012.c | ||
| fc0012.h | ||
| fc0013-priv.h | ||
| fc0013.c | ||
| fc0013.h | ||
| fc2580_priv.h | ||
| fc2580.c | ||
| fc2580.h | ||
| it913x.c | ||
| it913x.h | ||
| Kconfig | ||
| m88rs6000t.c | ||
| m88rs6000t.h | ||
| Makefile | ||
| max2165_priv.h | ||
| max2165.c | ||
| max2165.h | ||
| mc44s803_priv.h | ||
| mc44s803.c | ||
| mc44s803.h | ||
| msi001.c | ||
| mt20xx.c | ||
| mt20xx.h | ||
| mt2060_priv.h | ||
| mt2060.c | ||
| mt2060.h | ||
| mt2063.c | ||
| mt2063.h | ||
| mt2131_priv.h | ||
| mt2131.c | ||
| mt2131.h | ||
| mt2266.c | ||
| mt2266.h | ||
| mxl301rf.c | ||
| mxl301rf.h | ||
| mxl5005s.c | ||
| mxl5005s.h | ||
| mxl5007t.c | ||
| mxl5007t.h | ||
| qm1d1b0004.c | ||
| qm1d1b0004.h | ||
| qm1d1c0042.c | ||
| qm1d1c0042.h | ||
| qt1010_priv.h | ||
| qt1010.c | ||
| qt1010.h | ||
| r820t.c | ||
| r820t.h | ||
| si2157_priv.h | ||
| si2157.c | ||
| si2157.h | ||
| tda827x.c | ||
| tda827x.h | ||
| tda8290.c | ||
| tda8290.h | ||
| tda9887.c | ||
| tda9887.h | ||
| tda18212.c | ||
| tda18212.h | ||
| tda18218_priv.h | ||
| tda18218.c | ||
| tda18218.h | ||
| tda18250_priv.h | ||
| tda18250.c | ||
| tda18250.h | ||
| tda18271-common.c | ||
| tda18271-fe.c | ||
| tda18271-maps.c | ||
| tda18271-priv.h | ||
| tda18271.h | ||
| tea5761.c | ||
| tea5761.h | ||
| tea5767.c | ||
| tea5767.h | ||
| tua9001_priv.h | ||
| tua9001.c | ||
| tua9001.h | ||
| tuner-i2c.h | ||
| tuner-simple.c | ||
| tuner-simple.h | ||
| tuner-types.c | ||
| xc2028-types.h | ||
| xc2028.c | ||
| xc2028.h | ||
| xc4000.c | ||
| xc4000.h | ||
| xc5000.c | ||
| xc5000.h | ||