खरोंच से सी संकलक को कैसे संकलित करें, फिर खरोंच से यूनिक्स / लिनक्स संकलित करें


64

मान लीजिए कि मैं यूएस / यूके के बाहर एक बड़े सेवा संगठन के लिए काम करता हूं। हम यूनिक्स और लिनक्स सर्वरों का बड़े पैमाने पर उपयोग करते हैं।

इस लेख को पढ़कर यह उल्लेख है कि एक सी कंपाइलर में एक पिछले दरवाजे को सम्मिलित करना आसान होगा, फिर उस कंपाइलर के साथ संकलित किसी भी कोड में एक बैकडोर भी होगा। अब एनएसए / जीसीएचक्यू के सभी एन्क्रिप्शन तरीकों, हार्डवेयर और सॉफ्टवेयर में बैकडोर / कमजोरियां डालने के बारे में हालिया लीक को देखते हुए, कंपाइलर अब विफलता का एक महत्वपूर्ण बिंदु है। संभावित रूप से सभी मानक UNIX / Linix वितरण में समझौता किया जा सकता है। हम अपने सिस्टम, डेटा और हमारे ग्राहकों के डेटा को दुष्ट सरकारों द्वारा समझौता करने का जोखिम नहीं उठा सकते हैं।

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

सवाल

स्रोत कोड (एक प्रतीत होता है चिकन-अंडा परिदृश्य) से एक संकलक के बारे में जाने के लिए सही (और सुरक्षित तरीका) क्या है फिर एक विश्वसनीय यूनिक्स / लिनक्स वितरण को खरोंच से संकलित करना?

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

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

जैसा कि ब्रूस श्नेयर कहते हैं: "इंजीनियरों के लिए, मैं यह कहता हूं: हमने इंटरनेट का निर्माण किया, और हम में से कुछ ने इसे हटाने में मदद की है। अब, हममें से जो स्वतंत्रता से प्यार करते हैं, उन्हें इसे ठीक करना होगा।"

अतिरिक्त लिंक:


7
अरे, यह एक बहुत ही दिलचस्प सवाल है और मैं इसे स्थानांतरित नहीं करना चाहता, लेकिन मुझे नहीं लगता कि यह यहाँ विषय पर है। यह बेहतर है stackoverflow.com के बाद से अपने बुनियादी सवाल के बारे में कैसे एक संकलक खरोंच से संकलन करने के लिए है जो बहुत ज्यादा है OS अज्ञेयवादी और बहुत एक प्रोग्रामिंग सवाल। यदि आपको अपने प्रश्न के टैग के तहत "ध्वज" लिंक का उपयोग करने पर विचार करने के बाद यहां जवाब नहीं मिलता है और किसी मध्यस्थ को SO को स्थानांतरित करने के लिए कहता है।
terdon

2
@terdon यह वास्तव में प्रोग्रामर्स के लिए एक बेहतर फिट हो सकता है। क्योंकि यह एक विशिष्ट विकास समस्या की तुलना में सामान्य प्रोग्रामिंग मुद्दों के बारे में अधिक है। वास्तव में, यह एक डुप्लिकेट हो सकता है
एक CVn

2
जीसीसी खुला स्रोत है, किसी भी पिछले दरवाजे को कैसे डाला जाएगा?
माइकल पैंकोव

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

2
@ कॉन्स्टेंटियस - पहली पंक्ति में जुड़े थॉम्पसन लेख को पढ़ें। कंपाइलर का संकलन कौन करता है?
रसेल बोरोगोव

जवाबों:


30

AFAIK सुरक्षा का पूरी तरह से सुनिश्चित करने का एकमात्र तरीका असेंबली भाषा में एक कंपाइलर लिखना होगा (या सीधे डिस्क को संशोधित करना )। तभी आप यह सुनिश्चित कर सकते हैं कि आपका कंपाइलर पिछले दरवाजे को नहीं लगा रहा है - यह काम करता है क्योंकि आप वास्तव में कंपाइलर को पूरी तरह से खत्म कर रहे हैं।

वहां से, आप अपने स्क्रेप कंपाइलर से लेकर बूटस्ट्रैप जैसे जीएनयू टूलचैन का उपयोग कर सकते हैं। तब आप अपने कस्टम टूलचिन का उपयोग स्क्रैच सिस्टम से लिनक्स संकलित करने के लिए कर सकते थे ।

ध्यान दें कि चीजों को खुद पर आसान बनाने के लिए, आपके पास एक दूसरा मध्यस्थ कंपाइलर हो सकता है, जो सी (या जो भी अन्य भाषा) में लिखा गया है। तो आप संकलक A को असेंबली में लिखेंगे, फिर उस कंपाइलर को C / C ++ / Python / Brainfuck / में से जो भी कंपाइलर B प्राप्त करना है, जो आप कंपाइलर A का उपयोग करके संकलित करेंगे, फिर से लिखेंगे। तब आप g और दोस्तों को कंपाइल करने के लिए कंपाइलर B का उपयोग करेंगे।


