gpt4 book ai didi

setuid 包装器的注意事项

转载 作者:太空狗 更新时间:2023-10-29 15:08:35 25 4
gpt4 key购买 nike

我编写的一个 Python 扩展需要 root 访问权限才能执行单个硬件初始化调用。我不想仅仅为了我的扩展中的这个调用而以 root 身份运行整个脚本,所以我想编写一个包装器来执行此初始化,然后再降低到用户权限并运行实际脚本。

我打算让这个包装器通过 sudo 运行,例如

$ sudo devwrap python somescript.py

我正在考虑类似(更新以修复几个错误):

int main(int argc, char * argv[])
{
if(argc < 2) return 0;

int res = do_hardware_init();
if(res != OK_VALUE)
{
// Print error message
return HW_ERR;
}

const char *sudo_uid = getenv("SUDO_UID");
if(sudo_uid)
{
int real_uid = (int) strtol(sudo_uid, NULL, 0);
setuid(real_uid);
}

return execvp(argv[1], &argv[1]); // No return if successful

}

所以我有三个问题:

  1. 这看起来正常吗?我通常不需要弄乱 *uid() 调用,所以我不熟悉通常的陷阱。 execvp 调用看起来也有点奇怪,但据我所知,它在正确的位置有参数)。
  2. execvp 手册页说“应用程序不应直接访问 environ 数组” - 这是否会调用 getenv一个坏主意?
  3. 有没有比 execvp 更好的调用,所以我可以执行 sudo devwrap somescript.py(注意缺少“python”)

最佳答案

  1. 有点理智......下面有更多内容。
  2. 使用 getenv() 不是直接访问 environ 数组 - 这是干净的。直接访问 environ 数组意味着“strcpy(buffer, environ[3])”或类似的东西。
  3. 如果脚本以 shebang 开头(可能是 #!/usr/bin/env python),您已经可以做您想做的事了 - somescript.py当然,必须是可执行的。

我在第一部分看到的问题取决于您如何处理硬件初始化错误。如果省略的错误处理没有退出,那么当你没有通过“sudo”运行时,你可能会得到一个核心转储(或段错误),因为你在空指针上运行 strtol()。如果 do_hardware_init() 本身在失败时退出,则没有问题,除非用户找到一种方法从“sudo”破坏环境。我真的认为如果 SUDO_UID 没有合理设置,你应该验证环境并退出并出现错误。 root 会想要运行这个扩展吗?

我没有查看 sudo 的规范,看它确实设置了 SUDO_UID 环境变量 - 我假设你是正确的。

用户键入此内容会产生什么后果?

sudo devwrap ls

它执行硬件初始化、重置 UID,然后运行 ​​ls - 可能不会造成太大危害,但可能不是您想要的。那有关系吗?你能完全控制它吗?

如果参数计数小于两个,您可能应该给出错误退出,而不是成功退出。


要求人们通过“sudo”运行扩展是非常不合常规的。

您确定没有其他方法可以实现吗?初始化有什么要求?是对所有进程执行一次,还是每个进程执行一次(因此链接至关重要)?


你能简单地让 devwrap 程序成为 SUID root 吗?然后,您需要以不同方式重置 UID:

setgid(getgid());
setuid(getuid());

这会在执行命令之前删除任何 SGID-ness 和任何 SUID-ness。很难造成重大损害。如果安装的程序没有 SGID,则 setgid() 调用是否是强制性的尚不清楚,但这也没有坏处。

关于setuid 包装器的注意事项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4212387/

25 4 0
文章推荐: android - 在 1 行和多列中显示带有水平滚动条的 GridView 或画廊的图像和文本
文章推荐: html - 语义标记 : Why <header> instead of
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com