จะเกิดอะไรขึ้นเมื่อผู้ใช้ที่ไม่ใช่รูทส่งสัญญาณไปยังกระบวนการของผู้ใช้รูท


33

ฉันสงสัยเกี่ยวกับความปลอดภัยของสัญญาณ UNIX

SIGKILLจะฆ่ากระบวนการ ดังนั้นจะเกิดอะไรขึ้นเมื่อกระบวนการของผู้ใช้ที่ไม่ใช่รูทส่งสัญญาณไปยังกระบวนการของผู้ใช้รูท กระบวนการยังคงดำเนินการตัวจัดการสัญญาณหรือไม่?

ฉันทำตามคำตอบที่ยอมรับ (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ซึ่งเป็นกรณีพิเศษและจัดการอย่างสมบูรณ์โดยเคอร์เนลสัญญาณเป็นเพียงการร้องขอ กระบวนการรับสามารถทำทุกอย่างที่พวกเขาต้องการได้
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@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
ติดตามเบาะแสของคุณฉันพิมพ์ "ความสามารถของมนุษย์" และฉันพบสิ่งต่างๆมากมายเกี่ยวกับเคอร์เนลลินุกซ์
2559

24

ไม่มีอะไร:

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

1
การรักษาความปลอดภัยแบบนี้ทำได้โดยใช้ระดับระบบปฏิบัติการหรือฮาร์ดโค้ดในเครื่องมือจัดการสัญญาณของผู้ใช้หรือไม่?
lovespring

3
@lovespring เคอร์เนลไม่ได้ส่งสัญญาณไปยังกระบวนการเป้าหมาย syscall จะถูกส่งกลับโดยมีข้อผิดพลาดและนอกเหนือจากนั้นจะถูกละเว้น
Hauke ​​Laging

นั่นไม่เป็นความจริงโดยทั่วไป มันขึ้นอยู่กับความสามารถ
กอลลัม

1
@psmears ใช่ แต่คนอื่น ๆ มีแนวคิดที่คล้ายคลึงกัน (เช่น "สิทธิพิเศษ" บน Solaris) ดังนั้นคำตอบ "ไม่มีอะไร" นั้นผิดอย่างแน่นอน
กอลลัม

1
@gollum: มันไม่ถูกต้องอย่างแน่นอน(หลังจากทั้งหมดมันเป็นพฤติกรรมเริ่มต้นในระบบปฏิบัติการยูนิกซ์ตระกูลทั้งหมดและเป็นสิ่งเดียวที่เป็นไปได้สำหรับหลาย ๆ คน - รวมถึง Linux เมล็ดเก่าเช่น) แต่คุณพูดถูกว่าไม่สมบูรณ์ - แต่เพียงแค่พูดถึง "ความสามารถ" โดยไม่ต้องไปลงในรายละเอียดเพิ่มเติมเกี่ยวกับการที่พวกเขาจะ suported นี้ยังไม่สมบูรณ์ในคำถามเกี่ยวกับระบบปฏิบัติการยูนิกซ์ทั่วไป :)
psmears

5

kill(2) หน้าคนอธิบาย:

หมายเหตุของ Linux

ในเวอร์ชันเคอร์เนลที่ต่างกัน Linux ได้บังคับใช้กฎที่แตกต่างกันสำหรับสิทธิ์ที่จำเป็นสำหรับกระบวนการที่ไม่ได้รับสิทธิพิเศษเพื่อส่งสัญญาณไปยังกระบวนการอื่น ในเคอร์เนล 1.0 ถึง 1.2.2 สัญญาณอาจถูกส่งถ้า 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.