मैं कांटा बम के साथ अपने सिस्टम को क्रैश क्यों नहीं कर सकता?


54

हाल ही में मैं GNU / Linux में प्रक्रियाओं के बारे में जानकारी खोद रहा हूं और मैं कुख्यात कांटा बम से मिला:

:(){ : | :& }; :

सैद्धांतिक रूप से, यह खुद को असीम रूप से डुप्लिकेट करने के लिए माना जाता है जब तक कि सिस्टम संसाधनों से बाहर चलाता है ...

हालाँकि, मैंने CLI डेबियन और GUI मिंट डिस्ट्रो दोनों पर परीक्षण करने की कोशिश की है , और यह सिस्टम को बहुत प्रभावित नहीं करता है। हाँ, ऐसी बहुत सारी प्रक्रियाएँ हैं जो बनती हैं, और थोड़ी देर बाद मैं सांत्वना संदेशों में पढ़ता हूँ जैसे:

bash: कांटा: संसाधन अस्थायी रूप से अनुपलब्ध है

बैश: कांटा: पुन: प्रयास: कोई बच्चा नहीं

लेकिन कुछ समय बाद, सभी प्रक्रियाएं बस मार दी जाती हैं और सब कुछ सामान्य हो जाता है। मैंने पढ़ा है कि ulimit ने प्रति उपयोगकर्ता अधिकतम प्रक्रिया सेट की है, लेकिन मैं इसे वास्तव में दूर तक बढ़ाने में सक्षम नहीं हो सकता।

कांटा-बम के खिलाफ सिस्टम सुरक्षा क्या हैं? जब तक सब कुछ जम नहीं जाता या कम से कम बहुत पीछे नहीं हट जाता, तब तक वह खुद को क्यों नहीं दोहराता? क्या वास्तव में कांटा बम के साथ एक प्रणाली को क्रैश करने का एक तरीका है?


2
वर्तमान में आपके द्वारा निर्धारित अधिकतम पीआईडी ​​क्या है?
dsstorefile1

5
ध्यान दें कि आप एक फोर्क बम का उपयोग करके अपने सिस्टम को "क्रैश" नहीं करेंगे ... जैसा कि आपने कहा, आप संसाधनों को समाप्त कर देंगे और नई प्रक्रियाओं को स्पॉन करने में असमर्थ होंगे, लेकिन सिस्टम क्रैश
जोश

2
:(){ :& :; }; :इसके बजाय अगर आप दौड़ेंगे तो क्या होगा ? क्या वे भी अंत में मारे जा रहे हैं? किस बारे में :(){ while :& do :& done; }; :?
mtraceur

आपके इस अद्भुत प्रश्न ने मुझे मेरे पिछले "लीव क्लोज्ड" वोट पर पुनर्विचार करने के लिए राजी कर लिया है। हालाँकि, "I" हमेशा अंग्रेजी में अपरकेस होता है, कृपया इसे बुरी तरह से न लिखें।
user259412

जवाबों:


86

आपके पास शायद लिनक्स डिस्ट्रो है जो सिस्टमड का उपयोग करता है।

Systemd प्रत्येक उपयोगकर्ता के लिए एक cgroup बनाता है, और उपयोगकर्ता की सभी प्रक्रियाएँ समान cgroup से संबंधित होती हैं।

Cgroups सिस्टम संसाधनों की सीमा पर अधिकतम प्रक्रियाओं, CPU चक्र, RAM उपयोग इत्यादि को निर्धारित करने के लिए एक Linux तंत्र है। यह संसाधन की सीमित ulimit(जो getrlimit()syscall का उपयोग करता है ) की एक अलग, अधिक आधुनिक, परत है ।

यदि आप चलाते हैं systemctl status user-<uid>.slice(जो उपयोगकर्ता के cgroup का प्रतिनिधित्व करता है), तो आप वर्तमान और अधिकतम संख्या में कार्य (प्रक्रिया और थ्रेड्स) देख सकते हैं जो उस cgroup के भीतर अनुमत हैं।

$ systemctl स्थिति उपयोगकर्ता- $ UID.slice
● उपयोगकर्ता -22001. स्लाइस - यूआईडी 22001 का उपयोगकर्ता स्लाइस
   भरी हुई: भरी हुई
  ड्रॉप-इन: /usr/lib/systemd/system/user-.slice.d
           └─10-defaults.conf
   सक्रिय: सोम 2018-09-10 17:36:35 से सक्रिय; 1 सप्ताह 3 दिन पहले
    कार्य: 17 (सीमा: 10267)
   मेमोरी: 616.7M

डिफ़ॉल्ट रूप से, प्रत्येक उपयोगकर्ता के लिए सिस्टमड की अनुमति देने वाले कार्यों की अधिकतम संख्या "सिस्टम-वाइड अधिकतम" ( sysctl kernel.threads-max) का 33% है ; यह आमतौर पर ~ 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

  • Systemd v238 और इससे पहले के उपयोगकर्ता डिफ़ॉल्ट को UserTasksMax = के माध्यम से सेट किया गया है /etc/systemd/logind.conf। मान को बदलना आमतौर पर रिबूट की आवश्यकता होती है।

इसके बारे में अधिक जानकारी:


5
और 12288 प्रक्रियाएं (शून्य से पहले जो बम से पहले ही पैदा हो गई थी) एक नया बनाने की कोशिश के अलावा कुछ भी नहीं कर रही है , वास्तव में एक आधुनिक प्रणाली को प्रभावित नहीं करती है।
मस्त

13

यह वैसे भी आधुनिक लिनक्स सिस्टम को क्रैश नहीं करेगा।

