CVE-2022-50506CVE-2022-50506是Linux内核DRBD(Distributed Replicated Block Device,分布式复制块设备)驱动中的一个空指针解引用漏洞。该漏洞源于commit c347a787e34cb(drbd: set ->bi_bdev in drbd_req_new)将bio_set_dev调用从drbd_request_prepare函数前移到drbd_req_new函数中。在此过程中,代码访问了device->ldev->backing_bdev指针,但该指针在此处未进行NULL检查。当DRBD设备处于无磁盘(diskless)状态时,即没有关联的ldev(逻辑设备)时,访问backing_bdev将导致空指针解引用,可能引发内核崩溃(kernel panic)或拒绝服务(DoS)。该漏洞的CVSS评分为5.5,属于中危级别,攻击者需要本地低权限访问即可触发此漏洞,无需用户交互,主要影响系统的可用性。该漏洞已在Linux内核的稳定版本中通过补丁05580a3bbf3cec677cb00a85dfeb21d6a9b48eaf和6d42ddf7f27b6723549ee6d4c8b1b418b59bf6b5得到修复。修复方案是在确认存在磁盘设备(即ldev有效)后才分配private_bio,避免在无磁盘情况下进行不必要的bio克隆操作。
该漏洞的技术原理如下:在DRBD驱动中,bio(Block I/O)是块设备I/O操作的基本数据结构。commit c347a787e34cb将bio_set_dev调用从drbd_request_prepare前移到drbd_req_new函数,目的是更早地设置bi_bdev字段。然而,drbd_req_new函数中访问了device->ldev->backing_bdev来获取后备块设备指针,但未对ldev进行NULL检查。在DRBD的无磁盘(diskless)模式下,ldev为NULL,因此访问ldev->backing_bdev将触发空指针解引用,导致内核崩溃。
利用方式:
1. 攻击者需要本地访问目标系统,并具有低权限(PR:L)。
2. 攻击者需要配置或访问处于diskless状态的DRBD设备。
3. 当对diskless的DRBD设备发起I/O请求时,内核会调用drbd_req_new函数。
4. 在drbd_req_new中,代码尝试访问device->ldev->backing_bdev,由于ldev为NULL,触发空指针解引用。
5. 内核崩溃,导致系统拒绝服务。
修复方案是仅在确实存在磁盘设备(即ldev有效)时才分配private_bio,这样不仅修复了空指针解引用问题,还避免了不必要的bio克隆操作(因为在diskless情况下,克隆的bio会立即被释放)。