
CVE-2022-41218에 대한 취약점 세부 정보
이 취약점은 drivers/media/dvb-core/dmxdev.c에서 발생하는 경쟁 조건 취약점입니다. 따라서 이 dmxdev를 사용하는 usb 장치 드라이버에서 경쟁 조건이 발생할 수 있습니다.
이 취약점은 3개의 UAF를 트리거하는 데 사용될 수 있습니다.
먼저, 익스플로잇 순서는 다음과 같습니다(drivers/media/usb/ttusb-dec/ttusb_dec.c를 사용하여 디버깅했습니다):```
cpu0 cpu1 cpu 2
1. dvb_dvr_open()
2. ttusb_dec_disconnect()
ttusb_dec_exit_dvb()
dvb_dmxdev_release()
wait_event(dmxdev->dvr_dvbdev->wait_queue, …)
3. dvb_demux_open()
dvb_demux_ioctl()
dvb_usercopy()
copy_from_user() <- userfaultfd stuck
4. dvb_dvr_release()
5. vfree(dmxdev->filter)
6. copy_from_user() <- userfaultfd release
dvb_demux_do_ioctl()
struct dmxdev *dmxdev = dmxdevfilter->dev; <- UAF!!
상세한 익스플로잇 흐름은 다음과 같습니다:
1. 디바이스 노드 중 dvr0에 대해 open()을 호출합니다. 이는 dvb_dvr_open()을 호출하여 `dvbdev->users++`가 실행되도록 합니다.
이 경우, usb 디바이스를 제거하여 ttusb_dec_disconnect()가 실행되면 `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)` 조건이 포착됩니다.
2. USB 디바이스를 물리적으로 제거합니다.
이 경우, ttusb_dec_disconnect() 함수가 실행되는 동안 `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`에서 대기합니다.
3. demux0 노드에 대해 open()을 호출하여 dvb_demux_open() 함수가 호출되도록 합니다.
이 함수도 단계 1의 dvb_dvr_open() 함수와 유사하게 `dvbdev->users++`를 실행합니다.
그러나 현재 대기 중인 dvb_dmxdev_release() 함수가 이미 `dvbdev->users`에 대한 검사를 통과했기 때문에 잘못된 참조 카운팅이 발생합니다:```
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
dmxdev->exit = 1;
if (dmxdev->dvbdev->users > 1) { // This check is bypassed. improper reference counting.
wait_event(dmxdev->dvbdev->wait_queue,
dmxdev->dvbdev->users == 1);
}
if (dmxdev->dvr_dvbdev->users > 1) {
wait_event(dmxdev->dvr_dvbdev->wait_queue, // Currently wait()ing here.
dmxdev->dvr_dvbdev->users == 1);
}
dvb_unregister_device(dmxdev->dvbdev);
dvb_unregister_device(dmxdev->dvr_dvbdev);
vfree(dmxdev->filter);
dmxdev->filter = NULL;
dmxdev->demux->close(dmxdev->demux);
}
그런 다음 demux0에서 ioctl()을 호출합니다. 호출 시, 세 번째 인자는 userfaultfd(또는 FUSE fs)에 의해 설정된 사용자 공간 주소를 제출합니다. 이제 ioctl이 실행되는 동안 dvb_usercopy()의 copy_from_user()에서 멈추게 됩니다:``` int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, int (*func)(struct file *file, unsigned int cmd, void *arg)) { char sbuf[128]; void *mbuf = NULL; void *parg = NULL; int err = -EINVAL;
/* Copy arguments into temp kernel buffer */
switch (_IOC_DIR(cmd)) {
case _IOC_NONE:
/*
* For this command, the pointer is actually an integer
* argument.
*/
parg = (void *) arg;
break;
case _IOC_READ: /* some v4l ioctls are marked wrong ... */
case _IOC_WRITE:
case (_IOC_WRITE | _IOC_READ):
if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
parg = sbuf;
} else {
/* too big to allocate from stack */
mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
if (NULL == mbuf)
return -ENOMEM;
parg = mbuf;
}
err = -EFAULT;
if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) // here
goto out;
break;
}
4. dvr0 노드를 open()한 스레드에서 fd를 close()합니다.
그러면 dvb_dvr_release()가 호출되고, `dvbdev->users--`와 `wake_up(&dvbdev->wait_queue)`가 실행되어 .disconnect 흐름인 dvb_dmxdev_release() 함수를 깨웁니다.
5. .disconnect 흐름에서 dvb_dmxdev_release() 함수는 `vfree(dmxdev->filter)`를 실행합니다.
6. userfaultfd를 설정한 demux0 ioctl 스레드에서 userfaultfd를 해제합니다.
이로 인해 .disconnect에서 방금 해제한 `dmxdev->filter` 주소를 읽어 UAF가 발생합니다.
이제 UAF는 dvb_demux_do_ioctl()의 모든 경우에 사용될 수 있으며, eBPF와 연결하면 LPE도 가능합니다.
커널 로그는 다음과 같습니다:
[ 155.774326] BUG: unable to handle page fault for address: ffff888105f8c000
[ 155.774331] #PF: supervisor read access in kernel mode
[ 155.774333] #PF: error_code(0x0000) - not-present page
[ 83.990720] BUG: unable to handle page fault for address: ffffc900013c5060
[ 83.990733] #PF: supervisor read access in kernel mode
[ 83.990739] #PF: error_code(0x0000) - not-present page
[ 83.990744] PGD 100000067 P4D 100000067 PUD 1001dd067 PMD 1078fc067 PTE 0
[ 83.990760] Oops: 0000 [#1] PREEMPT SMP NOPTI
[ 83.990768] CPU: 2 PID: 2580 Comm: exploit Not tainted 6.0.0-rc2+ #3
[ 83.990776] Hardware name: Gigabyte Technology Co., Ltd. B460MDS3H/B460M DS3H, BIOS F3 05/27/2020
[ 83.990781] RIP: 0010:dvb_demux_do_ioctl+0x22/0x5b0 [dvb_core]
[ 83.990809] Code: 00 00 00 00 0f 1f 40 00 0f 1f 44 00 00 55 48 89 e5 41 57 49 89 d7 41 56 41 55 41 54 53 89 f3 48 84
[ 83.990816] RSP: 0018:ffffc90001a3fd10 EFLAGS: 00010282
[ 83.990824] RAX: 0000000000000000 RBX: 00000000403c6f2b RCX: ffffffffc051c520
[ 83.990830] RDX: ffffc90001a3fd80 RSI: 00000000403c6f2b RDI: ffff88810c4adc00
[ 83.990835] RBP: ffffc90001a3fd58 R08: 0000000000000000 R09: 0000000000000000
[ 83.990840] R10: 0000000000000000 R11: 0000000000000000 R12: 00000000fffffff2
[ 83.990845] R13: ffffc900013c5000 R14: ffff88810c4adc00 R15: ffffc90001a3fd80
[ 83.990850] FS: 00007f0c4fdd7640(0000) GS:ffff88844ea80000(0000) knlGS:0000000000000000
[ 83.990857] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 83.990863] CR2: ffffc900013c5060 CR3: 000000010b31e001 CR4: 00000000007706e0
[ 83.990869] PKRU: 55555554
[ 83.990873] Call Trace:
[ 83.990877] <TASK>
[ 83.990886] dvb_usercopy+0x55/0x1a0 [dvb_core]
[ 83.990907] ? dvb_dmxdev_filter_start+0x3b0/0x3b0 [dvb_core]
[ 83.990932] dvb_demux_ioctl+0x15/0x20 [dvb_core]
[ 83.990951] __x64_sys_ioctl+0x92/0xd0
[ 83.990965] do_syscall_64+0x59/0x90
[ 83.990973] ? debug_smp_processor_id+0x17/0x20
[ 83.990984] ? fpregs_assert_state_consistent+0x2a/0x50
[ 83.990995] ? exit_to_user_mode_prepare+0x49/0x1a0
[ 83.991007] ? syscall_exit_to_user_mode+0x26/0x50
[ 83.991016] ? __x64_sys_write+0x19/0x20
[ 83.991024] ? do_syscall_64+0x69/0x90
[ 83.991030] ? irqentry_exit_to_user_mode+0x9/0x20
[ 83.991039] ? irqentry_exit+0x3b/0x50
[ 83.991048] ? exc_page_fault+0x87/0x180
[ 83.991056] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[ 83.991068] RIP: 0033:0x454b7f
[ 83.991075] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 40
[ 83.991081] RSP: 002b:00007f0c4fdd7150 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 83.991090] RAX: ffffffffffffffda RBX: 00007f0c4fdd7640 RCX: 0000000000454b7f
[ 83.991095] RDX: 00007f0c50dda000 RSI: 00000000403c6f2b RDI: 0000000000000005
[ 83.991100] RBP: 00007f0c4fdd71d0 R08: 0000000000000000 R09: 0000000000000000
[ 83.991104] R10: 000000000000000a R11: 0000000000000246 R12: 00007f0c4fdd7640
[ 83.991109] R13: 0000000000000000 R14: 000000000041ba00 R15: 00007f0c4f5d7000
[ 83.991118] </TASK>
[ 83.991121] Modules linked in: snd_usb_audio usbhid hid snd_usbmidi_lib ttusb_dec ttusbdecfe dvb_core mc snd_sof_pca
[ 83.991249] sysfillrect rapl sysimgblt snd intel_cstate mei_me soundcore ee1004 mei gigabyte_wmi wmi_bmof serial_mt
[ 83.991333] CR2: ffffc900013c5060
[ 83.991339] ---[ end trace 0000000000000000 ]---
[ 83.991344] RIP: 0010:dvb_demux_do_ioctl+0x22/0x5b0 [dvb_core]
[ 83.991366] Code: 00 00 00 00 0f 1f 40 00 0f 1f 44 00 00 55 48 89 e5 41 57 49 89 d7 41 56 41 55 41 54 53 89 f3 48 84
[ 83.991372] RSP: 0018:ffffc90001a3fd10 EFLAGS: 00010282
[ 83.991378] RAX: 0000000000000000 RBX: 00000000403c6f2b RCX: ffffffffc051c520
[ 83.991383] RDX: ffffc90001a3fd80 RSI: 00000000403c6f2b RDI: ffff88810c4adc00
[ 83.991387] RBP: ffffc90001a3fd58 R08: 0000000000000000 R09: 0000000000000000
[ 83.991392] R10: 0000000000000000 R11: 0000000000000000 R12: 00000000fffffff2
[ 83.991396] R13: ffffc900013c5000 R14: ffff88810c4adc00 R15: ffffc90001a3fd80
[ 83.991401] FS: 00007f0c4fdd7640(0000) GS:ffff88844ea80000(0000) knlGS:0000000000000000
[ 83.991407] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 83.991412] CR2: ffffc900013c5060 CR3: 000000010b31e001 CR4: 00000000007706e0
[ 83.991417] PKRU: 55555554
```
## 2. 임의 주소 실행을 허용하는 UAF
먼저, 익스플로잇의 순서는 다음과 같습니다:```
cpu0 cpu1 cpu 2
1. dvb_dvr_open()
2. ttusb_dec_disconnect()
ttusb_dec_exit_dvb()
dvb_dmxdev_release()
wait_event(dmxdev->dvr_dvbdev->wait_queue, ...)
3. dvb_demux_open()
4. dvb_dvr_release()
5. dvb_unregister_device(dmxdev->dvbdev)
dvb_free_device()
kfree (dvbdev->fops)
6. close(demux0)
__x64_sys_close()
close_fd()
filp_close()
filp->f_op->flush(filp, id); <- UAF!!
```
상세한 익스플로잇 흐름은 다음과 같습니다:
1 ~ 4. 1~4의 순서는 첫 번째 취약점과 동일합니다.
5. .disconnect 흐름에서 `dvb_unregister_device(dmxdev->dvbdev) -> dvb_free_device() -> kfree (dvbdev->fops)`가 실행됩니다.
여기서 kfree()된 `dvbdev->fops`는 UAF 취약점의 대상입니다.
6. demux0 노드를 open()한 스레드에서 demux0 fd를 close()합니다.
실제로 demux0와 같은 dvb 장치 노드를 열 때는 dvb_XXX_open()이 아닌 `dvb_device_open()`이 먼저 호출됩니다:```
static int dvb_device_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev;
mutex_lock(&dvbdev_mutex);
down_read(&minor_rwsem);
dvbdev = dvb_minors[iminor(inode)];
if (dvbdev && dvbdev->fops) {
int err = 0;
const struct file_operations *new_fops;
new_fops = fops_get(dvbdev->fops);
if (!new_fops)
goto fail;
file->private_data = dvbdev;
replace_fops(file, new_fops); // replace fops here.
if (file->f_op->open)
err = file->f_op->open(inode, file); // call dvb_XXX_open()
up_read(&minor_rwsem);
mutex_unlock(&dvbdev_mutex);
return err;
}
fail:
up_read(&minor_rwsem);
mutex_unlock(&dvbdev_mutex);
return -ENODEV;
}
```
위 함수가 호출된 후, `replace_fops(file, new_fops);`를 통해 `file->f_op`가 `dvbdev->fops`로 대체됩니다.
이 `dvbdev->fops`는 단계 5에서 설명된 대로 이 UAF 취약점의 대상입니다.
흐름으로 돌아와서, `close(demux0)`가 호출되었기 때문에 close() 시스템 콜은 `__x64_sys_close() -> close_fd() -> filp_close()` 순서로 실행됩니다:```
int filp_close(struct file *filp, fl_owner_t id)
{
int retval = 0;
if (!file_count(filp)) {
printk(KERN_ERR "VFS: Close: file count is 0\n");
return 0;
}
if (filp->f_op->flush)
retval = filp->f_op->flush(filp, id); // UAF!!
if (likely(!(filp->f_mode & FMODE_PATH))) {
dnotify_flush(filp, id);
locks_remove_posix(filp, id);
}
fput(filp);
return retval;
}
```
위 함수에서 `filp->f_op->flush(filp, id);`가 호출되며, 이 `f_op`가 5단계에서 kfree()된 fops이기 때문에 UAF가 발생합니다.
이는 kmalloc 힙 스프레이와 결합하여 원하는 주소를 실행할 수 있는 취약점이 됩니다.
다음은 KASAN 로그입니다:```
[ 708.982899] ==================================================================
[ 708.982921] BUG: KASAN: use-after-free in filp_close+0x119/0x140
[ 708.982929] Read of size 8 at addr ffff888114bd4078 by task exploit2/2918
[ 708.982933] CPU: 7 PID: 2918 Comm: exploit2 Not tainted 6.0.0-rc2+ #4
[ 708.982936] Hardware name: Gigabyte Technology Co., Ltd. B460MDS3H/B460M DS3H, BIOS F3 05/27/2020
[ 708.982938] Call Trace:
[ 708.982954] <TASK>
[ 708.982956] dump_stack_lvl+0x49/0x63
[ 708.982960] print_report.cold+0x5e/0x5d9
[ 708.982963] ? filp_close+0x119/0x140
[ 708.982966] kasan_report+0xa0/0x120
[ 708.982969] ? filp_close+0x119/0x140
[ 708.982972] __asan_report_load8_noabort+0x14/0x20
[ 708.982975] filp_close+0x119/0x140
[ 708.982978] close_fd+0x75/0x90
[ 708.982981] __x64_sys_close+0x30/0x80
[ 708.982984] do_syscall_64+0x59/0x90
[ 708.982987] ? syscall_exit_to_user_mode+0x26/0x50
[ 708.982990] ? do_syscall_64+0x69/0x90
[ 708.982994] ? syscall_exit_to_user_mode+0x26/0x50
[ 708.983017] ? __do_sys_gettid+0x1b/0x30
[ 708.983022] ? do_syscall_64+0x69/0x90
[ 708.983027] ? exit_to_user_mode_prepare+0x49/0x1a0
[ 708.983035] ? irqentry_exit_to_user_mode+0x9/0x20
[ 708.983041] ? irqentry_exit+0x3b/0x50
[ 708.983045] ? exc_page_fault+0x72/0xf0
[ 708.983050] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[ 708.983072] RIP: 0033:0x45396b
[ 708.983077] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 33 a9 02 00 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 81 a9 02 00 8b 44
[ 708.983081] RSP: 002b:00007f55128b41a0 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
[ 708.983087] RAX: ffffffffffffffda RBX: 00007f55128b4640 RCX: 000000000045396b
[ 708.983091] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000004
[ 708.983094] RBP: 00007f55128b41d0 R08: 0000000000000000 R09: 0000000000000000
[ 708.983097] R10: 0000000000000000 R11: 0000000000000293 R12: 00007f55128b4640
[ 708.983100] R13: 0000000000000000 R14: 000000000041b3e0 R15: 00007f55120b4000
[ 708.983107] </TASK>
[ 708.983130] Allocated by task 663:
[ 708.983133] kasan_save_stack+0x26/0x50
[ 708.983137] __kasan_kmalloc+0xae/0xe0
[ 708.983140] __kmalloc_node+0x185/0x420
[ 708.983145] memcg_alloc_slab_cgroups+0x8a/0x130
[ 708.983149] allocate_slab+0x389/0x4a0
[ 708.983152] ___slab_alloc+0x6c5/0xa50
[ 708.983155] __slab_alloc.constprop.0+0x5a/0xb0
[ 708.983159] kmem_cache_alloc+0x2e3/0x320
[ 708.983162] seq_open+0x57/0x160
[ 708.983166] kernfs_fop_open+0x4f0/0xc10
[ 708.983171] do_dentry_open+0x404/0xf80
[ 708.983174] vfs_open+0x9f/0xd0
[ 708.983177] path_openat+0xd58/0x3f60
[ 708.983181] do_filp_open+0x1b1/0x3e0
[ 708.983184] do_sys_openat2+0x132/0x450
[ 708.983187] __x64_sys_openat+0x128/0x210
[ 708.983191] do_syscall_64+0x59/0x90
[ 708.983194] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[ 708.983201] Freed by task 159:
[ 708.983204] kasan_save_stack+0x26/0x50
[ 708.983207] kasan_set_track+0x25/0x40
[ 708.983211] kasan_set_free_info+0x24/0x40
[ 708.983215] ____kasan_slab_free+0x176/0x1e0
[ 708.983218] __kasan_slab_free+0x12/0x20
[ 708.983221] slab_free_freelist_hook+0xd0/0x1a0
[ 708.983224] kfree+0x1ae/0x3e0
[ 708.983227] dvb_free_device.part.0+0x33/0x70 [dvb_core]
[ 708.983241] dvb_unregister_device+0x20/0x30 [dvb_core]
[ 708.983248] dvb_dmxdev_release+0x3ba/0x4e3 [dvb_core]
[ 708.983255] ttusb_dec_disconnect+0x3d8/0x499 [ttusb_dec]
[ 708.983258] usb_unbind_interface+0x187/0x7c0
[ 708.983261] device_remove+0x117/0x170
[ 708.983264] device_release_driver_internal+0x418/0x660
[ 708.983266] device_release_driver+0x12/0x20
[ 708.983268] bus_remove_device+0x28f/0x540
[ 708.983270] device_del+0x501/0xc30
[ 708.983273] usb_disable_device+0x2a5/0x660
[ 708.983274] usb_disconnect.cold+0x1f9/0x620
[ 708.983277] hub_event+0x16d3/0x3d20
[ 708.983280] process_one_work+0x778/0x11c0
[ 708.983283] worker_thread+0x544/0x1180
[ 708.983285] kthread+0x280/0x320
[ 708.983286] ret_from_fork+0x1f/0x30
[ 708.983291] The buggy address belongs to the object at ffff888114bd4000
which belongs to the cache kmalloc-512 of size 512
[ 708.983293] The buggy address is located 120 bytes inside of
512-byte region [ffff888114bd4000, ffff888114bd4200)
[ 708.983297] The buggy address belongs to the physical page:
[ 708.983298] page:000000009b45bbf6 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x114bd0
[ 708.983301] head:000000009b45bbf6 order:3 compound_mapcount:0 compound_pincount:0
[ 708.983303] flags: 0x17ffffc0010200(slab|head|node=0|zone=2|lastcpupid=0x1fffff)
[ 708.983307] raw: 0017ffffc0010200 dead000000000100 dead000000000122 ffff888100042c80
[ 708.983309] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
[ 708.983311] page dumped because: kasan: bad access detected
[ 708.983313] Memory state around the buggy address:
[ 708.983314] ffff888114bd3f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 708.983316] ffff888114bd3f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 708.983318] >ffff888114bd4000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 708.983320] ^
[ 708.983321] ffff888114bd4080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 708.983323] ffff888114bd4100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 708.983325] ==================================================================
[ 708.983336] Disabling lock debugging due to kernel taint
```
## 3. slab UAF 쓰기
세 번째 slab UAF 취약점은 두 번째와 거의 동일합니다.
이것은 극히 미세한 경쟁 조건 시간 차이에서만 발생합니다.
익스플로잇의 순서는 다음과 같습니다:```
cpu0 cpu1 cpu 2
1. dvb_dvr_open()
2. ttusb_dec_disconnect()
ttusb_dec_exit_dvb()
dvb_dmxdev_release()
wait_event(dmxdev->dvr_dvbdev->wait_queue, ...)
3. dvb_demux_open()
4. dvb_dvr_release()
5. dvb_unregister_device(dmxdev->dvbdev)
dvb_free_device()
kfree (dvbdev)
6. dvb_demux_release()
dmxdev->dvbdev->users--; <- UAF!!
```
상세한 익스플로잇 흐름은 다음과 같습니다:
1 ~ 4. 1-4의 순서는 첫 번째 취약점과 동일합니다.
5. 이번에는 `dvbdev->fops`가 아닌 `dvbdev`가 UAF 취약점의 대상입니다:```
void dvb_free_device(struct dvb_device *dvbdev)
{
if (!dvbdev)
return;
kfree (dvbdev->fops);
kfree (dvbdev); // target
}
EXPORT_SYMBOL(dvb_free_device);
```
6. `close(demux0)`가 실행되면 `dvb_demux_release()` 함수가 호출되고, `dmxdev->dvbdev->users--;`에서 UAF 쓰기 취약점이 발생합니다.```
static int dvb_demux_release(struct inode *inode, struct file *file)
{
struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev = dmxdevfilter->dev;
int ret;
ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
mutex_lock(&dmxdev->mutex);
dmxdev->dvbdev->users--; // here
if (dmxdev->dvbdev->users == 1 && dmxdev->exit == 1) {
mutex_unlock(&dmxdev->mutex);
wake_up(&dmxdev->dvbdev->wait_queue);
} else
mutex_unlock(&dmxdev->mutex);
return ret;
}
```
이 UAF 쓰기 취약점은 예를 들어 다른 구조체의 참조 횟수(refcount)를 감소시키는 데 사용될 수 있습니다.
# 취약점 범위
해당 취약점의 범위는 다음과 같습니다:
- drivers/media/usb/as102/as102_usb_drv.c
- drivers/media/usb/tm6000/tm6000-cards.c
- drivers/media/usb/pvrusb2/pvrusb2-dvb.c
- drivers/media/usb/au0828/au0828-core.c
- drivers/media/usb/cx231xx/cx231xx-cards.c
- drivers/media/usb/ttusb-dec/ttusb_dec.c
- drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
- drivers/media/usb/em28xx/em28xx-dvb.c
- drivers/media/usb/dvb-usb/cxusb.c
- drivers/media/usb/dvb-usb/dw2102.c
- drivers/media/usb/dvb-usb/dtt200u.c
- drivers/media/usb/dvb-usb/m920x.c
- drivers/media/usb/dvb-usb/dibusb-mb.c
- drivers/media/usb/dvb-usb/ttusb2.c
- drivers/media/usb/dvb-usb/pctv452e.c
- drivers/media/usb/dvb-usb/a800.c
- drivers/media/usb/dvb-usb/umt-010.c
- drivers/media/usb/dvb-usb/dtv5100.c
- drivers/media/usb/dvb-usb/dibusb-mc.c
- drivers/media/usb/dvb-usb/cinergyT2-core.c
- drivers/media/usb/dvb-usb/nova-t-usb2.c
- drivers/media/usb/dvb-usb/vp7045.c
- drivers/media/usb/dvb-usb/digitv.c
- drivers/media/usb/dvb-usb/gp8psk.c
- drivers/media/usb/dvb-usb/vp702x.c
- drivers/media/usb/dvb-usb/opera1.c
- drivers/media/usb/dvb-usb/technisat-usb2.c
- drivers/media/usb/dvb-usb/dib0700_core.c
- drivers/media/usb/dvb-usb/az6027.c
- drivers/media/usb/dvb-usb/af9005.c
- drivers/media/usb/dvb-usb-v2/au6610.c
- drivers/media/usb/dvb-usb-v2/zd1301.c
- drivers/media/usb/dvb-usb-v2/ce6230.c
- drivers/media/usb/dvb-usb-v2/ec168.c
- drivers/media/usb/dvb-usb-v2/gl861.c
- drivers/media/usb/dvb-usb-v2/dvbsky.c
- drivers/media/usb/dvb-usb-v2/az6007.c
- drivers/media/usb/dvb-usb-v2/lmedm04.c
- drivers/media/usb/dvb-usb-v2/anysee.c
- drivers/media/usb/dvb-usb-v2/mxl111sf.c
- drivers/media/usb/dvb-usb-v2/af9015.c
- drivers/media/usb/dvb-usb-v2/rtl28xxu.c
- drivers/media/usb/dvb-usb-v2/af9035.c
- ...
# 참조
- https://lore.kernel.org/all/[email protected]/
- https://www.suse.com/security/cve/CVE-2022-41218.html
- https://www.openwall.com/lists/oss-security/2022/09/24/1