我在 Parallels for Mac 上使用全新安装的 OpenBSD 5.3 作为来宾操作系统:
$ uname -a
OpenBSD openbsd.localdomain 5.3 GENERIC#53 amd64
令我惊讶的是,一个由 root 拥有且设置了 SUID 位的二进制文件使用 UID 运行,就好像未设置 SUID 一样。也就是说,当 UID 1000 运行这样的程序时,程序启动状态为:
<real_uid, effective_uid, saved_uid> = <1000, 1000, 1000>
并且不在状态:
<real_uid, effective_uid, saved_uid> = <1000, 0, 0>
正如预期的那样。
为什么会这样?
以下是有关我如何发现问题的详细信息:
我编写了一个交互式 C 程序(编译为setuid_min.bin)用于评估不同 Unix 系统中的 setuid 行为。该程序位于 UID 1000 的主目录的子目录中,使用sudo命令更改所有权和 SUID;然后程序运行,我输入uid来报告进程的真实、有效和保存的 UID:
$ sudo chown root:staff setuid_min.bin
$ ls -l | grep 'setuid_min\.bin$'
-rwxr-xr-x 1 root staff [...] setuid_min.bin
$ sudo chmod a+s setuid_min.bin
$ ls -l | grep 'setuid_min\.bin$'
-rwsr-sr-x 1 root staff [...] setuid_min.bin
$ ./setuid_min.bin
uid
1000 1000 1000 some_pid
exit
$
注意上面的some_pid是setuid_min.bin进程的 pid 。程序通过报告以下 shell 命令的输出来报告真实 UID、有效 UID 和保存的 UID:
ps -ao ruid,uid,svuid,pid | grep '[ ]my_pid$'
其中my_pid是由getpid()报告的 pid 。关于为什么会出现这种情况,我唯一的猜测是 OpenBSD 具有一些底层权限结构,该结构使用setuid_min.bin所在目录的所有权/权限,或者当非特权用户使用时实际上并没有更改所有权/SUID 位sudo更改文件权限。