루트가 아닌 사용자가 루트 사용자의 프로세스에 신호를 보내면 어떻게됩니까?


33

UNIX 신호의 보안에 대해 궁금합니다.

SIGKILL프로세스를 종료합니다. 루트가 아닌 사용자 프로세스가 루트 사용자의 프로세스에 신호를 보내면 어떻게됩니까? 프로세스가 여전히 신호 핸들러를 수행합니까?

나는 받아 들인 대답 (골룸)을 따르고 입력 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특별한 경우이며 커널이 완전히 관리하는 이외의 신호는 단지 요청 일뿐입니다. 수신 프로세스는 원하는대로 무엇이든 할 수 있습니다.
chepner

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 사용자는 백그라운드에서 절전 프로세스를 시작합니다.

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

이제 루트 사용자가 /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
당신의 실마리를 따르고, "사람의 능력"을 입력하고 리눅스 커널에 대해 많은 것을 발견합니다
lovespring

24

아무것도:

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

1
이런 종류의 보안은 OS 레벨에 의해 수행되거나 사용자의 신호 처리기에 하드 코딩되어 있습니까?
lovespring

3
@lovespring 커널은 신호를 대상 프로세스에 전달하지 않습니다. syscall은 오류와 함께 반환되며 무시됩니다.
Hauke ​​Laging

그것은 일반적으로 사실이 아닙니다. 기능에 따라 다릅니다.
gollum

1
@psmears는 그렇습니다. 그러나 다른 개념도 비슷합니다 (예 : solaris의 "권한"). 따라서 "아무것도"라는 대답은 분명히 틀 렸습니다.
gollum

1
@gollum : 그것은 정확히 잘못 은 아닙니다 (결국 모든 유닉스 계열 OS의 기본 동작이며, 예를 들어 오래된 Linux 커널을 포함하여 많은 경우 유일하게 가능합니다).하지만 불완전하다는 것은 옳습니다. 그들이 지원되는 장소에 대해 더 자세하게 설명하지 않고 "기능"도 일반 유닉스에 대한 질문에서 불완전하다 :)
psmears

5

kill(2) 매뉴얼 페이지 설명 :

리눅스 노트

여러 커널 버전에서 Linux는 권한이없는 프로세스가 다른 프로세스에 신호를 보내는 데 필요한 권한에 대해 다른 규칙을 시행했습니다. 커널 1.0에서 1.2.2까지, 발신자의 유효 사용자 ID가 수신자의 유효 사용자 ID와 일치하거나 발신자의 실제 사용자 ID가 수신자의 실제 사용자 ID와 일치하면 신호가 송신 될 수 있습니다. 커널 1.2.3에서 1.3.77까지, 발신자의 유효 사용자 ID가 수신자의 실제 또는 유효 사용자 ID와 일치하면 신호가 송신 될 수 있습니다. POSIX.1-2001을 준수하는 현재 규칙은 커널 1.3.78에서 채택되었습니다.


1.3.78은 1.3과 같은 매우 오래된 역사입니다. 1995 년 또는 그 이후의 날짜. 1.3은 2.0으로 이어지는 개발 시리즈였습니다 (1996 년)
vonbrand

-1

신호는 전달하지만 프로세스 소유자는 루트에 속합니다. 따라서 다른 사용자에게는 프로세스를 종료 할 권한이 없으므로 권한 오류 문제가 발생합니다.

프로세스 종료는 프로세스의 소유권 (적절한 권리)을 소유 한 경우에만 가능합니다.


아니요, sys_kill은 -1을 반환하고 errno는 -EPERM이됩니다.
peterh는 모니카 복원
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.