Що трапляється, коли користувач, що не користується коренем, надсилає сигнали до процесу користувача root?


33

Мені цікаво про безпеку сигналів UNIX.

SIGKILLвб'є процес. Отже, що відбувається, коли некористувацький користувальницький процес надсилає сигнал користувачу root-процесу? Чи все ще процес виконує обробник сигналу?

Я дотримуюсь прийнятої відповіді (gollum's), і я набираю man capabilites, і я знаходжу багато речей про ядро ​​Linux. Від man capabilities:

NAME

   capabilities - overview of Linux capabilities
DESCRIPTION

   For the purpose of performing permission checks, traditional UNIX
   implementations distinguish two categories of processes: privileged
   processes (whose effective user ID is 0, referred to as superuser or
   root), and unprivileged processes (whose effective UID is nonzero).
   Privileged processes bypass all kernel permission checks, while
   unprivileged processes are subject to full permission checking based
   on the process's credentials (usually: effective UID, effective GID,
   and supplementary group list).

   Starting with kernel 2.2, Linux divides the privileges traditionally
   associated with superuser into distinct units, known as capabilities,
   which can be independently enabled and disabled.  Capabilities are a
   per-thread attribute.

5
Крім того SIGKILL, що є особливим випадком і керується ядром повністю, сигнали - це лише запит. Процес прийому може робити з ними все, що завгодно.
чепнер

3
@chepner Окрім SIGKILL і SIGSTOP ...
jlliagre

1
@chepner Процес прийому повинен активно вирішувати, чи хоче він обробляти сигнал. Якщо процес отримання цього не зробив, то багато сигналів за замовчуванням вбивають процес точно так само, як SIGKILLі. Спочатку SIGINT, SIGKILLі SIGTERMматиме такий самий ефект, різниця полягає лише в тому, що процес отримання може змінити цей дефолт для деяких з них.
kasperd

Відповіді:


34

У Linux це залежить від можливостей файлу.

Візьміть таке просте mykill.cджерело:

#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;
}

побудуйте його:

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

Тепер, як користувацький корінь запускає процес сну у фоновому режимі:

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

Тепер як звичайний користувач намагається його вбити:

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

Тепер, як користувач root змінити /tmp/mykillлітери:

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

І спробуйте знову як звичайний користувач:

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

Нарешті, будь ласка, видаліть /tmp/mykillіз зрозумілих причин;)


3
Дотримуйтесь вашої підказки, я
набираю

24

Нічого:

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

1
Чи здійснюється такий захист рівнем os або жорстко закодовано в обробці сигналу користувача?
lovepring

3
@lovespring Ядро не доставляє сигнал цільовому процесу. Системний виклик повертається з помилкою і крім ігнорованої.
Hauke ​​Laging

Це взагалі не вірно. Це залежить від можливостей.
gollum

1
@psmears так, але інші мають подібні поняття (наприклад, "привілеї" на solaris). Тож відповідь «Нічого», безумовно, неправильна.
gollum

1
@gollum: Це не зовсім неправильно (зрештою, це поведінка за замовчуванням на всіх ОС сімейства Unix, і єдина можлива для багатьох - включаючи старіші ядра Linux, наприклад), але ви маєте рацію, що вона неповна - але лише згадка "можливості", не розглядаючи детальніше про те, де вони підтримуються, також є неповним у запитанні про загальний Unix :)
psmears

5

kill(2) man page пояснює:

Linux Notes

У різних версіях ядра Linux застосував різні правила щодо дозволів, необхідних для непривілейованого процесу для передачі сигналу іншому процесу. У ядрах від 1.0 до 1.2.2 сигнал може бути надісланий, якщо ефективний ідентифікатор користувача відправника відповідає ідентифікатору приймача, або реальний ідентифікатор користувача відправника збігається з таким у приймача. З ядра 1.2.3 до 1.3.77 сигнал може бути надісланий, якщо ефективний ідентифікатор користувача відправника збігається з реальним або ефективним ідентифікатором користувача одержувача. Поточні правила, які відповідають POSIX.1-2001, були прийняті в ядрі 1.3.78.


1.3.78 - надзвичайно давня історія, як 1.3. датується 1995 роком або з тих пір. 1.3 була серія розробок, що вела до 2.0 (у 1996 р.)
фонбранд

-1

сигнал буде нести, але власник процесу належить root. тож інший користувач не має права припиняти процес, тому ви отримаєте проблему з помилкою дозволу.

припинити процес можливо лише тоді, коли ви володієте правом власності (належні права) на процес.


Ні, sys_kill повертає -1 і errno буде -EPERM.
Peterh каже відновити Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.