关于setuid的问题

时间:2018-03-12 14:19:42

标签: c setuid

我在运行以下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

我的协议中有错误吗?

1 个答案:

答案 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()它并处理错误(如果有的话)。 (这也避免了竞争条件。)