Linux एक interpreter है
(astrid.tech)- initrd को कर्नेल द्वारा सीधे interpret और execute की जाने वाली program unit के रूप में परिभाषित करते हुए, Linux को एक तरह के interpreter के रूप में फिर से समझाया गया है
kexec,base64,cpioका उपयोग करके अपने-आप को reboot करने वाली recursive Linux distribution बनाई जाती है, जहाँ initrd खुद को फिर से execute करती है- अगर
/initscript को अपनी ही cpio image output करने के लिए बनाया जाए, तो Quine-शैली की self-replicating initrd बनती है - ELF execution structure और
ld.so,binfmt_miscके जरिए interpreter layers के कर्नेल तक जारी रहने वाली संरचना समझाई गई है kexecया QEMU का उपयोग करने पर Linux के ऊपर एक और Linux को tail-recursive तरीके से चलाना संभव है, जिससे kernel, virtualization, और interpreter की सीमाएँ प्रयोगात्मक रूप से फैलती हैं
rkx.gz का reverse engineering और self-recursive initrd संरचना
curl https://astrid.tech/rkx.gz | gunzip | sudo shकमांड 20MB आकार की base64-encoded shell script को डाउनलोड करके चलाती है- script root permissions की जाँच करती है और
kexec,base64,cpioकी मौजूदगी की पुष्टि करती है - base64 data को decode करके
rनाम का cpio archive बनाती है, और उसके भीतर सेkनाम की kernel image निकालती है kexecका उपयोग करकेkको kernel औरrको ramdisk के रूप में load करने के बाद execute करती है
- script root permissions की जाँच करती है और
r.cpioके अंदर/bin,/init,kफ़ाइलें शामिल हैं, जहाँkLinux 6.18.18 kernel image है और/initshell script के रूप में है/init/procको mount करती है,/rमें मौजूदा file system को cpio के रूप में पैक करती है, फिरkexecसे/kऔर/rको दोबारा execute करती है- नतीजतन यह अपने-आप को लगातार reboot करने वाली recursive Linux distribution बन जाती है
Linux kernel को interpreter के रूप में देखने का नज़रिया
- initrd सिर्फ़ boot के लिए ramdisk नहीं है, बल्कि इसे Linux kernel द्वारा interpret और execute किए जाने वाले program के रूप में देखा जा सकता है
curl | shयाpython3 script.pyकी तरह, initrd भी kernel द्वारा execute किया जाने वाला input program है- इसलिए Linux kernel initrd को interpret करने वाले interpreter की तरह काम करता है
- यह संरचना tail-call optimization जैसी है
kexecपिछले kernel को overwrite नहीं करता, बल्कि नए memory space में load करके execute करता है- हर kernel पिछली state को बनाए नहीं रखता, बल्कि नए “stack frame” से replace हो जाता है
Quine और initrd self-replication
- Quine का मतलब ऐसा program जो खुद को output करे
- अगर
/initscript आखिर मेंcat /rचलाए, तो वह अपने जैसा ही cpio output करती है - इस स्थिति में Linux initrd interpreter का Quine बनता है
- चूँकि सभी फ़ाइलें RAM पर मौजूद
tmpfsमें हैं, इसलिए वास्तविक disk I/O नहीं होता
- अगर
ELF, ld.so, और interpreter की परतें
- ELF executable अपनी header में interpreter (
ld-linux-x86-64.so.2) का path शामिल करती है- execution के समय kernel पहले
ld.soको चलाता है, औरld.soELF की dynamic libraries load करने के बाद program चलाता है - इसलिए ELF को भी एक प्रकार की interpreter language माना जा सकता है
- execution के समय kernel पहले
/bin/shकोld.sointerpret करता है, औरld.soको kernel सीधे interpret करता हैld.sostatically linked ELF है, इसलिए kernel उसे सीधे execute कर सकता है- इस तरह interpreter hierarchy का base case बनता है
binfmt_misc के जरिए CPIO execution
binfmt_miscका उपयोग करके विशिष्ट magic bytes वाले file को तय interpreter से execute कराया जा सकता है- उदाहरण registration command:
echo ':cpio:M::\x30\x37\x30\x37\x30\x31::/path/to/my/script.sh:' > /proc/sys/fs/binfmt_misc/register - इस setting के साथ
chmod +xकिए गए CPIO files को सीधे execute किया जा सकता है
- उदाहरण registration command:
- QEMU का उपयोग करके CPIO को initrd के रूप में चलाने वाली script को interpreter के रूप में register किया जा सकता है
- QEMU तय kernel और initrd का उपयोग करके virtual machine boot करता है
- नतीजतन CPIO file का interpreter QEMU द्वारा चलाया गया Linux kernel बन जाता है
Recursive interpreter और “सबसे अजीब loop”
- QEMU-आधारित interpreter नई Linux environment stack frame बनाता है
- Linux के ऊपर एक और Linux चलाने वाली संरचना में, memory limit तक nesting संभव है
- अगर इसे
kexec-आधारित interpreter से बदला जाए, तो tail-call optimized recursive Linux execution संभव है
- अगर
/initमेंbinfmt_miscregister करके/rको execute करने के लिए configure किया जाए, खुद को execute करने वाली initrd पूरी हो जाती है/rCPIO format में अगला init process है, जो execute होने पर फिर से खुद को interpret करता है
निष्कर्ष
- initrd सिर्फ़ एक boot tool नहीं, बल्कि Linux kernel द्वारा interpret की जाने वाली program unit है
kexecऔरbinfmt_miscकी मदद से Linux को ही interpreter की तरह recursive तरीके से चलाना संभव है- यह संरचना kernel, virtualization, interpreter, और self-replicating programs की सीमाओं को तोड़ने वाली एक प्रयोगात्मक अवधारणा है
- संबंधित source code GitHub repository ifd3f/rekexec में उपलब्ध है
2 टिप्पणियां
कहते हैं अज्ञान इंसान को बेखौफ बना देता है.. उम्मीद है ऐसे लेखों से बचा जाएगा।
Hacker News की राय
यह लेख पढ़ते समय बहुत ज़्यादा गलतफ़हमियों की वजह से काफ़ी तकलीफ़ हुई
cpio archive कोई filesystem नहीं है। लेखक initramfs का इस्तेमाल कर रहा है, जो tmpfs-आधारित है। Linux cpio को tmpfs में extract कर सकता है। फ़ाइलों और directories का archive अपने आप में कोई program नहीं होता
कोई चीज़ सिर्फ़ इसलिए एक जैसी नहीं हो जाती कि वह मिलती-जुलती दिखती है। binary program CPU पर चलता है, और अगर कोई interpreter है तो वह hardware environment के अंदर छिपा है। यह kernel के दायरे से बाहर है
shell script चलाने के लिए उस script को interpret करने वाला shell चाहिए। लेखक ने इस हिस्से को छोड़ दिया और kernel और shell program को गड़बड़ा दिया
Linux को initramfs या ramdisk के बिना भी compile किया जा सकता है, और तब भी वह filesystem के userland को चला सकता है
“Linux initrd interpreter” कहना सचमुच ग़लत व्याख्या है
क्या हर OS kernel privilege के साथ machine code interpreter की तरह काम नहीं करता?
यह लेख “Linux एक interpreter है” वाले mental model के रूप में ठीक है, लेकिन अगर इसे शब्दशः लिया जाए तो ग़लत है
CPU instruction स्तर पर interpretation की बात नहीं है, बल्कि kernel ELF, shebang script, initramfs जैसे execution formats को orchestrate करता है — इस नज़रिए से यह ज़्यादा उचित है। भ्रम शायद ‘interpreter’ के दो अर्थों के मिल जाने से पैदा हुआ है
मुद्दा यह नहीं है कि रूपक सही है या नहीं, बल्कि यह है कि ‘execution’ की अवधारणा कितनी हद तक environment पर निर्भर करती है
“सब कुछ interpreter है?”
Turing का Theta Combinator
इस series की पिछली पोस्ट में लेखक ने कहा था कि वह Contabo का object storage इस्तेमाल नहीं करना चाहता था, इसलिए उसने ख़ुद VPS image बनाई
मुझे लगता है कि महीने के 1.50 डॉलर बचाने के लिए 50 घंटे खर्च करने और tokens पर 2.5 लाख डॉलर उड़ा देने जैसी अतियों के बीच कहीं संतुलन होता है।
अगर आप infra cost नहीं उठा सकते, तो शायद समस्या तकनीकी क्षमता से ज़्यादा सामाजिक कारणों की हो सकती है। curl से Doom चलाने पर अटक जाना मुझे productive नहीं लगता
man ld.soदेखने पर साफ़ लिखा है कि ELF के.interpsection में रखा dynamic linker execute किया जाता है। section का नाम अपने आप में दिलचस्प हैLinux एक programmable interface के रूप में बहुत उपयोगी है। Windows में भी यह संभव है, लेकिन Linux ज़्यादा उपयुक्त लगता है
GUI के मामले में मुझे Windows बेहतर लगता है, लेकिन GNOME या KDE भी असुविधाजनक हैं। इसलिए मैं fluxbox, icewm, और कभी-कभी xfce या mate-desktop इस्तेमाल करता हूँ। आजकल मुझे simple और fast environment पसंद है। ज़्यादातर काम command line और code editing से कर लेता हूँ