Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2022-41218 — CVE-2022-41218 漏洞详情 | Kitploit
工具/GitHubGitHub/tobey123/cve-2022-41218
漏洞分析漏洞利用二进制利用
GitHubtobey123/cve-2022-41218

CVE-2022-41218

CVE-2022-41218 漏洞详情

查看仓库
44年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

介绍

该漏洞是发生在 drivers/media/dvb-core/dmxdev.c 中的一个竞态条件漏洞。 因此,使用此 dmxdev 的 USB 设备驱动程序中也可能发生竞态条件。

此漏洞可用于触发 3 次 UAF。

漏洞

1. vmalloc 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. open() 设备节点中的 dvr0。这会调用 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. open() demux0 节点,以便调用 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()。 调用时,第3个参数提交由 userfaultfd(或 FUSE 文件系统)设置的用户空间地址。 现在,当 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 节点的线程中调用 `close()` 关闭 fd。
然后调用 `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。
现在,在所有 `dvb_demux_do_ioctl()` 的调用场景下都能利用 UAF,甚至在结合 eBPF 时还能实现 LPE。
下载工具