2011-11-11 3 views
7

पर प्रक्रिया की प्रक्रिया को निष्पादित करने के लिए लिखना क्या होगा यदि प्रक्रिया बी लिखता है (एक सामान्य लेखन() syscall के साथ) कुछ डेटा प्रक्रिया की छवि में कुछ डेटा जबकि उत्तरार्द्ध निष्पादित हो रहा है? क्या यह भ्रष्टाचार का कारण नहीं होगा कि ए प्रक्रिया निष्पादित कर रही है?लिनक्स

मैं लिनक्स के लिए नया हूं। जहां तक ​​मैं समझता हूं, यूनिक्स ऐतिहासिक रूप से अनिवार्य फ़ाइल ताले लगाता है (जैसे विंडोज करता है)। तो लेखन काफी संभव है।

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

फिर भी, मैंने जो पढ़ा है, उससे कर्नेल आसानी से कुछ पेजों को स्मृति फ़ाइल से स्मृति फ़ाइल में स्वैप कर सकता है, कहें, जब कम स्मृति स्थितियों पर बल दिया जाता है। इसलिए, डिस्क पर रहते समय, कुछ पेज संभावित रूप से किसी अन्य लेखक प्रक्रिया द्वारा दूषित हो सकते हैं; बाद में, उन्हें वापस रैम में बदल दिया जा सकता है और निष्पादित किया जा सकता है।

+0

चेक मेरा उत्तर देखें: http://stackoverflow.com/questions/4453781/what-happens-when-you-overwrite-a-memory-mapped-executable – Antoine

उत्तर

2

क्या आप pid_t 1234 की दूसरी प्रक्रिया के कुछ /proc/1234/mem में प्रक्रिया लिखने की सोच रहे हैं?

या क्या आप किसी अन्य प्रक्रिया के निष्पादन योग्य ईएलएफ में प्रक्रिया लिखने की सोच रहे हैं?

दोनों दृश्यों बहुत असामान्य हैं और लिनक्स विशिष्ट (अन्य पॉइसिक्स में ये नहीं है), इसलिए मुझे नहीं पता कि उस मामले में क्या हो सकता है। लेकिन कम से कम अनुमति मशीनरी को कुछ की रक्षा करनी चाहिए।

ETXTBSY त्रुटि भी देखें।

अभ्यास (के रूप में strace -f /usr/bin/gcc hello.c -o hello द्वारा दिखाया गया है) संकलक और लिंकर निष्पादन लिखने के लिए यह आईएनजी open से पहले निष्पादन हटा रहे हैं, इसलिए अधिकांश संकलन एक पुराने निष्पादन योग्य फ़ाइल में कभी नहीं लिखने में:

870 stat("hello", {st_mode=S_IFREG|0755, st_size=6096, ...}) = 0 
870 unlink("hello")     = 0 
870 open("hello", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0777) = 17 
870 fstat(17, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 

तो करने के लिए एक निष्पादन योग्य फ़ाइल में लिखें, आपको कड़ी मेहनत करनी है। बेशक, जब आप ऐसा करते हैं, तो शरारती दुर्घटनाएं हो सकती हैं।

+0

मैं दूसरा परिदृश्य मतलब था। –

+0

ETXTBSY मेरे अनुभव में सबसे बड़ा संकेत है, यदि आप चल रहे निष्पादन योग्य के हिस्सों को ओवरराइट करने का प्रयास कर रहे हैं तो आपको ETXTBSY की एक त्रुटि मिल जाएगी।और ध्यान दें कि फ़ाइल की सामग्री को ओवरराइट करना फ़ाइल को हटाने और पॉज़िक्स सिस्टम पर एक ही फ़ाइल नाम के साथ एक नया निर्माण करने से बहुत अलग है। – nos

+0

एंटोनी द्वारा जुड़े प्रश्न में विस्तृत चर्चाएं हैं। मुझे लगता है कि ETXTBSY अब और अधिक नहीं होता है (शायद स्थिर रूप से जुड़े निष्पादन योग्य को छोड़कर)। –

1

आपने क्या पढ़ा है जो सुझाव देता है कि पृष्ठों को "छवि फ़ाइल में" वापस बदला जा सकता है?

यदि सिस्टम स्मृति पर कम है, तो पृष्ठों को डिस्क पर स्वैप विभाजन में बदल दिया जाएगा, जो निष्पादन योग्य फ़ाइल से अलग है। निष्पादन योग्य फ़ाइल को लिखने पर अगली बार फ़ाइल चलाने तक कोई प्रभाव नहीं पड़ेगा।

यदि, किसी भी तरह आप स्वैप फ़ाइल पर सटीक पृष्ठ पर लिखने में सक्षम थे (जो मुश्किल होगा, क्योंकि आपको यह जानना होगा कि डेटा कहां और कब डिस्क पर लिखा गया था)। यदि आपने ऐसा किया है तो आप ऑब्जेक्ट कोड को संशोधित करने में सक्षम हो सकते हैं। क्या आप निष्पादन योग्य को भ्रष्ट करने का सुझाव दे रहे हैं, या प्रोग्राम चलाने के लिए कुछ चालाक तरीका चल रहे हैं?

+0

मैं ऑब्जेक्ट कोड भ्रष्टाचार की अवांछनीय संभावना से चिंतित हूं। मुझे संदेह है कि कर्नेल निष्पादन योग्य छवियों के लिए स्वैप विभाजन का उपयोग करता है; यह बहुत अपमानजनक होगा, जहां तक ​​मैं इसके बारे में सोच सकता हूं। कर्नेल बल्कि साधारण mmap के समान फैशन में छवियों को मानचित्र करता है। –

+0

स्वच्छ पृष्ठों को बिल्कुल भी नहीं बदला जाता है - उन्हें बस उस फ़ाइल से पुनः लोड किया जा सकता है, जिसे वे फिर से जरूरी होने से मैप किए जाते हैं। – caf

1

वास्तव में पृष्ठों को बदलने के लिए "कम स्मृति स्थिति" रखना जरूरी नहीं है। लिनक्स वैसे भी "मांग पर" निष्पादन योग्य फाइल लोड करता है, इसलिए जब आवश्यक हो तो एक पृष्ठ केवल लोड हो जाता है।

लेकिन करने के लिए वहाँ पिछले एक What happens when you overwrite a memory-mapped executable?