为何设置了setuid位的脚本未以文件所有者身份执行?
核心原因
Linux 系统默认不支持 Shell 脚本的 SUID 权限生效,仅二进制可执行文件的 SUID 位会被内核正常处理。
你看到的 SUID 权限规则描述本身是正确的,但仅适用于二进制可执行程序,不适用于解释型脚本(Shell、Python、PHP 等都属于这类),具体原因如下:
- 脚本本身不能直接被内核执行,内核识别到文件是脚本后,会启动对应的解释器(如 bash、zsh)进程,把脚本路径作为参数传入执行。此时 SUID 位是标记在脚本文件上的,解释器进程本身没有设置 SUID 位,所以进程最终还是以执行脚本的用户身份运行。
- 脚本的 SUID 存在极高的安全风险,很容易被通过路径篡改、环境变量劫持、符号链接攻击等方式利用提权,所以包括 Ubuntu 在内的几乎所有主流 Linux 发行版都默认禁用了脚本的 SUID 生效机制。
验证方案
你可以把需要执行的逻辑编译为二进制程序,再设置 SUID 位即可复现预期效果,示例如下:
- 编写 C 代码
test_suid.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { // 将实际UID设置为有效UID(即文件所有者UID),确保权限继承 setuid(geteuid()); system("ls /tmp/foo/bar"); return 0; }
- 编译并设置 SUID 位
gcc test_suid.c -o test_suid chmod 4777 test_suid
- 切换到 bob 用户执行该二进制程序,即可正常输出
/tmp/foo/bar下的baz.txt文件。
补充注意
生产环境使用 SUID 二进制程序时必须严格做权限控制和输入校验,避免出现提权安全漏洞。
内容的提问来源于stack exchange,提问作者gowerc
相关产品推荐
相关产品推荐

