我在运行以下C程序时遇到问题:
#include<unistd.h>
void main()
{
if (access("/root/main.c",R_OK)==0)
{
printf("/root/main.c can be read\n");
}
else
{
printf("can't be read\n");
}
}
当我以root身份运行可执行文件时,我可以获得输出:
/root/main.c can be read
但是当我将可执行文件的权限设置为4755
并以普通用户身份运行时,我只获得输出:
can't be read
我的协议中有错误吗?
答案 0 :(得分:3)
access
忽略setuid / setgid位。这是设计的。
在Linux上从man 2 access
引用:
使用调用进程的真实 UID和GID完成检查, 而不是实际尝试时所做的有效ID 对文件的操作(例如,
open(2)
)。同样,对于root用户, 检查使用允许的功能集而不是集 有效的能力;对于非root用户,检查使用 空集的能力。这允许set-user-ID程序和功能赋予的程序 轻松确定调用用户的权限。换一种说法,
access()
没有回答“我可以读取/写入/执行此文件吗?” 题。它回答了一个略有不同的问题:“(假设我是一个 setuid binary)可以调用我的用户读/写/执行此操作 file?“,它为set-user-ID程序提供了防范的可能性 恶意用户导致他们读取用户不应该读取的文件 能够阅读。
如果您想知道您的进程是否可以实际打开文件进行阅读,只需open()
它并处理错误(如果有的话)。 (这也避免了竞争条件。)