Linux open() 系统调用和文件夹权限

Linux open() 系统调用和文件夹权限

我有一个过程它是由 root 拥有的进程产生的。后创建 setguid() 并调用 setuid() 并以用户身份运行U

过程尝试创建文件F在文件夹上F(在根文件系统中)由root拥有并具有以下权限:

drwxrwx---    2 root     root

函数调用如下所示:

open(path , O_CREAT | O_RDWR , 0660);

如果我运行命令ps -e -o cmd,uid,euid,ruid,suid,gid,egid,rgid,sgid 结果如下:

/my/process    500   500   500   500   500   500   500   500

这证实了该过程没有以 root 身份运行,但是很奇怪,即使该进程以用户身份运行U文件F是在文件夹下创建的F只能由 root 及其组成员写入:

-rw-rw---- 1 U U

所以该文件的所有者是U

如果我尝试从 bash 中执行相同的操作,我会按预期得到“权限被拒绝”:

$ touch /F/f
touch: cannot touch `/F/f': Permission denied

如果我设置文件夹F权限:

drwx------    2 root     root

那么 open() 调用将失败,并按预期显示“权限被拒绝”。

为什么可以当向根组授予写入权限时,在该文件夹中创建文件吗?

附注命令显示所有 uid 和 gid 都设置为相关的用户 id,那怎么可能呢?

这些是组成员身份U

$groups root
root : root

$groups U
U : U G

所以UG作为次要群体

$lid -g root
 root(uid=0)
 sync(uid=5)
 shutdown(uid=6)
 halt(uid=7)
 operator(uid=11)

$lid -g U
 U(uid=500)

$lid -g G
 U(uid=500)

这表明仅U是的成员G

答案1

就像@jdwolf 在评论中提到的那样,问题可能是补充组。setgid()不会删除它们。

一个简单的测试,./drop下面是一个程序,调用setregid()setreuid()将 GID 和 UID 更改为nobody,然后运行id

# id
uid=0(root) gid=0(root) groups=0(root)
# ./drop
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup),0(root)

还有零组。添加setgroups(0, NULL)(在 之前setuid())会删除该组:

# ./drop2
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)

当然,这不会添加任何其他目标用户的组。

相关内容