You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

丢弃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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:44:51