`kill -s TERM` 有效,`kill -s ABRT` 得到“不允许操作”

`kill -s TERM` 有效,`kill -s ABRT` 得到“不允许操作”

我拥有一个进程,其文档声称我可以发送SIGABRT到该进程以获得一些调试信息。但是,当我尝试发送时SIGABRT,我返回“不允许操作”。

我还尝试向我拥有的其他进程发送相同的信号,以确保没有某些底层块阻止我SIGABRT完全发送,但它们以适当的方式响应。这只是一个程序,但它是该程序的每个实例。该进程的系统调用跟踪显示它从未收到该信号。

我尝试/bin/kill显式运行,以排除 shell 内置的任何奇怪现象kill,并且,除了一些细微的输出差异之外,行为没有任何变化。

root 可以发送SIGABRT到进程并且它按我的预期工作。

我玩这个游戏已经有一段时间了,但我从未见过用户无法向他拥有的进程发送信号的实例,也没有见过用户可以发送一个信号但不是另一个。

操作系统是 FreeBSD 9.0,该进程是一个 ruby​​ 进程,是在 Apache 下运行的 Phusion Passenger Ruby-on-Rails 应用程序的一部分。

我目前完全不知所措。有谁知道发生了什么事吗?

更新:根据手册页,事实证明security.bsd.conservative_signalssysctl 设置为 1,这会阻止许多信号传递到 setuid 进程。将其设置为 0 即可解决该问题。

虽然在进程链的某个地方有一个 setuid 调用——该进程是 Apache httpd 的子进程,并且 Apache 更改其 uid 以放弃 root 权限——但该进程本身不是 setuid,它的 EUID、RUID 和 SVUID 都是与发送信号的用户相同。我能找到的唯一可以表明发生任何 setuid 的进程检查是“flags”字段P_SUGID中的标志。 ps(“自上次执行以来已设置 id 权限”)似乎不应该是这样,但它是在 Apache 模块中处理的,我不知道它的确切方法。

需要说明的是,它是一个 ruby​​ 进程,作为 Ruby on Rails 应用程序的一部分运行,由 mod_passenger(又名 mod_rails)处理。

答案1

来自最新版本的kill(2) 联机帮助页:

要使进程有权向 pid 指定的进程发送信号,用户必须是超级用户,或者接收进程的真实或保存的用户 ID 必须与发送进程的真实或有效用户 ID 相匹配。一个例外是信号 SIGCONT,它可能始终被发送到与发送方具有相同会话 ID 的任何进程。此外,如果 security.bsd.conservative_signals sysctl 设置为 1,则用户不是超级用户,并且接收者为 set-uid,则只能发送作业控制和终端控制信号(特别是,只能发送 SIGKILL、SIGINT、SIGTERM、SIGALRM、SIGSTOP、SIGTTIN、SIGTTOU、SIGTSTP、SIGHUP、SIGUSR1、SIGUSR2)。

您在什么意义上拥有该流程?与真实 uid、有效 uid、正在运行的二进制文件、该二进制文件的所有者和 setid 位等相关的进程状态到底是什么?

相关内容