我不理解我的平台(ubuntu)上可执行文件的 setgid 。g-x,g+s
没有向进程授予程序所有者的有效组权限。
$ gcc perms.c -o perms; ls -l ; ./perms
-rwxr-xr-x 1 ubuntu ubuntu 9302 Feb 24 01:00 perms*
-rw-r--r-- 1 ubuntu ubuntu 1437 Feb 21 08:41 perms.c
ruid: ubuntu:1000 group:1000
euid: ubuntu:1000 group:1000
$ sudo useradd alice; groups alice $USER
alice : alice
ubuntu : ubuntu sudo rvm
$ chmod g+s ./perms; ls -l ./perms ; sudo -u alice ./perms
rwxr-sr-x 1 ubuntu ubuntu 9302 Feb 24 01:00 perms*
ruid: alice:1001 group:1002
euid: alice:1001 group:**1000**
这一切都在意料之中,问题是:
$ chmod g-x ./perms; ls -l ./perms ; sudo -u alice ./perms
-rwxr-Sr-x 1 ubuntu ubuntu 9302 Feb 24 01:00 perms*
ruid: alice:1001 group:1002
euid: alice:1001 group:**1002**
我的理解是,这为g+s
进程提供了程序所有者的有效组 ID,但事实并非如此。显然,这是因为g-x
这是唯一的变化。
Edit1:删除了有关目录如何工作的部分g-x,g+s
,因为人们认为我在询问S
目录。我不是。
Edit2:因为我从一个答案中得到了屈辱。这也与以下情况不同u-x,u+s
:
$ rm -rf perms temp/; gcc perms.c -o perms
$ chmod ug-x,ug+s ./perms; ls -l ./perms; sudo -u alice ./perms
-rwSr-Sr-x 1 ubuntu ubuntu 9302 Feb 24 21:22 ./perms*
ruid: alice:1001 group:1002
euid: ubuntu:1000 group:1002
这里u-x,u+s
受到尊重,但g-x,g+s
并非如此。
我的问题:为什么capital S sgid
可执行文件被忽略?
g-x,g+s
在目录中受到尊重。
u-x,u+s
在可执行文件上受到尊重。
但g-x,g+s
在可执行文件上不受尊重。
为什么?
回答: 我的研究似乎已经陷入了“因为 System V 武断地决定它意味着其他东西”的死胡同。
答案1
好吧,RTFM 的一个回复对我没有多大帮助。经过几个小时的挖掘,我在当前的 Linux 内核中找到了这些行。
https://github.com/torvalds/linux/blob/e816c201aed5232171f8eb80b5d46ae6516683b9/fs/exec.c
/* Be careful if suid/sgid is set */
inode_lock(inode);
/* reload atomically mode/uid/gid now that lock held */
mode = inode->i_mode;
uid = inode->i_uid;
gid = inode->i_gid;
inode_unlock(inode);
/* We ignore suid/sgid if there are no mappings for them in the ns */
if (!kuid_has_mapping(bprm->cred->user_ns, uid) ||
!kgid_has_mapping(bprm->cred->user_ns, gid))
return;
if (mode & S_ISUID) {
bprm->per_clear |= PER_CLEAR_ON_SETID;
bprm->cred->euid = uid;
}
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
bprm->per_clear |= PER_CLEAR_ON_SETID;
bprm->cred->egid = gid;
}
很明显,这是故意的。
这可以追溯到 2005 年 5 月最初上传到 github 的时间:
https://github.com/torvalds/linux/blob/3677209239ed71d2654e73eecfab1dbec2af11a9/fs/exec.c
bprm->e_uid = current->euid;
bprm->e_gid = current->egid;
if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
/* Set-uid? */
if (mode & S_ISUID) {
current->personality &= ~PER_CLEAR_ON_SETID;
bprm->e_uid = inode->i_uid;
}
/* Set-gid? */
/*
* If setgid is set but no group execute bit then this
* is a candidate for mandatory locking, not a setgid
* executable.
*/
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
current->personality &= ~PER_CLEAR_ON_SETID;
bprm->e_gid = inode->i_gid;
}
}
谷歌搜索评论会导致:
https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt
- 将文件标记为强制锁定
文件被标记为强制锁定的候选者在其文件模式中设置组 ID 位,但删除组执行位。这是一个没有任何意义的组合,并且是由 System V 实施者选择以免破坏现有的用户程序。
请注意,当写入 setgid 文件时,内核通常会自动清除 group-id 位。这是一项安全措施。内核已被修改为识别强制锁定候选者的特殊情况并避免清除该位。同样,内核已被修改为不运行具有 setgid 权限的强制锁定候选者。
所以答案似乎是“因为它被选择来表示其他含义。”
答案2
当您编辑问题以包含以下内容时:
我的问题:为什么可执行文件会忽略大写的 S sgid?
它并没有被忽视。S
在你的情况下意味着该文件不能由组执行,因此它是良性的。如果您希望可执行文件以组的权限运行,那么它需要可由组执行。你把它拿走了,g-x
这就是你得到的原因S
。它将以执行它的人的权限运行,而不是以组的权限运行。