เหตุใดฉันจึงไม่สามารถชนระบบของฉันด้วยการวางระเบิดได้


54

เมื่อเร็ว ๆ นี้ฉันได้ขุดข้อมูลเกี่ยวกับกระบวนการใน GNU / Linux และฉันได้พบกับระเบิดที่น่าอับอาย:

:(){ : | :& }; :

ในทางทฤษฎีมันควรจะทำซ้ำตัวเองอย่างไม่มีที่สิ้นสุดจนกว่าระบบจะหมดทรัพยากร ...

อย่างไรก็ตามฉันได้ลองทดสอบทั้งในCLI DebianและGUI Mint distro และดูเหมือนว่าจะไม่ส่งผลกระทบต่อระบบมากนัก ใช่มีกระบวนการมากมายที่ถูกสร้างขึ้นและหลังจากนั้นไม่นานฉันก็อ่านในข้อความคอนโซลเช่น:

bash: fork: ทรัพยากรไม่สามารถใช้งานได้ชั่วคราว

bash: fork: ลองอีกครั้ง: ไม่มีกระบวนการลูก

แต่หลังจากเวลาผ่านไปกระบวนการทั้งหมดเพิ่งถูกฆ่าและทุกอย่างกลับสู่ปกติ ฉันได้อ่านว่าulimitตั้งค่าจำนวนสูงสุดของกระบวนการต่อผู้ใช้ แต่ฉันไม่สามารถยกมันได้ไกลนัก

ระบบป้องกันการระเบิดจากส้อมคืออะไร? ทำไมมันไม่ทำซ้ำตัวเองจนกว่าทุกอย่างจะหยุดหรืออย่างน้อยก็ล่าช้ามาก? มีวิธีที่จะทำให้ระบบพังด้วยส้อมระเบิดหรือไม่?


2
PID สูงสุดของคุณตั้งค่าไว้ที่เท่าไหร่
dsstorefile1

5
โปรดทราบว่าคุณจะไม่“ ผิดพลาด” ระบบของคุณโดยใช้ fork bomb ... อย่างที่คุณพูดคุณจะหมดทรัพยากรและไม่สามารถวางไข่กระบวนการใหม่ แต่ระบบไม่ควรผิดพลาด
Josh

2
จะเกิดอะไรขึ้นถ้าคุณวิ่ง:(){ :& :; }; :แทน ในที่สุดพวกเขาก็ถูกฆ่าตายด้วยหรือไม่? เกี่ยวกับ:(){ while :& do :& done; }; :อะไร
mtraceur

คำถามที่ยอดเยี่ยมนี้ของคุณทำให้ฉันคิดใหม่เกี่ยวกับการโหวต "ลาปิด" ก่อนหน้านี้ อย่างไรก็ตาม "ฉัน" มักจะเป็นตัวพิมพ์ใหญ่เสมอในภาษาอังกฤษโปรดอย่าเขียนมันแย่อีกต่อไป
user259412

คำตอบ:


86

คุณอาจมี Linux distro ที่ใช้ systemd

Systemd สร้าง cgroup สำหรับผู้ใช้แต่ละคนและกระบวนการทั้งหมดของผู้ใช้อยู่ใน cgroup เดียวกัน

Cgroups เป็นกลไกลีนุกซ์ในการกำหนดข้อ จำกัด เกี่ยวกับทรัพยากรระบบเช่นจำนวนกระบวนการสูงสุด, รอบการทำงานของ CPU, การใช้ RAM ฯลฯ นี่คือชั้นที่แตกต่างกันและทันสมัยกว่าของการ จำกัด ทรัพยากรมากกว่าulimit(ซึ่งใช้getrlimit()syscall)

หากคุณเรียกใช้systemctl status user-<uid>.slice(ซึ่งแสดงถึง cgroup ของผู้ใช้) คุณสามารถดูจำนวนงานปัจจุบันและสูงสุด(กระบวนการและกระทู้) ที่ได้รับอนุญาตภายใน cgroup นั้น

