बैश के स्रोत को निष्पादन की आवश्यकता क्यों नहीं है?


57

बैश के साथ sourceएक स्क्रिप्ट को क्रियान्वित बिट सेट के बिना निष्पादित करना संभव है। यह प्रलेखित और अपेक्षित व्यवहार है, लेकिन क्या यह एक निष्पादन बिट के उपयोग के खिलाफ नहीं है?

मुझे पता है, कि sourceएक उपधारा नहीं बनाता है।


2
तथ्य यह है कि chmodआप एक ऑक्टल नंबर के साथ अनुमतियाँ सेट कर सकते हैं (`x सहित) कुछ सुराग देता है कि यह किस युग से आता है। मुझे आश्चर्य नहीं होगा अगर यह एक त्वरित और गंदे के रूप में शुरू हुआ "यह एक द्विआधारी फ़ाइल है जिसे आप निष्पादित कर सकते हैं" सूचक, उन दिनों से जब वह धमाकेदार आविष्कार किया गया था, लेकिन मेरे पास इसका कोई सबूत नहीं है
infixed

9
फिर, जब एसयूआईडी खेल में आता है, तो विभिन्न श्रेणियों के उपयोगकर्ताओं के लिए सुरक्षा के विभिन्न स्तर अधिक महत्वपूर्ण हो जाते हैं। आगे बढ़ें और अगर आप चाहें तो मेरा SUID प्रोग्राम पढ़ें। लेकिन अगर आप इसे केवल पढ़ने के माध्यम से निष्पादित करते हैं, तो एसयूआईडी शक्तियां इसके साथ नहीं आ रही हैं
संक्रमित

@infixed लिनक्स प्रोग्राम-लोडर तब तक शेल्फ़ को नहीं देखेगा जब तक कि एक्ज़ीक्यूशन बिट सेट नहीं होता है। (मेरे खुद के सींग को थोड़ा टॉट करें : यहां देखें ।)
काइल स्ट्रैंड

आपके पास + xr भी हो सकता है, लेकिन यह थोड़ा अजीब है क्योंकि आमतौर पर रनिंग प्रक्रिया में कोड इंजेक्ट करके बाइनरी को पढ़ना संभव है
निकोलस बी।

@KyleStrand "यदि आप इसे केवल पढ़ने के माध्यम से निष्पादित करते हैं, तो SUID शक्तियां इसके साथ नहीं आ रही हैं" मैं कुछ पंक्तियों के साथ कुछ कल्पना कर रहा थाcp /sbin/suidexecutable /tmp/mycopy; /tmp/mycopy
12

जवाबों:


36

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

निष्पादन योग्य बिट के बारे में क्या परवाह है ऑपरेटिंग सिस्टम कर्नेल है। जब लिनक्स कर्नेल एक प्रदर्शन करता है exec, उदाहरण के लिए, यह जाँचता है कि फाइल सिस्टम एक noexecविकल्प के साथ मुहिम नहीं करता है, यह प्रोग्राम फ़ाइल के निष्पादन योग्य बिट की जांच करता है, और सुरक्षा मॉड्यूल (जैसे SELinux या AppAmmor) द्वारा लगाए गए किसी भी आवश्यकताओं को लागू करता है।

ध्यान दें कि निष्पादन योग्य बिट एक विवेकाधीन प्रकार का नियंत्रण है। लिनक्स x86-64 सिस्टम पर, उदाहरण के लिए, आप स्पष्ट /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2रूप से दुभाषिया के रूप में लागू करके निष्पादन योग्य बिट के कर्नेल सत्यापन को बायपास कर सकते हैं :

cp /bin/ls /tmp/
chmod -x /tmp/ls
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /tmp/ls

यह बाश में बश स्रोत कोड को सोर्स करने के लिए कुछ हद तक अनुरूप है, सिवाय इसके कि ld.soदुभाषिया है, और जिस कोड को यह निष्पादित करता है वह ईएलएफ प्रारूप में मशीन कोड है।


3
लोडर का उपयोग "बाईटेकोड" के "दुभाषिया" के रूप में करना जो कि बस एक वास्तविक निष्पादन योग्य बाइनरी होता है ..... भयानक। उसके लिये आपका धन्यवाद।
काइल स्ट्रैंड

@KyleStrand में अप्रत्यक्षता के कई स्तर हो सकते हैं (संग्रहीत प्रोग्राम और भरी हुई प्रक्रिया के बीच अंतर और मेमोरी कैसे मैप की जाती है, विभिन्न पर्यवेक्षकों, VMs, आदि) लेकिन सिद्धांत रूप में मशीन कोड को सीधे सीपीयू द्वारा निष्पादित किया जा सकता है (कोई माइक्रोकोड नहीं) आदि) और इसलिए मशीन कोड की व्याख्या नहीं की जाती है: हार्डवेयर इसे समझता है - यह मूल भाषा है - कोई व्याख्याकार आवश्यक नहीं है।
JFS

2
@JFSebastian हाँ, हम जानते हैं कि यह मूल कोड है, इसलिए "दुभाषिया" उद्धरणों में है। का काम ld.soडायनेमिक लिंकिंग करना है।
२०:०२ पर २०० से २०

@JFSebastian 200_success ने क्या कहा। इसके अलावा, इसका मतलब है कि "वास्तविक निष्पादन योग्य बाइनरी", और मैंने उद्धरणों में "बायटेकोड" भी डाल दिया है (चूंकि AFAIK "बायटेकोड" आमतौर पर वास्तविक संकलित मूल-निष्पादन योग्य बाइनरी कोड को संदर्भित करने के लिए उपयोग नहीं किया जाता है)। इसके अलावा, अच्छा उपयोगकर्ता नाम।
काइल स्ट्रैंड

@ जेएफएसबेस्टियन मेरा मानना ​​है कि आधुनिक x86 जैसे सीपीयू वास्तव में आंतरिक रूप से RISC हैं, पुरानी शैली CISC अनुदेश सेट के साथ मूल रूप से संबंधित RISC निर्देशों का माइक्रोकोड निष्पादन चला रहा है, जहां एक CISC निर्देश कई JISC निर्देशों को निष्पादित करने का कारण बन सकता है। तो एक अर्थ में, CPU कॉल RISC मशीन कोड "इंटरप्रिटिंग" के साथ क्या करता है, अगर तकनीकी दृष्टि से पूरी तरह से सही नहीं है, तो कम से कम एक मान्य मानसिक मॉडल। एईएस-एनआई शायद अधिक चरम उदाहरणों में से एक है: एईएस राउंड प्रति एक सीआईएससी निर्देश!
बजे एक CVn

57

sourceया समतुल्य लेकिन मानक डॉट. स्क्रिप्ट को निष्पादित नहीं करते हैं, लेकिन स्क्रिप्ट फ़ाइल से कमांड पढ़ते हैं , फिर उन्हें निष्पादित करें, लाइन द्वारा लाइन, वर्तमान शेल वातावरण में।

कारण है कि शेल केवल जरूरत नहीं, निष्पादन बिट के इस्तेमाल के खिलाफ कुछ भी नहीं है पढ़ा फ़ाइल की सामग्री पढ़ने की अनुमति।

जब आप स्क्रिप्ट चलाते हैं तो निष्पादन बिट की आवश्यकता होती है । यहां शेल fork()नई प्रक्रिया होगी फिर execve()स्क्रिप्ट से नई प्रक्रिया छवि बनाने के लिए फ़ंक्शन का उपयोग करना, जिसे नियमित, निष्पादन योग्य फ़ाइल होना आवश्यक है।


5
@alexis: मुझे यकीन नहीं है कि मैं वास्तव में अनुसरण करूंगा। यदि आप करते हैं bash < script, तो आप अनिवार्य रूप से उसी परिणाम को प्राप्त करते हैं source script। एक निष्पादित बिट चेक क्या सुरक्षा प्रदान करता है?
आकस्मिक संकलक

27
@alexis, लिपियों की अनुमतियों की जाँच करने के लिए यह दुभाषिया का काम नहीं है। कुछ भी ऐसा नहीं करता है - पायथन नहीं, रूबी नहीं, जावा वर्चुअल मशीन नहीं, अन्य यादृच्छिक गोले नहीं। निष्पादित बिट नियंत्रित करता है कि क्या execvsyscalls का OS * परिवार एक निष्पादन योग्य के साथ प्रयोग किया जा सकता है, न कि एक दुभाषिया इसे चलाएगा। सम्मेलनों को तोड़कर लोगों को भ्रमित (और गैर-फ़ाइल स्रोतों से स्ट्रीम कोड का मूल्यांकन करने की क्षमता को तोड़ना) क्यों?
चार्ल्स डफी

14
@alexis, ... इसके अलावा, शेल लाइब्रेरी होने का एक मूल्यवान अर्थ है, जो निष्पादन योग्य नहीं है: यह कहता है "मैं एक लाइब्रेरी हूं, कमांड नहीं - मुझे स्रोत, मुझे निष्पादित न करें"। अन्यथा आपको पता लगाने के लिए कोड लिखना होगा और कोड के दुरुपयोग का निवारण केवल खट्टा होना चाहिए, लेकिन + x अनुमति न होने से आप यह सुनिश्चित कर सकते हैं कि उपयोगकर्ता इस तरह से पुस्तकालय का दुरुपयोग नहीं कर सकते हैं।
चार्ल्स डफी

6
@alexis "यह लेखकों द्वारा एक निर्णय था" केवल इस अर्थ में कि कोड के हर दूसरे संभावित बिट को शामिल नहीं किया गया था जो एक निर्णय था। शेल पढ़ने के लिए फ़ाइल खोलता है, इसमें से कमांड को पढ़ने के लिए। मैं इसे पढ़ने की अनुमति के लिए जांच करने की उम्मीद नहीं करूंगा, यह सिर्फ फ़ाइल को खोलने की कोशिश करता है और अगर यह नहीं हो पाता है तो विफल हो जाता है। इसी तरह यह लिखने की अनुमति या जांच के लिए अनुमति नहीं देता है, क्योंकि वे चेक फ़ाइल को पढ़ने के लिए प्रासंगिक नहीं हैं।
रैंडी ऑरिसन

2
@alexis इसका उपयोग हालांकि व्यवहार में किया जाता है, उदाहरण के लिए अजगर के virtualenv के साथ, इसे सक्रिय करने के लिए स्क्रिप्ट का मतलब खट्टा होना है, और इसे निष्पादित नहीं किया गया है, और इस तरह bin/activateइसका निष्पादन योग्य बिट नहीं है। लिपियों को पूरी तरह से पुस्तकालयों या उस तरह की अन्य चीजें हो सकती हैं। मुझे लगता है कि .sh एक संकेत हो सकता है, लेकिन फुट-गन से कम से कम होना अच्छा है: यह अच्छा है कि ./bin/activateदुर्घटना के बजाय भागना संभव नहीं है. bin/activate
daboross

20

Nonsetuid और nonsetguid फ़ाइलों पर निष्पादन योग्य बिट (शेष के विपरीत) एक सुरक्षा तंत्र के अधिक नहीं है। आप जो कुछ भी पढ़ सकते हैं, आप अप्रत्यक्ष रूप से चला सकते हैं, और लिनक्स आपको अप्रत्यक्ष रूप से कुछ भी पढ़ा सकता है जिसे आप चला सकते हैं लेकिन सीधे नहीं पढ़ सकते हैं (जो कि गैर-सेट की अवधारणा में छेद को छिद्रित करने के लिए पर्याप्त होना चाहिए) सुरक्षा उपाय)।

यह एक सुविधा की बात अधिक है: यदि बिट सेट है, तो सिस्टम इसे सीधे मेरे लिए चलाए, अन्यथा मुझे इसे अप्रत्यक्ष रूप से करने की आवश्यकता है ( bash the_script;या कुछ हैकिंग-रीड-अनुमति निष्पादन योग्य की मेमोरी छवि प्राप्त करने के लिए )।

आप इसे सुविधा के लिए सेट कर सकते हैं यदि आप स्रोत में दोनों का इरादा रखते हैं और अपने अयोग्य का निष्पादन करते हैं।

जाहिर है, हालांकि, कई साझा पुस्तकालय कार्यान्वयनकर्ता आपकी सोच को साझा करते हैं और नतीजतन, कई प्रणालियों को उस साझा पुस्तकालयों की आवश्यकता होती है, जो मूल रूप से शेल इंसुलेबल्स के मूल समकक्ष हैं, जो प्रयोग करने योग्य होने के लिए निष्पादन योग्य चिह्नित किए जाते हैं। देखें कि साझा लाइब्रेरी निष्पादन योग्य क्यों हैं?


3
@ Motte001 वे उन अटैचमेंट्स को निष्पादित कर सकते हैं यदि वे वास्तव में चाहते हैं। यह एक सुविधा है।
PSkocik

2
निष्पादन योग्य बिट सुरक्षा के लिए नहीं है: यदि मेरे पास कोई फ़ाइल है तो मैं chmodइसके लिए स्वतंत्र हूं और इसे निष्पादन योग्य बनाता हूं । यह कार्यक्रमों से डेटा सॉर्ट करने के लिए है, इसलिए ओपी का प्रश्न एक उचित है।
एलेक्सिस

1
@ Motte001 यह GUI फ़ाइल ब्राउज़र / मेल एप्लिकेशन की एक सुरक्षा विशेषता से अधिक है - यह आसानी से तय कर सकता है कि किसी भी फ़ाइल का डबल क्लिक करने वाला जिसका नाम ".sh" टर्मिनल (विंडोज-शैली) में निष्पादित किया जाए, या इसके विपरीत डबल-। "डाउनलोड संलग्नक" निर्देशिका में किसी भी फ़ाइल पर क्लिक करने से एक अंतर्निहित सैंडबॉक्सेड पूर्वावलोकन ऐप का उपयोग होगा। xबिट सिर्फ एक अतिरिक्त जगह यह / पढ़ सकते हैं कि क्या करना है की एक संकेत के बारे में है।
IMSoP

3
निष्पादन योग्य बिट की आवश्यकता के लिए एक कारण सेट्यूड प्रोग्राम को चलाना है, विशेष रूप से रूट के स्वामित्व वाले। जब आप निश्चित रूप से उन्हें अपने दम पर निष्पादित कर सकते हैं, तो आपको उन्हें चलाने के लिए ओएस की आवश्यकता होगी ताकि उनके पास आवश्यक अनुमतियां हों। कुछ अन्य मामलों में यह वास्तव में सिर्फ एक सुविधा है।
वलीद खान

2
"लिनक्स आपको कुछ भी पढ़ने देगा जो आप / के माध्यम से चला सकते हैं" - खैर, मेरा स्टॉक डेबियन कर्नेल नहीं है: /tmp$ cp /bin/cat ./cat ; chmod a-rw ./cat ; ./cat & cp /proc/$!/exe /tmp/cat2->cp: cannot stat ‘/proc/16260/exe’: Permission denied
ilkachachu

9

यह एक अच्छा सवाल है! यूनिक्स कार्यक्रमों और डेटा के बीच अंतर करने के लिए निष्पादन योग्य बिट का उपयोग करता है। ओएस को निष्पादन बिट की आवश्यकता नहीं है, क्योंकि एक नई प्रक्रिया के रूप में निष्पादन के लिए ओएस के लिए एक खटारा स्क्रिप्ट पारित नहीं की जाती है। लेकिन शेल एक प्रोग्राम के रूप में एक खट्टा स्क्रिप्ट मानता है, और $PATHउस फ़ाइल की तलाश करेगा जिसे आप स्रोत करना चाहते हैं। तो, शेल में खट्टी फाइलों के लिए आवश्यक निष्पादन की अनुमति हो सकती है; लेकिन ऐसा नहीं हुआ।

सवाल बहुत पहले आ चुका होगा। बेल लैब्स के डिजाइन के बीच बॉर्न शेल का डिज़ाइन "संशोधन, संवाद, चर्चा का एक लंबा अनुक्रम" का परिणाम था , और कई डिजाइन निर्णयों पर एसआर बॉर्न और अन्य लोगों द्वारा वर्षों से चर्चा की गई थी। दुर्भाग्य से, मेरे त्वरित रूप को स्रोत सुविधा की कोई चर्चा नहीं मिली (मेरे बचाव में, इसके लिए Google के लिए कठिन है)। मैंने जो पाया वह यह है कि "।" कमांड बॉर्न द्वारा शेल के इस शुरुआती परिचय में प्रकट नहीं होता है , लेकिन यह अधिक परिपक्व संस्करण 7 संस्करण में मौजूद है

अनुपस्थित प्राधिकारी, यहाँ मेरी अपनी व्याख्या है:

  1. .आदेश, उर्फ source, प्रभाव शाब्दिक शामिल किए जाने (जैसे में है #includeसी पूर्वप्रक्रमक में) को क्रियान्वित स्क्रिप्ट या इंटरैक्टिव सत्र के स्रोत कोड में। जैसे, शामिल फ़ाइल यकीनन "निष्पादित" नहीं है।

  2. यूनिक्स दर्शन हमेशा प्रोग्रामरों को खुद को फांसी देने के लिए पर्याप्त रस्सी देने के लिए रहा है। बहुत हद तक हाथ पकड़ना और मनमाना प्रतिबंध रास्ते में ही मिल जाता है। यह केवल हाल ही में है कि कुछ वितरणों ने rm -r /आपके द्वारा पूछे जाने पर मना कर दिया। (यह आदेश आपके कंप्यूटर पर सब कुछ हटाने केrm लिए कहता है इसे रूट के रूप में आज़माएं नहीं! या बेहतर अभी तक, बिल्कुल नहीं।) तो, शायद बॉर्न अल पर। बस तय किया कि जब आप किसी फ़ाइल को स्रोत बनाने की कोशिश करते हैं, तो आपको यह पता चलता है कि आप क्या कर रहे हैं। यह भी अनावश्यक काम से बचता है, और चक्रों ने तब बहुत मायने रखा।


लेकिन @cat ने जो कहा वह निश्चित रूप से नहीं करना चाहिए ।
TOOGAM

मुझे आश्चर्य है कि इसे @TOOGAM को ध्वजांकित और हटाया नहीं गया है, लेकिन मैंने / s में डाल दिया है!
बिल्ली

वहाँ, मुझे नहीं पता कि @cat ने क्या लिखा था, लेकिन मैंने उत्तर को और भी अधिक प्रमाणित किया। (लेकिन आते हैं, यह पहले से ही संदर्भ से काफी स्पष्ट था।)
एलेक्सिस

4

जहां तक ​​ओएस का संबंध है, शेल स्क्रिप्ट वाली एक फ़ाइल सिर्फ डेटा है। यदि आप ऐसी डेटा फ़ाइल का नाम sourceकमांड को देते हैं या कमांड लाइन पर बैश शेल के आह्वान पर पास करते हैं, तो सभी OS देखता है एक स्ट्रिंग है जो डेटा युक्त फ़ाइल के नाम के साथ मेल खाता है।

उस मामले में निष्पादन बिट सभी प्रासंगिक कैसे होगा?


3

भेद महत्वपूर्ण है क्योंकि आपके पास शेल कमांड की एक फाइल हो सकती है जो निष्पादन योग्य के रूप में उपयोगी नहीं है, लेकिन केवल तब उपयोगी होती है जब खट्टा हो। इस फ़ाइल के लिए आप निष्पादित बिट को बंद कर सकते हैं और तब तक इसे कभी भी एक्सेस नहीं किया जा सकता जब तक कि स्पष्ट रूप से एक स्रोत कमांड में न हो। ऐसी चीज का कारण उस शेल पर साइड इफेक्ट्स होना है, जिससे इसे चलाया जाता है। एक विशिष्ट उदाहरण के लिए, मेरे पास एक स्क्रिप्ट है जिसे fix_path कहा जाता है जो पथ को देखता है और संशोधित करता है।


1

बस अगर किसी को आगे के अध्ययन और / या स्पष्टीकरण में रुचि है: कुछ समय पहले लागू किए गए लगभग POSIX अनुरूप शेल में 'एक्जीक्यूट_प्रोग्राम ()' और 'बिलिन_सोर्स ()' के आंतरिक कामकाज बहुत अनुकरणीय हैं। उन कार्यों में आप देखते हैं कि उनके बीच क्या अंतर है:

https://github.com/rsenn/shish/blob/master/src/builtin/builtin_source.c

https://github.com/rsenn/shish/blob/master/src/exec/exec_program.c

मूल रूप से सोर्सिंग को खोल के रूप में देखा जा सकता है कि अस्थायी रूप से इसकी आंतरिक फ़ाइल डिस्क्रिप्टर को पुनर्निर्देशित किया जाता है जहां यह शेल स्क्रिप्ट को (इंटरैक्टिव मोड में टर्मिनल) से पार्स करता है। इसलिए यह बहुत जैसे अन्य पुनर्निर्देशन के समान है <input_file.txtऔर >>append_to_something.listऔर ये सिर्फ खोल सकते हैं और करीब फ़ाइलों की जरूरत है।

इसलिए निष्पादन को execve()सिस्टम कॉल द्वारा नियंत्रित किया जाता है जिसके लिए निष्पादन बिट अनिवार्य है।

मुझे कुछ प्रणालियों को याद करते हुए देखा गया है जो ELF / a.out बायनेरिज़ के निष्पादन की अनुमति देते हैं, लेकिन पहले तर्क के रूप में "/lib/ld-dynamic-linker.so" और बाइनरी प्रोग्राम (निष्पादन बिट के बिना) को निष्पादित करने के माध्यम से। मेरा मानना ​​है कि कुछ DEC अल्फा या VAX मशीनों पर था (क्या यह SCO यूनिक्स हो सकता है?)


-2

एक और दृष्टिकोण:

Sourced स्क्रिप्ट मूल रूप से शेल बिल्डिन और प्रोग्राम कॉल के होते हैं। शेल बिल्डिंस ( sourceउनके बीच) शेल के हिस्से हैं और शेल को पहले स्थान पर निष्पादन योग्य होना चाहिए। प्रत्येक प्रोग्राम को बुलाया गया (जो कि ELF है, शेबबैंग के साथ एक और स्क्रिप्ट, जो भी हो) को निष्पादन बिट सेट करना होगा, अन्यथा यह नहीं चलेगा।

तो यह एक निष्पादन बिट के उपयोग के खिलाफ नहीं है, क्योंकि निष्पादन बिट के बिना कुछ भी नहीं चलेगा। सत्यापन एक संपूर्ण स्क्रिप्ट के लिए नहीं होता है; यह प्रत्येक भाग के लिए अलग-अलग किया जाता है, लेकिन यह है।


शेल बिल्डरों को शेल स्क्रिप्ट से अलग नहीं किया जाता है। आमतौर पर वे शैल निष्पादन योग्य होते हैं। Ksh93, zsh और कुछ अन्य शेल में वे शेल एक्सटेंशन हो सकते हैं।
fpmurphy

@ fpmurphy1 क्या यह मेरा वाक्य "शेल बिल्डिंस (...) शेल के हिस्से नहीं हैं"?
कामिल मैकियोरोव्स्की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.