丢弃CAP_DAC_OVERRIDE权限后文件创建失败的原因分析
为何sudo运行程序创建文件失败?
当用gcc编译以下程序并通过sudo ./a.out运行时,程序输出:
a.out: open 13: Permission denied
程序返回EXIT_FAILURE。但不使用sudo运行时,程序可成功创建test.lock文件,且当前工作目录对结果无影响。为何创建文件会失败?
程序代码
#include <err.h> #include <errno.h> #include <fcntl.h> #include <linux/capability.h> #include <stdlib.h> #include <sys/syscall.h> #include <unistd.h> int main(void) { /* get capabilities */ struct __user_cap_header_struct hdr = { .pid = 0, .version = _LINUX_CAPABILITY_VERSION_3, }; struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3]; if (syscall(SYS_capget, &hdr, data) == -1) err(EXIT_FAILURE, "SYS_capget %d", errno); /* update and set capabilities */ data[0].effective &= ~(1 << CAP_DAC_OVERRIDE); if (syscall(SYS_capset, &hdr, data) == -1) err(EXIT_FAILURE, "SYS_capset %d", errno); /* open file */ if (open("test.lock", O_CREAT|O_RDONLY|O_CLOEXEC, S_IRUSR|S_IWUSR) == -1) err(EXIT_FAILURE, "open %d", errno); return EXIT_SUCCESS; }
额外环境信息
$ uname --kernel-release 4.18.0-477.27.1.el8_8.x86_64 $ gcc --version gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-18) Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ rpm --query glibc glibc-2.28-225.el8_8.6.x86_64 glibc-2.28-225.el8_8.6.i686 $ cat /etc/os-release NAME="Red Hat Enterprise Linux" VERSION="8.9 (Ootpa)" ID="rhel" ID_LIKE="fedora" VERSION_ID="8.9" PLATFORM_ID="platform:el8" PRETTY_NAME="Red Hat Enterprise Linux 8.9 (Ootpa)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:redhat:enterprise_linux:8::baseos" HOME_URL="https://www.redhat.com/" DOCUMENTATION_URL="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8" BUG_REPORT_URL="https://bugzilla.redhat.com/" REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8" REDHAT_BUGZILLA_PRODUCT_VERSION=8.9 REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" REDHAT_SUPPORT_PRODUCT_VERSION="8.9"
原因分析
- sudo运行时的能力变化:通过
sudo启动程序时,进程的有效UID为root,默认拥有CAP_DAC_OVERRIDE能力——该能力允许进程绕过Linux的DAC(自主访问控制)权限检查,无需依赖目录的写权限即可创建文件。 - 主动移除关键能力:代码中通过
capset系统调用,从进程的有效能力集中移除了CAP_DAC_OVERRIDE。此时,root进程失去了权限绕过能力,必须严格遵守普通文件权限规则。 - 目录权限的限制:当前工作目录的权限大概率仅允许你的普通用户账号写入(比如权限为
700,属主为普通用户)。当root进程失去CAP_DAC_OVERRIDE后,无法绕过该目录的权限限制,因此创建文件时被拒绝,返回权限错误。 - 非sudo运行正常的逻辑:直接运行程序时,进程的UID是你的普通用户账号,该账号对当前目录拥有合法的写权限,因此无需依赖特殊能力就能成功创建文件。
内容的提问来源于stack exchange,提问作者Chris Yungmann
相关产品推荐
相关产品推荐

