
تفاصيل الثغرة الأمنية لـ CVE-2022-41218
هذه الثغرة هي ثغرة حالة سباق (race condition) تحدث في drivers/media/dvb-core/dmxdev.c. لذلك، قد تحدث حالة سباق في برنامج تشغيل جهاز USB الذي يستخدم هذا dmxdev.
يمكن استخدام هذه الثغرة لتفعيل 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 من بين عُقد الأجهزة. يؤدي هذا إلى استدعاء الدالة dvb_dvr_open() لتنفيذ `dvbdev->users++`.
في هذه الحالة، عند تنفيذ ttusb_dec_disconnect() عن طريق إزالة جهاز usb، يتم تعليق التنفيذ عند شرط `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.
2. قم بإزالة جهاز USB فعليًا.
في هذه الحالة، وأثناء تنفيذ الدالة ttusb_dec_disconnect()، فإنها تنتظر عند `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.
3. استدعِ open() على العقدة demux0 بحيث يتم استدعاء الدالة dvb_demux_open().
تنفذ هذه الدالة أيضًا `dvbdev->users++` بشكل مشابه للدالة dvb_dvr_open() في الخطوة 1.
ومع ذلك، يحدث هذا العد غير الصحيح للمراجع لأن الدالة 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);
}
ثم يستدعي ioctl() على demux0. عند الاستدعاء، تُرسل الوسيطة الثالثة عنوان مساحة المستخدم الذي تم تعيينه بواسطة userfaultfd (أو FUSE fs). الآن أثناء تشغيل ioctl، سيتوقف عند copy_from_user() الخاصة بـ dvb_usercopy():``` 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. قم باستدعاء `close()` على واصف الملف (fd) في الخيط الذي قام بفتح عقدة dvr0.
ثم يتم استدعاء `dvb_dvr_release()`، ويتم تنفيذ `dvbdev->users--` و `wake_up(&dvbdev->wait_queue)` لتنبيه دالة `dvb_dmxdev_release()`، وهي تدفق .disconnect.
5. في تدفق .disconnect، دالة `dvb_dmxdev_release()` تنفذ `vfree(dmxdev->filter)`.
6. حرّر userfaultfd من خيط ioctl الخاص بـ demux0 الذي قام بضبط userfaultfd.
سيؤدي هذا إلى حدوث UAF عند قراءة عنوان `dmxdev->filter` الذي تم تحريره للتو من .disconnect.
يمكن الآن استخدام UAF في جميع حالات `dvb_demux_do_ioctl()`، وحتى LPE ممكن عند ربطه مع eBPF.
يبدو سجل kernel كما يلي:```
[ 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
أولاً، يكون ترتيب الاستغلال كما يلي:``` 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)`.
هنا، `dvbdev->fops` الذي تم تحريره عبر kfree() هو هدف ثغرة الاستخدام بعد التحرير (UAF).
6. قم باستدعاء close() على واصف demux0 fd في الخيط الذي استدعى open() على عقدة demux0.
في الواقع، عند فتح عقدة جهاز dvb مثل demux0، يتم استدعاء `dvb_device_open()` أولاً، وليس `dvb_XXX_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 هو هدف ثغرة UAF هذه، كما هو موضح في الخطوة 5.
بالعودة إلى التدفق، يتم تنفيذ استدعاءات نظام close() بالترتيب __x64_sys_close() -> close_fd() -> filp_close() لأنه تم استدعاء close(demux0):```
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);`، ويحدث UAF لأن هذا `f_op` هو fops الذي تم تحريره عبر kfree() في الخطوة 5.
هذا، إلى جانب رشّ الكومة عبر 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
ثغرة slab UAF الثالثة مطابقة تقريبًا للثانية. تحدث فقط في فروق زمنية دقيقة في حالة race condition.
ترتيب الاستغلال هو كما يلي:``` 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`، وليس `dvbdev->fops`، هو الهدف من ثغرة الاستخدام بعد التحرير (UAF):```
void dvb_free_device(struct dvb_device *dvbdev)
{
if (!dvbdev)
return;
kfree (dvbdev->fops);
kfree (dvbdev); // target
}
EXPORT_SYMBOL(dvb_free_device);
عند تنفيذ close(demux0)، يتم استدعاء الدالة dvb_demux_release() وتحدث ثغرة كتابة UAF في dmxdev->dvbdev->users--;.```
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