setuid后调用getuid失效:非程序所有者执行C程序异常
解决setuid程序仅所有者可正常运行的问题
我来帮你梳理清楚这个问题——这其实是Linux/Unix下setuid权限的安全限制导致的,咱们一步步拆解:
核心问题:普通用户的setuid位仅对所有者生效
你给程序设了chmod 7777,看起来开放了所有权限,但这里有个关键的安全规则:如果程序的所有者是普通用户(非root),那么只有该所有者执行程序时,setuid位才会触发权限切换,其他用户(哪怕是同组用户)执行时,程序的有效UID依然是执行者自己的UID,不会切换到所有者的1111。
举个实际场景:当你用所有者身份执行时,程序的有效UID会变成1111,这时候你的setuid调用能正常工作;但同组用户执行时,有效UID是他们自己的UID,调用setuid(1111)会直接失败(普通用户没有权限切换到其他用户的UID),这就导致了程序异常。
验证方法:打印UID信息排查
你可以在程序里加上UID打印逻辑,直观看到不同用户执行时的权限差异:
#include <stdio.h> #include <unistd.h> int main() { uid_t ruid, euid, suid; getresuid(&ruid, &euid, &suid); printf("Real UID: %d\n", ruid); printf("Effective UID: %d\n", euid); printf("Saved UID: %d\n", suid); // 原setuid逻辑 int ret = setuid(1111); if (ret == -1) { perror("setuid failed"); } printf("After setuid, UID: %d\n", getuid()); return 0; }
编译后分别用所有者和同组用户执行,你会看到:
- 所有者执行:Effective UID是1111,setuid成功,最终UID为1111
- 同组用户执行:Effective UID是自己的UID,setuid报错,最终UID还是自己的
解决方案:让所有用户都能触发权限切换
如果你的需求是让所有用户执行程序时都能切换到1111的UID,需要借助root权限来设置程序:
- 先把程序的所有者改为root:
sudo chown root:root your_program - 给程序设置root的setuid位(只需要所有者的setuid位即可,不需要开放7777这么大的权限):
sudo chmod u+s your_program
这样,任何用户执行这个程序时,有效UID都会先变成root,这时候你的setuid(1111)调用就会成功(root有权限切换到任何UID),程序就能正常运行了。
安全提醒
- 不要用
chmod 7777,这会给所有用户写权限,非常不安全,只需要给其他用户执行权限即可(比如chmod o+x)。 - setuid程序要严格编写,避免缓冲区溢出、命令注入等漏洞,一旦是root的setuid程序,漏洞可能导致攻击者获取root权限。
内容的提问来源于stack exchange,提问作者daveg
相关产品推荐
相关产品推荐

