可执行文件设置root suid,但是access(path, W_OK) 还是return -1?

Executable file set root suid, but access(path, W_OK) still return -1?

为什么可执行文件设置了root suid,但是access(path, W_OK)还是return -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

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

的事实

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

这在man 2 access中有解释:

The check is done using the calling process's real UID and GID, rather than the effective IDs as is done when actually attempting an operation (e.g., open(2)) on the file.…

This allows set-user-ID programs and capability-endowed programs to easily determine the invoking user's authority. In other words, access() does not answer the "can I read/write/execute this file?" question. It answers a slightly different question: "(assuming I'm a setuid binary) can the user who invoked me read/write/execute this file?", which gives set-user-ID programs the possibility to prevent malicious users from causing them to read files which users shouldn't be able to read.

感谢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)