Điều gì xảy ra khi người dùng không root gửi tín hiệu đến tiến trình của người dùng root?


33

Tôi đang tự hỏi về tính bảo mật của tín hiệu UNIX.

SIGKILLsẽ giết quá trình. Vậy, điều gì xảy ra khi một quá trình người dùng root không gửi tín hiệu đến tiến trình của người dùng root? Liệu quá trình vẫn thực hiện xử lý tín hiệu?

Tôi làm theo câu trả lời được chấp nhận (gollum's) và tôi gõ man capabilitesvà tôi tìm thấy rất nhiều điều về nhân Linux. Từ 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
Khác với SIGKILL, đó là trường hợp đặc biệt và được quản lý hoàn toàn bởi kernel, tín hiệu chỉ là một yêu cầu. Quá trình tiếp nhận có thể làm bất cứ điều gì họ muốn với họ.
chepner

3
@chepner Khác SIGKILL SIGSTOP ...
jlliagre

1
@chepner Quá trình nhận phải chủ động quyết định nó muốn xử lý tín hiệu. Nếu quy trình nhận không được thực hiện như vậy, thì rất nhiều tín hiệu theo mặc định sẽ giết quá trình theo cách chính xác như vậy SIGKILL. Ban đầu SIGINT, SIGKILLSIGTERMsẽ có cùng hiệu ứng, sự khác biệt duy nhất là quá trình nhận có thể thay đổi mặc định này đối với một số trong số chúng.
kasperd

Câu trả lời:


34

Trên Linux, nó phụ thuộc vào khả năng của tập tin.

Lấy mykill.cnguồn đơn giản sau :

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

xây dựng nó:

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

Bây giờ khi người dùng root bắt đầu một quá trình ngủ trong nền:

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

Bây giờ như người dùng bình thường cố gắng để giết nó:

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

Bây giờ khi người dùng root thay đổi giới /tmp/mykillhạn:

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

Và thử lại như người dùng bình thường:

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

Cuối cùng xin vui lòng xóa /tmp/mykillvì lý do rõ ràng;)


3
Theo manh mối của bạn, tôi gõ "khả năng của người đàn ông" và tôi tìm thấy rất nhiều điều về kernel linux
lovepring

24

Không có gì:

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

1
Đây có phải là loại bảo mật được thực hiện bởi cấp độ os hoặc mã hóa cứng trong trình xử lý tín hiệu của người dùng?
lovespring

3
@lovespring Hạt nhân không cung cấp tín hiệu cho quá trình đích. Tòa nhà được trả lại với một lỗi và ngoài việc bỏ qua.
Hauke ​​Laging

Điều đó không đúng nói chung. Nó phụ thuộc vào khả năng.
gollum

1
@psmears có, nhưng những người khác có khái niệm tương tự (ví dụ: "đặc quyền" trên solaris). Vì vậy, câu trả lời "Không có gì" chắc chắn là sai.
gollum

1
@gollum: Điều đó không hoàn toàn sai (xét cho cùng, đó là hành vi mặc định trên tất cả các HĐH gia đình Unix và là điều duy nhất có thể có trên nhiều - ví dụ như các nhân Linux cũ hơn) nhưng bạn nói đúng là nó chưa hoàn chỉnh - nhưng chỉ đề cập đến "các khả năng" mà không đi sâu vào chi tiết hơn về nơi chúng được cung cấp cũng không đầy đủ trong một câu hỏi về Unix nói chung :)
psmears

5

kill(2) trang người đàn ông giải thích:

Ghi chú Linux

Trên các phiên bản kernel khác nhau, Linux đã thực thi các quy tắc khác nhau cho các quyền cần thiết cho một quy trình không có đặc quyền để gửi tín hiệu đến một quy trình khác. Trong các hạt 1.0 đến 1.2.2, tín hiệu có thể được gửi nếu ID người dùng hiệu quả của người gửi khớp với ID của người nhận hoặc ID người dùng thực của người gửi khớp với tín hiệu của người nhận. Từ kernel 1.2.3 đến 1.3.77, tín hiệu có thể được gửi nếu ID người dùng hiệu quả của người gửi khớp với ID người dùng thực hoặc hiệu quả của người nhận. Các quy tắc hiện hành, phù hợp với POSIX.1-2001, đã được thông qua trong kernel 1.3.78.


1.3.78 là lịch sử vô cùng cổ xưa, như 1.3. ngày từ năm 1995 hoặc sau đó. 1.3 là chuỗi phát triển dẫn đến 2.0 (năm 1996)
vonbrand

-1

tín hiệu sẽ mang nhưng chủ sở hữu quá trình thuộc về root. vì vậy, người dùng khác không có quyền chấm dứt quá trình nên bạn sẽ gặp vấn đề về quyền.

quá trình chấm dứt chỉ có thể khi bạn sở hữu quyền sở hữu (quyền thích hợp) của quy trình.


Không, sys_kill trả lại -1 và errno sẽ là -EPERM.
peterh nói rằng phục hồi Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.