13
फिर भी, यह अभी भी केवल एक दुर्भावनापूर्ण संकलक से बचाता है। आपको अभी भी उस सिस्टम पर भरोसा करने की आवश्यकता है जिस पर कंपाइलर निष्पादित होता है। अलगाव में कोई सॉफ्टवेयर मौजूद नहीं है।
बजे एक CVn

3
कुछ भी स्वायत्त स्वाभाविक रूप से खतरनाक है। आप प्रभावी रूप से एक टूलकिन कंपाइलर का प्रस्ताव दे रहे हैं (यद्यपि यह एक अजीब है) जिसका अर्थ है कि संभवतः इसे उसी तरह से संशोधित किया जा सकता है जिस तरह से आप बचने की कोशिश कर रहे हैं। और भी बेहतर, इसे मित्म के माध्यम से पारगमन में संशोधित किया जा सकता है।
स्ट्रगल

1
आप लोगों को महसूस करना होगा कि यह उत्तर 15 साल की उम्र से आ रहा है। भटके रहो!
mtahmed

3
किसी को खरोंच से एक कोड संपादक लिखना भी नहीं भूलना चाहिए - कौन जानता है कि आपका पूर्व-कोड <v> </ code> या <code> vim </ code> आप अपने अच्छे संकलक के साथ संकलित करते हैं जिस स्रोत से आपने केवल संक्रमित का उपयोग करके ऑडिट किया है <code> vim </ code> भरोसेमंद है?
हेगन वॉन एटिज़ेन

1
कभी न भूलें, जब तक कि आपने व्यक्तिगत रूप से उस पहली मशीन कोड (असेंबली नहीं। वास्तविक मशीन कोड) को लिखा है, और आप अंडरहेल्ड सुरक्षा छेदों को पहचानने में विशेषज्ञ हैं, और कोड की हर एक पंक्ति को पढ़ रहे हैं और जांच रहे हैं ... या कम से कम जानते हैं वह व्यक्ति जिसने व्यक्तिगत रूप से ऐसा किया है , और उसे ऐसा करने के लिए भरोसा है…। इसमें से कोई भी मदद नहीं करेगा। यही कारण है कि इस किकस्टार्टर की कोशिश, पूरे बिंदु को बर्बाद कर रही है। जो है: उच्च भरोसेमंदता।
Evi1M4chine 14

22

एक संभव तरीका है, हालांकि यह व्यवहार में एक लंबा समय लगेगा, जड़ों तक वापस जाना होगा। GNU का विकास 1984 में शुरू हुआ, और Minix का मूल संस्करण (जिसका उपयोग बूटस्ट्रैपिंग उद्देश्यों के लिए शुरुआती लिनक्स विकास के दौरान किया गया था) 1987 में जारी किया गया था।

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

यदि आप स्रोत कोड के साथ मूल Minix पुस्तक की एक प्रति पा सकते हैं, तो आप इसे पुस्तक से टाइप कर सकते हैं। इसे संकलित करें, और फिर यह पुष्टि करने के लिए कि सिस्टम मशीन अपेक्षित बायनरी आउटपुट उत्पन्न करता है, यह सत्यापित करने के लिए एक अलग सिस्टम पर एक अलग डिकंपाइलर का उपयोग करें। (कोड, केवल 12,000 लाइनों, शायद है सी तो ऐसा करने से समय लेने वाली लेकिन अभी भी भीतर कारण अगर आप इस तरह के एक परियोजना के बारे में गंभीर हैं।) आप अपने स्वयं के disassembler लिख सकता है; यह बहुत मुश्किल नहीं होना चाहिए।

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

कुछ बिंदु पर, आपके पास एक सिस्टम होगा जो लिनक्स कर्नेल के शुरुआती संस्करण को संकलित कर सकता है और बूटस्ट्रैप कर सकता है, जैसे कि यह 1990 के दशक की शुरुआत में किया गया था क्योंकि लिनक्स ने हैकर्स के बीच कर्षण हासिल करना शुरू कर दिया था। मैं उस बिंदु पर लिनक्स में माइग्रेट करने का सुझाव दूंगा (लिनक्स के खिलाफ सिस्टम लाइब्रेरी और टूलचैन को फिर से बनाऊंगा, लिनक्स कर्नेल का निर्माण करूंगा, लिनक्स में बूट करूंगा और संभवतः लिनक्स के भीतर लिनक्स कर्नेल और जीएनयू टूलचैन को फिर से बनाऊंगा; अंतिम साबित होता है कि सिस्टम अब स्व- है होस्टिंग), लेकिन यह काफी हद तक आपके ऊपर है। पैच को सत्यापित करना, कर्नेल, लाइब्रेरी और बुनियादी GNU टूल को पैच करना और पुनर्निर्माण करना जब तक कि आप आधुनिक संस्करण प्राप्त न कर लें।

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

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

