我有一个C ++程序,它将以root身份运行某些非常具体的命令。需要这样做的原因是因为在Node.js下运行的另一个程序需要执行诸如设置系统时间,设置时区等需要root权限才能完成的事情。我使用C ++中的函数execve在使用setuid命令后使用root权限进行系统调用。我特意选择execve命令,因为我想隔离环境,所以我不创建环境变量漏洞。
setuid(0);
execve(acExeName, pArgsForExec2, pcEnv);
我想要做的是确切地找出pcEnv,它是程序要执行的环境变量列表,我的程序需要它。例如,如果我想运行工具time-admin,就像我从控制台运行它一样,我怎样才能找出它需要的环境变量。我知道我可以使用命令printenv打印环境变量,但这给了我所有这些。我很确定我并不需要它们,并希望尽可能小的一部分。
我知道我可以全部使用它们然后慢慢评论每一个,看看它是否继续工作,但我真的不想走那么远。
任何人都有一个聪明的方法来弄清楚程序使用了哪些环境变量?我应该在Ubuntu 12.04 LTS安装上添加我这样做。
感谢您的帮助。
答案 0 :(得分:2)
没有通用的方法来确定某些程序使用的环境变量。例如,可以想象一个程序有一些配置文件,它们给出了环境变量的名称。
实际上很多类似shell的程序(或脚本解释器)正在这样做。
更一般地说,可以计算getenv(3)的参数。所以理论上你无法猜测它的可能值。 (我可能错了,但是libc
和bash
的一些非常旧的版本曾经玩过这样的技巧;不幸的是,我忘记了细节,但有时候一个环境变量的名字中有一些pid号是使用)。
并且,正如其他人评论的那样,您可能想要使用ltrace
(或玩LD_PRELOAD
技巧)或使用gdb
来了解getenv
被称为......
应用程序也可能使用environ
变量(请参阅environ(7) ...)或main
的第三个参数....
然而,在实践中,合理编写的程序应该清楚地记录它正在使用的所有环境变量....
如果您有权访问该程序的源代码,如果它是由GCC编译的,则可以使用MELT plugin的刚刚发布的版本1.0。 MELT是一种扩展GCC的领域特定语言,可用于在编译程序时探索GCC处理的内部Gimple表示。特别是使用新的findgimple
mode,您可以在一个命令中找到所有对getenv
的调用,并使用常量字符串。