【问题标题】:Why do I need setuid(0) within a setuid-root C program that calls an administrative program with system()?为什么在使用 system() 调用管理程序的 setuid-root C 程序中需要 setuid(0)?
【发布时间】:2009-06-26 21:32:17
【问题描述】:

我不得不为某人做一个肮脏的 Linux hack,以便他们可以在作为非 root 用户时使用cupsenable printername shell 命令启动打印机。我不希望他们能够以 root 身份使用整个 cupsenable 语法,所以我只编写了一个 C 包装器,用于清理 argv[1] 中的输入并调用 system("cupsenable sanitizedprintername")

我将程序 setuid 设为 root,但即便如此,cupsenable 仍因“权限被拒绝”而失败。然后我在system() 之前插入了一个setuid(0) 调用,你瞧,它起作用了。

忽略存在让用户控制打印机的更好方法的问题。可能有更好的方法。我感兴趣的是chmod u+ssetuid(0)system() 的复杂性。为什么会这样?

【问题讨论】:

    标签: c unix setuid privilege-elevation


    【解决方案1】:

    来自man system

    不要在具有 set-user-ID 或 set-group-ID 权限的程序中使用 system(),因为某些环境变量的奇怪值可能会被用来破坏系统完整性。请改用exec(3) 系列函数,但不要使用execlp(3)execvp(3)。事实上,system()/bin/sh 是 bash 版本 2 的系统上无法从具有 set-user-ID 或 set-group-ID 特权的程序正常工作,因为 bash 2 在启动时会放弃特权。

    来自man bash

    如果 shell 以不等于实际用户(组)id 的有效用户(组)id 启动,并且未提供-p 选项,则不读取启动文件,不继承 shell 函数环境中,SHELLOPTS变量,如果出现在环境中,则忽略,有效用户id设置为真实用户id。

    您的setuid(0) 呼叫似乎绕过了该保护。

    【讨论】:

    • 哇。好吧,我确实说过它很脏。我所做的似乎是让 system() 产生的 bash 进程相信我实际上,真的,老实说是 root,对上帝发誓。似乎需要进行一些重构。
    猜你喜欢
    • 2015-04-08
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    相关资源
    最近更新 更多