यह प्रक्रियाओं का घेरा बनाता है, लेकिन वास्तव में सभी सीपीयू नहीं जलते क्योंकि प्रक्रियाएं बेकार हो जाती हैं। अब रैम से बाहर चलने से पहले आप प्रोसेस टेबल में स्लॉट से बाहर चले जाते हैं।

यदि आप Cgroup को Hkoof के रूप में सीमित नहीं करते हैं, तो निम्नलिखित परिवर्तन अभी भी सिस्टम को नीचे लाता है:

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

5
यह वास्तव में इस बात पर निर्भर करता है कि आप सिस्टम को 'क्रैश' क्या मानते हैं। प्रोसेस टेबल में स्लॉट्स से बाहर दौड़ने से ज्यादातर मामलों में घुटनों तक एक सिस्टम आ जाएगा, भले ही यह पूरी तरह से कर्नेल पैनिक का कारण न बने।
ऑस्टिन हेमेलर्गरन

4
@AustinHemmelgarn: यही कारण है कि बुद्धिमान सिस्टम पिछले 4 या तो प्रक्रिया आईडी को रूट के लिए आरक्षित करते हैं।
जोशुआ

2
प्रक्रियाएं "निष्क्रिय" क्यों होंगी? प्रत्येक कांटा प्रक्रिया अधिक प्रक्रियाएं बनाने की एक अनंत पुनरावृत्ति में है। तो यह सिस्टम कॉल ओवरहेड ( forkओवर और ओवर) में बहुत समय बिताता है , और अपना बाकी समय फ़ंक्शन कॉल करता है (शेल के कॉल स्टैक में संभवतः प्रत्येक मेमोरी के लिए अधिक मेमोरी का उपयोग करते हुए, संभवतः)।
mtraceur

4
@mtraceur: यह केवल तब होता है जब फोर्किंग विफल होने लगती है।
जोशुआ

1
ओह, मैं इसे वापस लेता हूं। मैं :(){ :& :; }; :सवाल में एक के बजाय अपने सिर (इस तरह:) में थोड़ा अलग कांटा बम कार्यान्वयन का तर्क मॉडलिंग कर रहा था । मैंने वास्तव में दिए गए आर्कषक के निष्पादन प्रवाह के माध्यम से पूरी तरह से नहीं सोचा है।
mtraceur

9

वापस 90 के दशक में मैंने गलती से इनमें से एक को अपने ऊपर ले लिया। मैंने अनजाने में C स्रोत फ़ाइल पर निष्पादित बिट सेट किया था जिसमें एक फोर्क () कमांड था। जब मैंने इसे डबल-क्लिक किया, तो csh ने इसे संपादक की तरह खोलने के बजाय चलाने की कोशिश की, जैसे मैं चाहता था।

इसके बाद भी, यह सिस्टम क्रैश नहीं हुआ। यूनिक्स इतना मजबूत है कि आपके खाते और / या ओएस में एक प्रक्रिया सीमा होगी। इसके बजाय जो होता है, वह सुपर सुस्त हो जाता है, और प्रक्रिया शुरू करने के लिए कुछ भी विफल होने की संभावना है।

पर्दे के पीछे क्या हो रहा है कि प्रक्रिया तालिका उन प्रक्रियाओं से भर जाती है जो नई प्रक्रियाएं बनाने की कोशिश कर रही हैं। यदि उनमें से एक समाप्त हो जाता है (या तो कांटे पर एक त्रुटि होने के कारण क्योंकि प्रक्रिया तालिका भरी हुई है, या एक हताश ऑपरेटर अपने सिस्टम के लिए विवेक को बहाल करने की कोशिश कर रहा है), अन्य प्रक्रियाओं में से एक को भरने के लिए एक नया कांटा होगा। शून्य।

"कांटा बम" मूल रूप से आपकी प्रक्रिया तालिका को पूर्ण रखने के लिए एक मिशन पर प्रक्रियाओं का एक अनजाने में स्व-मरम्मत प्रणाली है। इसे रोकने का एक ही तरीका है कि किसी तरह एक ही बार में सभी को मार दिया जाए।


1
उन सभी को एक बार में मारना जितना आपको लगता है कि आसान है - उन सभी को सबसे पहले हस्ताक्षर करें।
स्कोर_उंडर

2
@Score_Under - मुझे आशा है कि अगर आपने तुरंत अपने करीबी हैरिस नाइटहॉक को देखने की जल्दी नहीं की तो मैं आपको माफ कर दूंगा कि अगर वहाँ समस्या का समाधान हो जाता। मैं सोच रहा हूं कि पीआईडी ​​को भेजने से पहले ही यह संकेत हो जाए, इससे पहले कि वह विफल कांटे से मर जाए और दूसरा स्थान ले ले, यह एक चुनौती हो सकती है, लेकिन मुझे इसे आज़माना होगा।
TED

@TED ​​किल -9 -1 आप यहां दोस्त हो सकते हैं (उसी उपयोगकर्ता के साथ जो कांटा बम चलाता है; जड़ के साथ नहीं)।
एंड्रियास क्रे सिप

@AndreasKrey - यह ध्वज परिचित नहीं दिखता है, इसलिए मैं अपने 90 के युग पर संदेह कर रहा हूं, यह नाइटहॉक के पास था।
TED

1
@ टेड: -1झंडा नहीं है। killकेवल एक विकल्प लेता है तो पार्सिंग विकल्प बंद कर देता है। यह प्रक्रिया आईडी को मारता है -1, जो सभी प्रक्रियाओं के लिए एक उपनाम है।
जोशुआ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.