Freebsd – `kill -s TERM` works, `kill -s ABRT` gets “Operation not permitted”

freebsdkillpermissionsrubysignals

There is a process that I own whose documentation claims I can send SIGABRT to in order to get some debugging information. However, when I try to send SIGABRT, I get back "Operation not permitted".

I have also tried sending the same signals to other processes I own to make sure that there isn't some underlying block preventing me from sending SIGABRT altogether, but they respond in the appropriate manner. It's just this one program, but it's every instance of that program. A system call trace of the process shows that it never receives the signal.

I have tried running /bin/kill explicitly in order to rule out any weirdness in my shell's builtin kill, and, other than some minor output differences, there was no change in behavior.

root can send SIGABRT to the process and it works as I expect it to.

I've been in this game for a while, but I've never seen an instance where a user is not able to send a signal to a process that he owns, nor have I seen an instance where a user can send one signal but not another.

The OS is FreeBSD 9.0 and the process is a ruby process that is part of a Phusion Passenger Ruby-on-Rails application running under Apache.

I'm currently at a total loss. Does anyone have any idea what is going on?

Update: Turns out that the security.bsd.conservative_signals sysctl was set to 1, and that prevents many signals from being delivered to setuid processes, according to the man page. Setting it to 0 solves the problem.

While there was a setuid call somewhere up the process chain — the process is a child of an Apache httpd, and Apache changes its uid to relinquish root permissions — the process itself is not setuid, and its EUID, RUID, and SVUID are all the same as the user sending the signal. The only inspection of the process that I can find that would indicate that any setuid happened is the P_SUGID flag in ps's "flags" field. ("Had set id privileges since last exec") It seems like that shouldn't be the case, but it's handled in an Apache module and I don't know its exact methods.

For the record, it's a ruby process that's functioning as part of a Ruby on Rails application being handled by mod_passenger, AKA mod_rails.

Best Answer

From the latest version of the kill(2) manpage:

For a process to have permission to send a signal to a process designated by pid, the user must be the super-user, or the real or saved user ID of the receiving process must match the real or effective user ID of the sending process. A single exception is the signal SIGCONT, which may always be sent to any process with the same session ID as the sender. In addition, if the security.bsd.conservative_signals sysctl is set to 1, the user is not a super-user, and the receiver is set-uid, then only job control and terminal control signals may be sent (in particular, only SIGKILL, SIGINT, SIGTERM, SIGALRM, SIGSTOP, SIGTTIN, SIGTTOU, SIGTSTP, SIGHUP, SIGUSR1, SIGUSR2).

In what sense do you own the process? What exactly is the status of the process relating to real uid, effective uid, what binary it is running, owner and setid-bits of that binary, etc?

Related Question