What happens when a non-root user sends signals to root user's process?

On Linux it depends on the file capabilities.

Take the following simple mykill.c source:

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>

void exit_usage(const char *prog) {
        printf("usage: %s -<signal> <pid>\n", prog);
        exit(1);
}

int main(int argc, char **argv) {
        pid_t pid;
        int sig;

        if (argc != 3)
                exit_usage(argv[0]);

        sig = atoi(argv[1]);
        pid = atoi(argv[2]);

        if (sig >= 0 || pid < 2)
                exit_usage(argv[0]);

        if (kill(pid, -sig) == -1) {
                perror("failed");
                return 1;
        }
        printf("successfully sent signal %d to process %d\n", -sig, pid);

        return 0;
}

build it:

gcc -Wall mykill.c -o /tmp/mykill

Now as user root start a sleep process in background:

root@horny:/root# /bin/sleep 3600 &
[1] 16098

Now as normal user try to kill it:

demouser@horny:/home/demouser$ ps aux | grep sleep
root     16098  0.0  0.0  11652   696 pts/20   S    15:06   0:00 sleep 500

demouser@horny:/home/demouser$ /tmp/mykill -9 16098
failed: Operation not permitted

Now as root user change the /tmp/mykill caps:

root@horny:/root# setcap cap_kill+ep /tmp/mykill

And try again as normal user:

demouser@horny:/home/demouser$ /tmp/mykill -9 16098
successfully sent signal 9 to process 16098

Finally please delete /tmp/mykill for obvious reasons ;)


Nothing:

strace kill -HUP 1
[...]
kill(1, SIGHUP)    = -1 EPERM (Operation not permitted)
[...]

kill(2) man page explains:

Linux Notes

Across different kernel versions, Linux has enforced different rules for the permissions required for an unprivileged process to send a signal to another process. In kernels 1.0 to 1.2.2, a signal could be sent if the effective user ID of the sender matched that of the receiver, or the real user ID of the sender matched that of the receiver. From kernel 1.2.3 until 1.3.77, a signal could be sent if the effective user ID of the sender matched either the real or effective user ID of the receiver. The current rules, which conform to POSIX.1-2001, were adopted in kernel 1.3.78.