You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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权限来设置程序:

  1. 先把程序的所有者改为root:
    sudo chown root:root your_program
    
  2. 给程序设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 06:52:48