使用 chmod 数字模式取消设置 setgid 位

使用 chmod 数字模式取消设置 setgid 位

我刚刚注意到chmod取消设置 setgid 位时的一些有趣行为:

$ mkdir test
$ chmod 2755 test
$ stat -c '%a %n' test
2755 test  # as expected
$ chmod 0755 test
$ stat -c '%a %n' test
2755 test  # what? see below
$ chmod 00755 test
$ stat -c '%a %n' test
755 test  # double what?!

尝试取消设置 setgid 位chmod 0755不起作用,这令人惊讶。但是,手册页表明这是预期的行为:

SETUID 和SETGID 位

如果文件的组 ID 与用户的有效组 ID 或用户的补充组 ID 之一不匹配,则 chmod 会清除常规文件的 set-group-ID 位,除非用户具有适当的权限。其他限制可能会导致 MODE 或 RFILE 的 set-user-ID 和 set-group-ID 位被忽略。此行为取决于底层 chmod 系统调用的策略和功能。如有疑问,请检查底层系统行为。

chmod 保留目录的 set-user-ID 和 set-group-ID 位,除非您另外明确指定。您可以使用 u+s 和 gs 等符号模式设置或清除位,以及您可以使用数字模式设置(但不能清除)这些位。

(强调已添加)

所以它似乎chmod 0755并不意味着取消设置 setgid 位。那么,为什么要chmod 00755取消它呢?chmod似乎没有任何用处数字模式的数字。再次从手册页:

数字模式来自一到四八进制数字 (0-7),通过将值 4、2 和 1 的位相加得出。省略的数字假定为前导零。

(强调已添加)

这里发生了什么?为什么chmod决定忽略单个前导 0?为什么会这样不是忽略两个前导 0?

(Debian Stretch 9.1,带有 chmod (GNU Coreutils) 8.6)

答案1

我找到了!手册页中缺少此信息,但 Coreutils 在线手册中有此信息。以机智:

在大多数系统上,如果设置了目录的 set-group-ID 位,则新创建的子文件将继承与该目录相同的组,并且新创建的子目录将继承父目录的 set-group-ID 位。在某些系统上,目录的 set-user-ID 位对新子文件的所有权和新子目录的 set-user-ID 位具有类似的影响。这些机制减少了使用chmodchown共享新文件的需要,使用户可以更轻松地共享文件。

这些便利机制依赖于目录的 set-user-ID 和 set-group-ID 位。如果像chmod和 之类的命令mkdir定期清除目录上的这些位,则该机制将不太方便,并且共享文件将变得更加困难。因此,类似的命令chmod不会影响目录的 set-user-ID 或 set-group-ID 位,除非用户以符号模式特别提及它们,或者使用运算符数字模式(例如“=755”),或者设置在数字模式下清除它们,或在具有五个或更多八进制数字的数字模式下清除它们。

参考:https://www.gnu.org/software/coreutils/manual/html_node/Directory-Setuid-and-Setgid.html

答案2

也许这是 Debian Stretch 9.1 中 chmod 的一个错误?它在 Ubuntu 12.04、Ubuntu 16.04.3、CentOS 6.9 和 CentOS 7.4 上正常工作。

相关内容