हां, इसमें बहुत समय लगेगा। लेकिन इस दृष्टिकोण का लाभ यह है कि प्रत्येक चरण वृद्धिशील है, जिसका अर्थ है कि दुर्भावनापूर्ण किसी चीज के लिए पर्ची करना बहुत कठिन होगा जब तक कि इसे बहुत धीरे-धीरे कई संस्करणों की अवधि में पेश नहीं किया जाता है; ऐसा इसलिए है क्योंकि प्रत्येक चरण में परिवर्तनों का सेट तुलनात्मक रूप से छोटा है और इस तरह से देखने में बहुत आसान है। चैंज के साथ पैचसेट की तुलना करें और सुनिश्चित करें कि आप यह निर्धारित कर सकते हैं कि चेंजलॉग प्रविष्टि स्रोत कोड में हर बदलाव से मेल खाती है। फिर, यह मान लेता है कि आपके पास यह क्षमता है (संभवत: किसी के माध्यम से जिस पर आप भरोसा करते हैं) यह सत्यापित करने के लिए कि इस तरह के बदलाव कोडबेस में चुपके से नहीं किए गए हैं, लेकिन यह आपको एक विश्वसनीय सिस्टम के करीब के रूप में मिलना चाहिए , केवल सॉफ्टवेयर के अलावा- फर्मवेयर दृष्टिकोण कर सकते हैं।


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

9

यदि आपको एक विश्वसनीय संकलक की आवश्यकता है, तो आप संकलित परियोजना की तरह शैक्षणिक कार्य पर एक नज़र डाल सकते हैं । यह एक कम्पाइलर है, जो कि INRIA (एक फ्रेंच आईटी पब्लिक लेबोरेटरी) द्वारा बनाया गया है, जो '' प्रमाणित '' होने के लिए डिज़ाइन किया गया है, यानी कोड के बराबर (और निश्चित रूप से, यह गणितीय रूप से सिद्ध हो चुका है) के लिए एक निष्पादन योग्य शब्दार्थ है।


1
हर किसी को एक विश्वसनीय कंपाइलर की जरूरत होती है। गणित कैसे काम करता है कि वे एक "विश्वसनीय" संकलक का उत्पादन कर सकते हैं?
डेविड जे

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

1
"" "कॉम्पैक सी को किसी भी अन्य उत्पादन संकलक के अलावा सेट करता है, यह है कि इसे औपचारिक रूप से सत्यापित किया जाता है, मशीन-असिस्टेड गणितीय प्रमाणों का उपयोग करके, गलत तरीके से मुद्दों से छूट पाने के लिए।" "" compcert.inria.fr/computerert-C.html संकलन। उतना अनुभवजन्य नहीं है जितना पहले हुआ करता था।
lgeorget

1
@ माइकलकॉर्लिंग जो शायद इस बात को ध्यान में नहीं रखता है कि कर्नेल को कंपाइलर स्रोत में एक पिछले दरवाजे को शामिल करने के लिए समझौता किया जा सकता है जब एक कंपाइलर द्वारा पढ़ा जाता है
शाफ़्ट फ्रीक

1
मुझे यह लिंक भी मिला जो काम भी कर सकता था।
डेविड जे

2

आरंभिक बिंदु के रूप में मैन्युअल रूप से अपना कंपाइलर बनाते समय यह सबसे सुरक्षित होगा, एक अन्य विकल्प 5 (या 10) वर्ष पुरानी सीडी को स्थापित करना है कि आप इन कारनामों के अस्तित्व में आने से पहले विश्वास करें। फिर नए ऑडिट किए गए स्रोत को संकलित करने के लिए एक नींव के रूप में उपयोग करें।


5
इस हमले को 1984 से सार्वजनिक रूप से जाना जाता है। संभवतः थॉम्पसन संभावना के बारे में सोचने वाले पहले व्यक्ति नहीं थे। उस समय तक वापस जाने का अर्थ है कि आज हम जिन चीजों को लेने के लिए तैयार हुए हैं, उनमें से अधिकांश आसपास नहीं थीं; विचार करें कि कंप्यूटर 20 साल पहले क्या करने में सक्षम थे और इसकी वर्तमान स्थिति से तुलना करें। यहां तक ​​कि मूल लिनक्स बूटस्ट्रैप सिस्टम मिनिक्स को '87 तक जारी नहीं किया गया था , और जीएनयू का विकास '84 में शुरू हुआ था। इसलिए सिद्धांत रूप में यह प्रश्न का उत्तर दे सकता है, व्यवहार में यह एक उत्तर के रूप में काफी हद तक बेकार है।
बजे एक सीवी

2
सबसे पहला कंप्यूटर मैं संभवतः अपने हाथों को प्राप्त कर सकता हूं, यह 286 होगा। मुझे यह देखना होगा कि क्या मेरे दादा-दादी अभी भी हैं।
डेविड जे

1
बोनस अंक वास्तव में उस पर विचार करने के लिए :-)। @DavidJ
11,684

@ माइकलकॉर्जलिंग: वास्तव में नहीं; चूंकि यह केवल आपके बूटस्ट्रैपिंग की श्रृंखला को लंबा बनाता है। लेकिन शायद तब तक नहीं जब तक कि मशीन की भाषा में स्क्रैच से अपना कंपाइलर नहीं लिखा जाता।
Evi1M4chine
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.