$ systemctl สถานะผู้ใช้ - $ UID.slice
● user-22001.slice - User Slice ของ UID 22001
   โหลดแล้ว: โหลดแล้ว
  ดร็อปอิน: /usr/lib/systemd/system/user-.slice.d
           └─10-defaults.conf
   ใช้งานอยู่: เปิดใช้งานตั้งแต่จันทร์ 2018-09-10 17:36:35 EEST; 1 สัปดาห์ 3 วันก่อน
    งาน: 17 (จำกัด : 10267)
   หน่วยความจำ: 616.7M

โดยค่าเริ่มต้นจำนวนสูงสุดของงานที่ systemd จะอนุญาตสำหรับผู้ใช้แต่ละคนคือ 33% ของ "สูงสุดทั้งระบบ" ( sysctl kernel.threads-max); โดยปกติจะมีจำนวนงาน ~ 10,000 งาน หากคุณต้องการเปลี่ยนขีด จำกัด นี้:

  • ใน systemd v239 และใหม่กว่าค่าเริ่มต้นของผู้ใช้จะถูกตั้งค่าผ่านTasksMax =ใน:

    /usr/lib/systemd/system/user-.slice.d/10-defaults.conf
    

    หากต้องการปรับขีด จำกัด สำหรับผู้ใช้เฉพาะ (ซึ่งจะถูกนำไปใช้ทันทีเช่นเดียวกับที่เก็บไว้ใน /etc/systemd/system.control) ให้เรียกใช้:

    systemctl [--runtime] set-property user-<uid>.slice TasksMax=<value>
    

    กลไกปกติของการแทนที่การตั้งค่าของหน่วย (เช่นsystemctl edit) สามารถใช้ที่นี่ได้เช่นกัน แต่จะต้องมีการรีบูต ตัวอย่างเช่นหากคุณต้องการเปลี่ยนขีด จำกัด สำหรับผู้ใช้ทุกคนคุณสามารถสร้าง/etc/systemd/system/user-.slice.d/15-limits.confได้

  • ใน v238 systemd และก่อนหน้านี้เริ่มต้นที่ผู้ใช้ตั้งค่าผ่านทางUserTasksMax =/etc/systemd/logind.confใน การเปลี่ยนค่าโดยทั่วไปต้องการการรีบูต

ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้:


5
และกระบวนการ 12288 (ลบด้วยสิ่งที่เกิดขึ้นแล้วก่อนการวางระเบิด) ไม่ทำอะไรนอกจากพยายามสร้างใหม่ไม่ส่งผลกระทบต่อระบบที่ทันสมัย
เสา

13

นี่จะไม่ทำให้ระบบลินุกซ์ยุคใหม่ขัดข้องอีกต่อไป

มันสร้างกระบวนการจำนวนมาก แต่ไม่ได้เผาไหม้ CPU ทั้งหมดเท่าที่กระบวนการใช้งาน คุณไม่มีสล็อตในตารางกระบวนการก่อนที่จะหมด RAM ทันที

หากคุณไม่ได้ จำกัด กลุ่ม cgroup ตามที่ Hkoof ชี้ให้เห็นการเปลี่ยนแปลงต่อไปนี้ยังคงทำให้ระบบต่างๆแย่ลง:

:(){ : | :& : | :& }; :

5
สิ่งนี้ขึ้นอยู่กับสิ่งที่คุณพิจารณาว่า 'หยุด' ระบบ การวิ่งออกจากสล็อตในตารางกระบวนการจะนำระบบไปสู่การเป็นหัวเข่าในกรณีส่วนใหญ่แม้ว่ามันจะไม่ทำให้เกิดความตื่นตระหนกของเคอร์เนลก็ตาม
Austin Hemmelgarn

4
@AustinHemmelgarn: ซึ่งเป็นสาเหตุที่ระบบที่ชาญฉลาดจองรหัสกระบวนการ 4 รายการสุดท้ายสำหรับรูต
Joshua

2
ทำไมกระบวนการต่าง ๆ จึง "ไม่ทำงาน" แต่ละกระบวนการแยกอยู่ในการเรียกซ้ำแบบไม่สิ้นสุดของการสร้างกระบวนการเพิ่มเติม ดังนั้นจึงใช้เวลามากในการเรียกใช้ระบบ ( forkมากกว่า) และเวลาที่เหลือในการทำฟังก์ชั่นการโทร (ใช้หน่วยความจำเพิ่มเติมสำหรับการโทรแต่ละครั้งในการโทรของเชลล์สแต็ก)
mtraceur

