从 apache 正在运行的 c++ 代码调用 bash 脚本的权限问题

Posted

技术标签:

【中文标题】从 apache 正在运行的 c++ 代码调用 bash 脚本的权限问题【英文标题】:Permissions issue calling bash script from c++ code that apache is running 【发布时间】:2014-10-30 15:19:12 【问题描述】:

此代码的目标是在捕获 sigterm/sigint/sigsegv/etc 时创建堆栈跟踪。为了在 sigsegv 的情况下不依赖于 C++ 代码内部的内存管理,我决定编写一个 bash 脚本来接收跟踪数组中的 PID 和内存地址。 正在捕获 Sig 事件。

下面是我生成对 bash 脚本的调用的地方

trace_size = backtrace(trace, 16);
trace[1] = (void *)ctx->rsi;
messages = backtrace_symbols(trace, trace_size);

char syscom[356] = 0;
sprintf(syscom,"bash_crash_supp.sh %d", getpid());
for (i=1; i<(trace_size-1) && i < 10; ++i)

    sprintf(syscom,"%s %p",syscom,trace[i]);

下面是我的问题出现的地方。 syscom 中的命令生成正确。我可以在以下弹出之前停止代码,在终端中运行命令,它可以正常运行。 但是,直接从 c++ 代码运行脚本似乎不起作用。

setuid(0);
FILE *bashCommand = popen(syscom,"r");

char buf[256] = 0;
while(fgets(buf,sizeof(buf),bashCommand) != 0) 
    LogMessage(LOG_WARNING, "%s\n", buf);

pclose(bashCommand);
exit(sig);

bash 脚本的目的是从 /proc/pid/maps 中获取偏移量,然后使用它来运行 addr2line 以获取文件名/行号。

strResult=$(sudo cat /proc/"$1"/maps | grep "target_file" | grep -m 1 '[0-9a-fA-F]')

offset=$( cut -d '-' -f 1 <<< "$strResult");

但是,当我从 c++ 代码运行时,偏移量变为 0,但是当我在终端中运行完全相同的命令(存储在 c++ 代码中的 syscom 中)时,我得到了预期的输出。

我一直在尝试解决这个问题。权限很可能是问题所在,但我已经尝试用我知道/通过谷歌看到的每一种方式来解决这些问题。尝试运行脚本的用户(当前正在运行 c++ 代码)是 apache。

修复不需要担心盒子的安全性。如果像“chmod 777 /proc -r”这样简单的东西有效,那将是解决方案(遗憾的是操作系统不允许我用 /proc 做这样的命令)。

我已经尝试过的事情:

在 C++ 代码中存储在 syscom 中的命令周围添加 `` chown 脚本到 apache bash_crash_supp.sh 脚本上的 chmod 4755,使其始终以 root 身份触发。 我已将 apache 添加到 sudoers (visudo),允许他们在不使用密码的情况下运行 sudo 我在 sudoers.d 中添加了一个子文件(以防万一),其作用与上述相同 我查看了 objdump,但它没有给我地址的偏移量或文件/行号(据我所知) 我在c++代码中有setuid(0)设置当前用户为root

用 C++ 生成的命令 bash_crash_supp.sh 25817 0x7f4bfe600ec8 0x7f4bf28f7400 0x7f4bf28f83c6 0x7f4bf2904f02 0x7f4bfdf0fbb0 0x7f4bfdf1346e 0x7f4bfdf1eb30 0x7f4bfdf1b768 0x7f4bfdf1b768

bash 中的参数: 25817 0x7f4bfe600ec8 0x7f4bf28f7400 0x7f4bf28f83c6 0x7f4bf2904f02 0x7f4bfdf0fbb0 0x7f4bfdf1346e 0x7f4bfdf1eb30 0x7f4bfdf1b9a8 0x7f4bf1b9a8 0x7f4bf

谁能想到任何其他的方法来解决这个问题?

【问题讨论】:

1) 在bash_crash_supp.sh 脚本中你的shabang 是什么(以#! 开头的行)和2) 在shell 脚本中包含echo "$*" 并发布结果。 #!/bin/bash 是顶部的shabang。添加了参数的回声,以及从 c++ 代码生成的命令 strResult 包含什么?你能做一个echo "$strResult" 并发布它吗?如果问题是运行错误的命令或获得错误的输出,请尝试缩小范围。 strResult 什么都不包含,这就是为什么我认为这是一个权限问题,如果我以我的用户(而不是 apache)在终端中运行 strResult=$(sudo ...) 命令,它可以工作。 好的,时间到了。在脚本开头附近包含whoami 以验证它以root 身份运行。尝试strResult=$(sudo cat /proc/"$1"/maps 2&gt;&amp;1),然后立即echo $? 检查返回码,然后echo "$strResult" 看看您是否捕获了任何 STDERR 输出。 【参考方案1】:

长话短说,几乎所有基于 Unix 的系统都会忽略任何解释脚本上的 setuid(任何带有 shebang #!)作为安全预防措施。

您可以在实际的可执行文件上使用setuid,但不能在 shell 脚本本身上使用。如果你愿意冒巨大的安全风险,你可以制作一个包装器executable来运行shell脚本并提供可执行文件setuid

有关更多信息,请参阅 Unix StackExchange 上的此问题:https://unix.stackexchange.com/a/2910

【讨论】:

以上是关于从 apache 正在运行的 c++ 代码调用 bash 脚本的权限问题的主要内容,如果未能解决你的问题,请参考以下文章

“运行时检查失败 #0 - ESP 的值未在函数调用中正确保存”从 C++ 代码成功 C# 回调后

从python调用c++函数

一组线程的 C++ 互斥锁

你可以从 C++ 运行 C# 代码吗?

分析由 JNI 调用运行的 Java

C++ DLL 返回从 Python 调用的指针