6 पॉइंट द्वारा GN⁺ 2026-03-30 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • initrd को कर्नेल द्वारा सीधे interpret और execute की जाने वाली program unit के रूप में परिभाषित करते हुए, Linux को एक तरह के interpreter के रूप में फिर से समझाया गया है
  • kexec, base64, cpio का उपयोग करके अपने-आप को reboot करने वाली recursive Linux distribution बनाई जाती है, जहाँ initrd खुद को फिर से execute करती है
  • अगर /init script को अपनी ही 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 करती है
  • r.cpio के अंदर /bin, /init, k फ़ाइलें शामिल हैं, जहाँ k Linux 6.18.18 kernel image है और /init shell 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 करे
    • अगर /init script आखिर में 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.so ELF की dynamic libraries load करने के बाद program चलाता है
    • इसलिए ELF को भी एक प्रकार की interpreter language माना जा सकता है
  • /bin/sh को ld.so interpret करता है, और ld.so को kernel सीधे interpret करता है
    • ld.so statically 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 किया जा सकता है
  • 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_misc register करके /r को execute करने के लिए configure किया जाए, खुद को execute करने वाली initrd पूरी हो जाती है
    • /r CPIO 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 टिप्पणियां

 
github88 2026-03-31

कहते हैं अज्ञान इंसान को बेखौफ बना देता है.. उम्मीद है ऐसे लेखों से बचा जाएगा।

 
GN⁺ 2026-03-30
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” कहना सचमुच ग़लत व्याख्या है

    • ELF फ़ाइल भी अपने आप में program नहीं हो सकती। कुछ ELF में dynamic library होने की वजह से entry point नहीं होता। जैसे कुछ ELF executable होते हैं, वैसे ही कुछ CPIO को भी executable माना जा सकता है। आख़िरकार ld.so ELF को memory में खोलता है और entry point चलाता है, और उसी तरह kernel initramfs को खोलकर entry point चलाता है — यह एक मिलता-जुलता विचार है
    • cpio के अंदर की init file ही असल में interpret होने वाला program है, और बाकी फ़ाइलें उस program के इस्तेमाल की memory जैसी भूमिका निभाती हैं
    • binary program CPU पर चलता है, लेकिन program file ख़ुद कई sections से बनी एक archive structure होती है। CPU program file को सीधे नहीं समझता। Linux उस address space को सेट करता है जहाँ program चलेगा, और फिर program counter जिस address की ओर इशारा कर रहा हो वहाँ jump करता है। ELF के metadata sections इसी प्रक्रिया को परिभाषित करते हैं
    • कम से कम यह सुकून है कि यह AI से लिखा हुआ लेख नहीं है
  • क्या हर OS kernel privilege के साथ machine code interpreter की तरह काम नहीं करता?

    • मुझे नहीं लगता। OS हर instruction को ख़ुद interpret नहीं करता, बल्कि उसे CPU को देकर execute करवाता है
    • OS एक interface है जो system resources का इस्तेमाल संभव बनाता है। machine code को CPU interpret करता है, और OS यह निर्देश दे सकता है कि CPU क्या चलाए
    • इस मामले में इसे CPIO फ़ाइल का interpreter माना जा सकता है
  • यह लेख “Linux एक interpreter है” वाले mental model के रूप में ठीक है, लेकिन अगर इसे शब्दशः लिया जाए तो ग़लत है
    CPU instruction स्तर पर interpretation की बात नहीं है, बल्कि kernel ELF, shebang script, initramfs जैसे execution formats को orchestrate करता है — इस नज़रिए से यह ज़्यादा उचित है। भ्रम शायद ‘interpreter’ के दो अर्थों के मिल जाने से पैदा हुआ है

  • मुद्दा यह नहीं है कि रूपक सही है या नहीं, बल्कि यह है कि ‘execution’ की अवधारणा कितनी हद तक environment पर निर्भर करती है

  • “सब कुछ interpreter है?”

    • हाँ, लेकिन compiler अपवाद है
  • Turing का Theta Combinator

    • यह इस लेख से कैसे जुड़ा है, मुझे ठीक से समझ नहीं आया। मैं functional programming की अवधारणाओं से परिचित नहीं हूँ
  • इस series की पिछली पोस्ट में लेखक ने कहा था कि वह Contabo का object storage इस्तेमाल नहीं करना चाहता था, इसलिए उसने ख़ुद VPS image बनाई
    मुझे लगता है कि महीने के 1.50 डॉलर बचाने के लिए 50 घंटे खर्च करने और tokens पर 2.5 लाख डॉलर उड़ा देने जैसी अतियों के बीच कहीं संतुलन होता है।
    अगर आप infra cost नहीं उठा सकते, तो शायद समस्या तकनीकी क्षमता से ज़्यादा सामाजिक कारणों की हो सकती है। curl से Doom चलाने पर अटक जाना मुझे productive नहीं लगता

    • मैं भी पहले ऐसा ही था। VPS के 5 euro प्रति माह मुझे बहुत महंगे लगते थे, इसलिए पैसे इकट्ठे होने तक instance बंद कर देता था और root filesystem को माँ के laptop पर backup करता था। बाद में Kindle पर Terminal IDE डालकर busybox और gcc के साथ खेलता था। करियर की शुरुआत बनाने के लिए Spartacus Rex का धन्यवाद
    • लेखक की बात मज़ाक थी। असली वजह ठीक अगले paragraph में है — “मुझे लगा यह एक मज़ेदार trick है, और अगर इसे blog पर डालूँ तो मैं भी सीखूँगा, पाठक भी सीखेंगे, और internet points भी मिलेंगे — एक win-win
    • जो चीज़ किसी और को unproductive लगे, वह किसी व्यक्ति के लिए विशेष रुचि का स्रोत हो सकती है, और उसका आनंद लेना mental health के लिए महत्वपूर्ण है। ADHD होने के कारण मेरे लिए तो यह उल्टा ज़रूरी गतिविधि है
    • “अगर तुम 1.50 डॉलर नहीं दे सकते तो प्रो नहीं हो” — यह बात अजीब है। professional की परिभाषा इस बात से होती है कि उसे पैसे मिलते हैं या नहीं, न कि वह कितना खर्च करता है
  • man ld.so देखने पर साफ़ लिखा है कि ELF के .interp section में रखा 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 से कर लेता हूँ

    • अगर आपको तेज़ और simple environment चाहिए तो Sway + foot का combination अच्छा है। keybindings से workspace सेट कर लें तो desktop के बिना भी आराम से इस्तेमाल किया जा सकता है
    • Windows GUI बेहतर है, इससे मैं सहमत नहीं हूँ। GNOME और KDE भी ख़ास नहीं हैं, लेकिन Windows में आप Microsoft के जटिल WM से निकल ही नहीं सकते। मेरी निजी राय में Xerox-शैली से बेहतर mpx/mux-शैली interface (जैसे 9wm, cwm, dwm) हैं। वे Engelbart की philosophy के ज़्यादा क़रीब हैं और कुल मिलाकर ज़्यादा साफ़-सुथरे लगते हैं