作为Apache CGI程序运行的C ++程序无法通过shmget访问共享内存

时间:2014-03-07 04:07:20

标签: c++ apache cgi

Apache CGI进程显然无法创建共享内存? shmget()将返回EACCES,权限被拒绝错误。有谁知道我怎么能超越这个?我在Linux(Fedora 17 w / 3.9.10-100内核)和Apache 2.2.23上运行。这是一个封闭的系统,所以我并不关心这可能导致的安全漏洞。

这是一个最小的CGI程序:

#include <iostream>
#include <string.h>
#include <sys/shm.h>
#include <errno.h>

using namespace std;

int main()
{
  cout << "Content-Type: text/plain" << endl << endl;

  if(shmget(0x1234, 1000, IPC_CREAT | 0666) < 0) {
    cout << "Error: " << strerror(errno) << endl;
  } else {
    cout << "Success!" << endl;
  }

  return 0;
}

这是最小的HTML:

<html>
<body>
  <form action="/cgi-bin/sscce" method="post">
    <input type="submit" value="Go" id="submit"/>
  </form>
</body>
</html>

以下是命令行的结果:

$ ./run
Content-Type: text/plain

Success!
$ ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00001234 29917185   root       666        1000       0
$ ipcrm -m 29917185
$

这是通过Apache运行的结果:

Content-Type: text/plain

Error: Permission denied

它正在返回EACCES。其他CGI的东西工作得很好。所以,我尝试过的事情:

  • 将Apache更改为与命令行上的用户相同(无帮助)
  • “chmod + s”在可执行文件上以root权限运行(没有帮助)
  • 可执行文件(以及httpd可执行文件)上的“setcap cap_ipc_owner + iep”,因为shmget()的手册页说它需要CAP_IPC_OWNER功能或者将返回EACCES(没有帮助)

我有点在我的智慧结束。不知何故,Apache正在剥离CGI脚本(甚至以root身份运行)创建一大块共享内存的能力?谷歌搜索出现了其他几个经历过这个问题的人,但没有解决方案。此外,如果我预先创建共享内存,同样的事情发生... shmget()在尝试连接到共享内存的读取时返回EACCES w / 0666的权限。任何想法?提前谢谢。

1 个答案:

答案 0 :(得分:1)

好的,我终于找到了答案。问题是SELinux。在/ var / log / messages中:

SELinux is preventing <executable> from using the sys_resource capability.

通过编辑/ etc / sysconfig / selinux关闭SELinux允许CGI进程使用shmget()。但是,我不知道关闭SELinux的全部后果。在我们的封闭系统中,我认为这不是什么大问题,但对于其他情况,可能有一个较小的锤子解决方案。但这是总的方向。希望它能帮到某个人。