Cosa succede quando un utente non root invia segnali al processo dell'utente root?


33

Mi chiedo la sicurezza dei segnali UNIX.

SIGKILLucciderà il processo. Quindi, cosa succede quando il processo di un utente non root invia un segnale al processo di un utente root? Il processo esegue ancora il gestore del segnale?

Seguo la risposta accettata (di Gollum) e scrivo man capabilitese trovo molte cose sul kernel di Linux. Da 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
A parte questo SIGKILL, che è un caso speciale e gestito completamente dal kernel, i segnali sono semplicemente una richiesta. Il processo di ricezione può fare tutto ciò che vogliono con loro.
Chepner,

3
@chepner Altro che SIGKILL e SIGSTOP ...
jlliagre

1
@chepner Il processo di ricezione deve decidere attivamente di voler gestire il segnale. Se il processo di ricezione non lo ha fatto, molti segnali per impostazione predefinita uccideranno il processo esattamente allo stesso modo SIGKILL. Inizialmente SIGINT, SIGKILLe SIGTERMavrà esattamente lo stesso effetto, l'unica differenza è che il processo di ricezione può modificare questo valore predefinito per alcuni di essi.
Kasperd,

Risposte:


34

Su Linux dipende dalle capacità del file.

Prendi la seguente semplice mykill.cfonte:

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

costruiscilo:

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

Ora come utente root avvia un processo di sospensione in background:

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

Ora come normale utente tenta di ucciderlo:

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

Ora come utente root cambia i /tmp/mykilltappi:

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

E riprova come utente normale:

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

Infine, /tmp/mykillper favore cancella per ovvi motivi;)


3
Segui il tuo indizio,
scrivo

24

Niente:

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

1
Questo tipo di sicurezza viene eseguito a livello di sistema operativo o codificato nel gestore di segnali dell'utente?
lovepring

3
@lovespring Il kernel non invia il segnale al processo di destinazione. Il syscall viene restituito con un errore e a parte quello ignorato.
Hauke ​​Laging

Questo non è vero in generale. Dipende dalle capacità.
gollum,

1
@psmears sì, ma altri hanno concetti simili (ad es. "privilegi" su solaris). Quindi la risposta "Niente" è decisamente sbagliata.
gollum,

1
@gollum: Non è esattamente sbagliato (dopotutto, è il comportamento predefinito su tutti i sistemi operativi della famiglia Unix e l'unico possibile su molti - inclusi i kernel Linux più vecchi per esempio) ma hai ragione sul fatto che è incompleto - ma solo menzionando le "capacità" senza entrare nel dettaglio di dove sono supportate sono anche incomplete in una domanda sul generale Unix :)
psmears

5

kill(2) la pagina man spiega:

Note Linux

In diverse versioni del kernel, Linux ha imposto regole diverse per le autorizzazioni necessarie per un processo senza privilegi per inviare un segnale a un altro processo. Nei kernel da 1.0 a 1.2.2, un segnale potrebbe essere inviato se l'ID utente effettivo del mittente corrispondesse a quello del destinatario, o l'ID utente reale del mittente corrispondesse a quello del destinatario. Dal kernel 1.2.3 all'1.3.77, potrebbe essere inviato un segnale se l'ID utente effettivo del mittente corrispondesse all'ID utente reale o effettivo del destinatario. Le regole attuali, conformi a POSIX.1-2001, sono state adottate nel kernel 1.3.78.


1.3.78 è una storia estremamente antica, come 1.3. risale al 1995 o più tardi. 1.3 era la serie di sviluppo che portava al 2.0 (nel 1996)
vonbrand il

-1

il segnale sarebbe portato ma il proprietario del processo appartiene al root. quindi, l'altro utente non ha il diritto di terminare il processo in modo da ricevere un problema di errore di autorizzazione.

terminare il processo è possibile solo se si possiede la proprietà (diritti propri) del processo.


No, sys_kill restituisce -1 e errno sarà -EPERM.
Peter dice di reintegrare Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.