为什么删除CAP_DAC_OVERRIDE后创建文件失败?

问题描述 投票:0回答:1

当用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"
c linux linux-kernel system-calls linux-capabilities
1个回答
0
投票

当您以自己的身份运行该程序时,它不需要

CAP_DAC_OVERRIDE
功能来在您可写的目录中创建文件。事实上,除非您通过
setcap
为二进制文件分配功能,否则该进程首先不会具有该功能。这并不值得注意,如果您在不可写的目录中运行程序,程序会失败也不是事实。

当您使用

sudo
运行程序时,它以用户0(root)身份运行。因此,它从其有效集中的所有功能开始。正是这个,而不是 uid 0 本身,才是进程能够绕过自主访问控制的基础,例如,在不同用户和组拥有的目录中创建文件,并且该文件不是全局可写的。例如(很可能)您的主目录及其所有子目录。如果您关闭
CAP_DAC_OVERRIDE
那么该过程将无法再执行此操作。

你写的

当前工作目录似乎没有任何区别。

...但我倾向于认为工作目录实际上确实有所作为。我希望如果您通过

sudo
在可写入 root 的目录中运行程序而不使用
CAP_DAC_OVERRIDE
那么它将成功。您的系统上不应该有许多全局可写的目录,并且在 root 拥有的大多数文件夹中进行测试是不明智的,但是
/tmp
将是一个合理的测试文件夹。

© www.soinside.com 2019 - 2024. All rights reserved.