【问题标题】:library (.so) with root privilege具有 root 权限的库 (.so)
【发布时间】:2018-01-17 16:32:48
【问题描述】:

我有一个使用一些 C 库的 C++ 程序。该程序以“非特权”用户身份执行,但程序加载的库 (.so) 的一个且只有一个函数需要 root 权限(它需要写入 /dev/mem)。

是否有一种方法可以只让那个函数或那个库以 root 身份执行,而让所有其余代码“无特权”?

谢谢大家, 克里斯蒂安

【问题讨论】:

  • 没有。权限是每个进程的。
  • 我不这么认为,那将是巨大的安全漏洞。我知道的唯一方法是 suid app。
  • 我同意安全问题,但此时的替代方案是以root身份执行整个程序,随之而来的安全问题(我无法检查整个库源中的安全漏洞)

标签: c++ c linux root


【解决方案1】:

快速回答是。您不能在每个库的基础上切换用户 ID,因为用户身份是每个进程的属性(如果您尝试深入了解 /dev/mem 设备,您至少应该知道这一点)。

运行时库加载是一个库任务(它是由我的系统中称为动态加载器的共享对象ld-linux-x86-64.so.2 完成的)并且它是在运行时完成的,因此为了安全起见,不能授予它特权访问权限原因。

无论如何,程序的 setuid 属性允许您在 有效 用户(这是 setuid 用户)和 real 用户(执行程序)并返回,所以在root帐户的特殊情况下,您可以使用它来访问/dev/mem

无论如何,除了访问问题之外,写入/dev/mem 是非常危险的,因为它映射到机器的物理地址空间(因此,它作为物理页面存在,来自不同的进程和内核,没有明显命令)。这必须通过可用的转换表来完成,因为页面以非常动态的方式来来去去交换。无论如何,您都在触及内核内存,因此在此处写入时必须格外小心。我不知道你想做什么,但你最好在写之前三思而后行(从你的问题来看,你对进程的属性不够了解,很可能你也不知道内核中保存的页面的虚拟到物理转换)。

但是,如果您想使系统崩溃,这是一个完美的方法。无论如何,如果那是您追求的目标,那么只需将整个程序设置为根(如果您知道这句话的意思)并继续。或者更好的是,以 root 用户身份进行操作,这样您就无需担心 setuid 之类的问题。

【讨论】:

  • 感谢您的关注,但我们需要写入 /dev/mem 以打开/关闭设备。该功能不是由我编写的,而是由谁设计了连接设备的电路板,所以他知道自己在做什么。而且我们没有其他选择。根据其他人的建议,我将尝试使用 seteuid() 函数在以 root 身份打开 /dev/mem 后更改权限。
  • @CDF,那么使用映射到内核虚拟内存空间的/dev/kmem 可能会更好。这样,您可以使用内核内存映射,而不必自己翻译。无论如何,一个简单的设备开发将是一个更好的解决方案,因为您继续进行的方式,没有机会能够阻止或阻止同时访问同一个地方,并使整个系统崩溃。我认为您不知道自己在计划什么……设备驱动程序将是实现此目的的解决方案。
  • 我将您对使用 /dev/kmem 的建议转发给开发人员,谢谢。
  • 不,我的建议是不要使用/dev/kmem,而是编写驱动程序...驱动程序是控制设备的唯一东西.....如果您尝试通过写入来控制它/dev/kmem 你也会让事情崩溃...... /dev/kmem 强烈反对使用。请永远不要说我建议使用/dev/kmem 来停止设备......我从来没有这样做过。而且,为什么不是问问题的开发人员。你觉得在这两者之间需要你吗?
  • 长话短说 非常非常 短(因​​为 cmets 有字符限制):这里的硬件/库人员擅长硬件/内核/设备的东西,但不擅长安全性问题。我是被雇用的“最后一个人”,在我到达之前,他们通常习惯于以 root 执行所有软件(是的,我知道:你还记得我说他们不擅长的部分吗?安全?)。所以我正在努力强化系统。哦,我没有提到其他不允许我们以不同方式进行的约束。
【解决方案2】:

以 root 身份启动程序并将 /dev/mem 作为文件打开。然后将用户 ID 更改为不那么具有侵入性的内容。该文件将保留其原始权限。

【讨论】:

  • 哦,好的提示,我学到了一些新东西,谢谢!目前我不能这样做,因为 /dev/mem 每次在启动时调用函数时都会打开。但我可以尝试向函数开发者提出修改建议。
最近更新 更多