4
@mtraceur: มันเกิดขึ้นเมื่อการฟอร์กเริ่มล้มเหลวเท่านั้น
Joshua

1
โอ้ฉันเอามันกลับมา ฉันกำลังสร้างแบบจำลองตรรกะของการวางระเบิดทางแยกที่แตกต่างกันเล็กน้อยในหัวของฉัน (เช่นนี้:(){ :& :; }; ::) แทนที่จะเป็นหนึ่งในคำถาม ฉันไม่ได้คิดอย่างถี่ถ้วนผ่านโฟลว์การดำเนินการของ archetypical ที่กำหนด
mtraceur

9

ย้อนกลับไปในยุค 90 ฉันได้ปลดปล่อยสิ่งเหล่านี้ด้วยตัวเองโดยไม่ตั้งใจ ฉันตั้งใจตั้งบิตรันบนไฟล์ต้นฉบับ C ที่มีคำสั่ง fork () ในนั้น เมื่อฉันคลิกสองครั้ง csh พยายามเรียกใช้มันแทนที่จะเปิดในตัวแก้ไขอย่างที่ฉันต้องการ

ถึงอย่างนั้นมันก็ไม่ได้ผิดพลาดของระบบ Unix นั้นแข็งแกร่งเพียงพอที่บัญชีของคุณและ / หรือระบบปฏิบัติการจะมีขีด จำกัด กระบวนการ สิ่งที่เกิดขึ้นแทนคือมันเฉื่อยอย่างยิ่งและสิ่งใดก็ตามที่ต้องเริ่มกระบวนการมีแนวโน้มที่จะล้มเหลว

สิ่งที่เกิดขึ้นเบื้องหลังคือตารางกระบวนการเติมเต็มกระบวนการที่พยายามสร้างกระบวนการใหม่ หากหนึ่งในนั้นถูกยกเลิก (เนื่องจากการรับข้อผิดพลาดบนทางแยกเนื่องจากตารางกระบวนการเต็มหรือเนื่องจากผู้ดำเนินการที่พยายามกู้คืนสติในระบบของพวกเขาอย่างหมดหวัง) หนึ่งในกระบวนการอื่น ๆ จะแยกรายการใหม่อย่างสนุกสนาน ความว่างเปล่า

"fork bomb" นั้นเป็นระบบที่ซ่อมแซมตัวเองโดยไม่ได้ตั้งใจของกระบวนการในภารกิจเพื่อให้ตารางกระบวนการของคุณเต็ม วิธีเดียวที่จะหยุดมันได้คือฆ่าพวกมันทั้งหมดในครั้งเดียว


1
การฆ่าพวกเขาทั้งหมดในครั้งเดียวนั้นง่ายกว่าที่คุณคิด SIGSTOP พวกเขาทั้งหมดก่อน
คะแนน _ ต่ำ

2
@Score_Under - ฉันหวังว่าคุณจะยกโทษให้ฉันถ้าฉันไม่รีบไปที่ Harris Nighthawk ที่ใกล้ที่สุดเพื่อดูว่าจะแก้ไขปัญหาที่นั่นหรือไม่ ฉันคิดว่าจะได้รับ PID ส่งสัญญาณก่อนที่มันจะตายจากส้อมที่ล้มเหลวและอีกอย่างที่เกิดขึ้นอาจเป็นเรื่องที่ท้าทาย แต่ฉันต้องลองดู
TED

@TED ​​kill -9 -1 อาจเป็นเพื่อนของคุณได้ที่นี่ (ด้วยผู้ใช้เดียวกันกับที่รัน fork fork ไม่ใช่ด้วย root)
Andreas Krey

@ AndreasKrey - ธงนั้นดูไม่คุ้นเคยดังนั้นฉันจึงสงสัยว่า Nighthawk ในยุค 90 ของฉันมีแล้ว
TED

1
@TED: -1ไม่ใช่ธง killใช้ตัวเลือกเดียวเท่านั้นจากนั้นหยุดการแยกวิเคราะห์ตัวเลือก รหัสกระบวนการนี้จะฆ่า-1ซึ่งเป็นนามแฝงสำหรับกระบวนการทั้งหมด
Joshua
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.