可执行文件设置root suid,但是access(path,W_OK)仍然返回-1?

时间:2016-01-22 02:20:06

标签: c suid

为什么可执行文件集root suid,但access(path,W_OK)仍然返回-1?

代码:

#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("privilege => %d\n", access("/usr/local/etc/t.conf", W_OK));
    return 0;
}

试运行:

[www@mypy access]$ ll
总用量 12
-rwsrwxr-x. 1 root root 6600 1月  22 10:05 access
-rw-rw-r--. 1 www  www   135 1月  22 10:05 access.c

[www@mypy access]$ ./access 
privilege => -1

[root@mypy access]# ./access 
privilege => 0

2 个答案:

答案 0 :(得分:3)

access库函数故意检查真实用户的访问权限,忽略了可执行文件具有不同的有效UID / GID这一事实。

如果您只想知道是否可以进行读或写访问,可以打开该文件并查看是否有错误。但是,仔细的setuid可执行文件通常想知道真实用户是否能够对文件执行操作。为了找到答案,他们可以使用access库函数。

man 2 access中解释了这一点:

  

使用调用进程的真实UID和GID完成检查,而不是在文件上实际尝试操作(例如,open(2))时完成的有效ID。...

     

这允许set-user-ID程序和能力赋予程序轻松确定调用用户的权限。换句话说,access()不回答&#34;我可以读/写/执行这个文件吗?&#34;题。它回答了一个稍微不同的问题:&#34;(假设我是setuid二进制文件),调用我的用户可以读/写/执行这个文件吗?&#34;,它给出了set-user-ID程序的可能性防止恶意用户读取用户不应该阅读的文件。

答案 1 :(得分:1)

感谢rici的回答!我按照以下方式完成了

int accesswriteable(char const *path)
{
    if(access(path, F_OK))
    {
        return 1;
    }
    FILE *fp = fopen(path, "a");
    if(fp == NULL)
    {
        return 1;
    }
    fclose(fp);
    return 0;
}

#define PATH_WRITE_ABLE(path) (accesswriteable(path) == 0)