6 poin oleh GN⁺ 23 hari lalu | 2 komentar | Bagikan ke WhatsApp
  • Mendefinisikan initrd sebagai unit program yang diinterpretasikan dan dijalankan langsung oleh kernel, lalu menafsirkan ulang Linux sebagai semacam interpreter
  • Membangun distribusi Linux rekursif yang me-reboot dirinya sendiri dengan kexec, base64, dan cpio, sehingga initrd menjalankan dirinya lagi
  • Jika skrip /init dibuat untuk mencetak image cpio miliknya sendiri, akan terbentuk initrd yang mereplikasi diri dalam bentuk Quine
  • Menjelaskan struktur berlapis interpreter yang berlanjut hingga ke kernel melalui struktur eksekusi ELF, ld.so, dan binfmt_misc
  • Dengan kexec atau QEMU, Linux di atas Linux dapat dijalankan secara tail-recursive, sehingga batas antara kernel, virtualisasi, dan interpreter diperluas secara eksperimental

Reverse engineering rkx.gz dan struktur initrd rekursif mandiri

  • Perintah curl https://astrid.tech/rkx.gz | gunzip | sudo sh mengunduh dan menjalankan skrip shell berukuran 20MB yang di-encode dengan base64
    • Skrip memeriksa hak akses root dan keberadaan kexec, base64, serta cpio
    • Data base64 didekode menjadi arsip cpio bernama r, lalu image kernel bernama k diekstrak dari dalamnya
    • Dengan kexec, k dimuat sebagai kernel dan r sebagai ramdisk, lalu dijalankan
  • Di dalam r.cpio terdapat file /bin, /init, dan k; k adalah image kernel Linux 6.18.18, sementara /init berbentuk skrip shell
    • /init me-mount /proc, lalu membungkus sistem file saat ini menjadi cpio di /r, kemudian menjalankan kembali /k dan /r lewat kexec
    • Hasilnya adalah distribusi Linux rekursif yang terus me-reboot dirinya sendiri

Sudut pandang yang melihat kernel Linux sebagai interpreter

  • initrd bukan sekadar ramdisk untuk boot, melainkan dapat dipandang sebagai program yang diinterpretasikan dan dijalankan oleh kernel Linux
    • Seperti curl | sh atau python3 script.py, initrd juga merupakan bentuk program input yang dijalankan oleh kernel
    • Karena itu, kernel Linux berfungsi sebagai interpreter yang menginterpretasikan initrd
  • Struktur ini mirip dengan optimisasi tail recursion (tail-call optimization)
    • kexec memuat dan menjalankan kernel baru di ruang memori baru tanpa menimpa kernel sebelumnya
    • Setiap kernel tidak mempertahankan state sebelumnya, melainkan diganti dengan “stack frame” baru

Quine dan replikasi diri initrd

  • Quine berarti program yang mencetak dirinya sendiri
    • Jika skrip /init di akhir menjalankan cat /r, maka ia akan mencetak cpio yang identik dengan dirinya
    • Dalam kasus ini terbentuk Quine dari interpreter initrd Linux
    • Karena semua file berada di tmpfs dalam RAM, tidak terjadi I/O disk nyata

ELF, ld.so, dan lapisan interpreter

  • File eksekusi ELF memuat path interpreter (ld-linux-x86-64.so.2) di header-nya
    • Saat dieksekusi, kernel lebih dulu menjalankan ld.so, lalu ld.so memuat library dinamis ELF dan menjalankan program
    • Karena itu, ELF juga dapat dipandang sebagai semacam bahasa interpreter
  • /bin/sh diinterpretasikan oleh ld.so, dan ld.so sendiri diinterpretasikan langsung oleh kernel
    • ld.so adalah ELF yang ditautkan secara statis, sehingga bisa dijalankan langsung oleh kernel
    • Dengan demikian terbentuk basis (base case) dari lapisan interpreter

Menjalankan CPIO melalui binfmt_misc

  • Dengan binfmt_misc, file dengan magic byte tertentu bisa dijalankan memakai interpreter yang ditentukan
    • Contoh perintah pendaftaran:
      echo ':cpio:M::\x30\x37\x30\x37\x30\x31::/path/to/my/script.sh:' > /proc/sys/fs/binfmt_misc/register
      
    • Dengan pengaturan ini, file CPIO yang sudah chmod +x dapat dijalankan langsung
  • Skrip yang menjalankan CPIO sebagai initrd lewat QEMU dapat didaftarkan sebagai interpreter
    • QEMU mem-boot mesin virtual dengan kernel dan initrd yang ditentukan
    • Hasil akhirnya, interpreter untuk file CPIO adalah kernel Linux yang dijalankan oleh QEMU

Interpreter rekursif dan “strange loop”

  • Interpreter berbasis QEMU membuat stack frame lingkungan Linux baru
    • Dengan struktur Linux di atas Linux, penumpukan bisa berlangsung hingga batas memori
    • Jika diganti dengan interpreter berbasis kexec, maka eksekusi Linux rekursif dengan optimisasi tail call menjadi mungkin
  • Jika /init dikonfigurasi untuk mendaftarkan binfmt_misc lalu menjalankan /r, initrd yang menjalankan dirinya sendiri pun terbentuk
    • /r adalah proses init berikutnya dalam format CPIO, dan saat dijalankan ia kembali menginterpretasikan dirinya sendiri

Kesimpulan

  • initrd bukan sekadar alat boot, tetapi unit program yang diinterpretasikan oleh kernel Linux
  • Dengan kexec dan binfmt_misc, Linux sendiri dapat dijalankan secara rekursif layaknya interpreter
  • Struktur ini adalah konsep eksperimental yang meruntuhkan batas antara kernel, virtualisasi, interpreter, dan program yang mereplikasi diri
  • Kode sumber terkait dipublikasikan di repositori GitHub ifd3f/rekexec

2 komentar

 
github88 22 hari lalu

Katanya, kalau tidak tahu malah jadi berani.. Saya harap tulisan seperti ini sebaiknya dihindari.

 
GN⁺ 23 hari lalu
Komentar Hacker News
  • Membaca tulisan ini terasa menyakitkan karena terlalu banyak kesalahpahaman
    Arsip cpio bukan filesystem. Penulis memakai initramfs, yang berbasis tmpfs. Linux dapat mengekstrak cpio ke tmpfs. Arsip file dan direktori pada dirinya sendiri bukanlah program
    Hanya karena sesuatu tampak mirip bukan berarti keduanya sama. Program biner dijalankan di CPU, dan jika ada interpreter, maka ia tersembunyi di lingkungan perangkat keras. Itu berada di luar cakupan kernel
    Untuk menjalankan shell script, Anda memerlukan shell yang akan menafsirkan script tersebut. Penulis melewatkan bagian ini dan mencampuradukkan kernel dengan program shell
    Linux dapat dikompilasi tanpa initramfs maupun ramdisk, dan tetap bisa menjalankan userland filesystem
    Ungkapan “Linux initrd interpreter” benar-benar penjelasan yang keliru

    • File ELF juga belum tentu merupakan program pada dirinya sendiri. Sebagian ELF adalah library dinamis dan tidak memiliki entry point. Seperti halnya sebagian ELF dapat dieksekusi, sebagian CPIO juga bisa dianggap dapat dieksekusi. Pada akhirnya, ld.so mengekstrak ELF ke memori dan menjalankan entry point, sementara kernel mengekstrak initramfs dan menjalankan entry point; keduanya merupakan konsep yang serupa
    • File init di dalam cpio adalah program yang benar-benar ditafsirkan, sedangkan file-file lainnya berperan sebagai memori yang digunakan program tersebut
    • Program biner dijalankan di CPU, tetapi file program itu sendiri adalah struktur arsip yang terdiri dari berbagai section. CPU tidak dapat memahami file program secara langsung. Linux menyiapkan address space tempat program akan berjalan, lalu melompat ke alamat yang ditunjuk oleh program counter. Section metadata ELF mendefinisikan proses ini
    • Setidaknya ini menghibur karena tampaknya bukan tulisan yang dibuat AI
  • Bukankah semua OS bertindak sebagai interpreter machine code dengan hak kernel?

    • Menurut saya tidak. OS tidak menafsirkan setiap instruksi secara langsung, melainkan menyerahkannya ke CPU untuk dieksekusi
    • OS adalah antarmuka yang memungkinkan penggunaan sumber daya sistem. CPU yang menafsirkan machine code, dan OS dapat mengarahkan CPU tentang apa yang harus dijalankan
    • Dalam kasus ini, itu bisa dilihat sebagai interpreter untuk file CPIO
  • Tulisan ini cukup oke jika dipahami sebagai model mental “Linux adalah interpreter”, tetapi salah jika diterima secara harfiah
    Lebih masuk akal bila dipandang bukan sebagai interpretasi pada level instruksi CPU, melainkan sebagai peran kernel dalam mengorkestrasi format eksekusi seperti ELF, script shebang, dan initramfs. Kebingungannya tampaknya muncul karena dua makna dari kata ‘interpreter’ tercampur

  • Intinya bukan apakah analoginya tepat, melainkan bahwa ini menunjukkan betapa bergantung pada lingkungan konsep eksekusi itu

  • “Segalanya adalah interpreter?”

    • Ya, tetapi compiler adalah pengecualian
  • Theta Combinator milik Turing

    • Saya tidak begitu paham apa kaitannya dengan tulisan ini. Saya tidak terbiasa dengan konsep pemrograman fungsional
  • Dalam tulisan sebelumnya di seri ini, penulis mengatakan ia membuat image VPS sendiri karena tidak ingin memakai object storage dari Contabo
    Menurut saya ada titik keseimbangan antara menghabiskan 50 jam demi menghemat $1.50 per bulan dan menghabiskan $250.000 untuk token.
    Jika Anda tidak mampu menanggung biaya infrastruktur, mungkin masalahnya adalah faktor sosial, bukan kemampuan teknis. Terobsesi menjalankan Doom lewat curl terasa tidak produktif

    • Saya juga dulu begitu. VPS 5 euro per bulan terasa terlalu mahal, jadi saya sering mematikan instance dan mencadangkan root filesystem ke laptop ibu saya sampai uang terkumpul lagi. Belakangan saya memasang Terminal IDE di Kindle dan bermain-main dengan busybox serta gcc. Terima kasih kepada Spartacus Rex yang membantu memulai karier saya
    • Yang dimaksud penulis itu bercanda. Alasan sebenarnya ada tepat di paragraf berikutnya — “Saya pikir ini trik yang menarik, dan kalau saya tulis di blog, saya bisa belajar, pembaca juga bisa belajar, dan saya juga dapat poin internet, sebuah win-win
    • Bagi sebagian orang mungkin terlihat tidak produktif, tetapi menikmati minat yang sangat spesifik itu penting untuk kesehatan mental. Sebagai orang dengan ADHD, justru itu aktivitas yang saya butuhkan
    • Pernyataan “kalau tidak bisa bayar $1.50 maka Anda bukan profesional” terdengar aneh. Profesional didefinisikan oleh apakah seseorang dibayar, bukan oleh pengeluarannya
  • Jika melihat man ld.so, tertulis bahwa dynamic linker yang disimpan di section .interp milik ELF akan dijalankan. Nama section itu sendiri menarik

  • Linux sangat berguna sebagai antarmuka yang dapat diprogram. Windows juga bisa, tetapi Linux terasa lebih cocok
    Untuk GUI saya rasa Windows lebih baik, tetapi GNOME maupun KDE juga terasa kurang nyaman. Karena itu saya memakai fluxbox, icewm, kadang xfce atau mate-desktop. Akhir-akhir ini saya lebih menyukai lingkungan yang sederhana dan cepat. Sebagian besar pekerjaan saya lakukan lewat command line dan pengeditan kode

    • Jika menginginkan lingkungan yang cepat dan sederhana, kombinasi Sway + foot bagus. Dengan menyusun workspace lewat keybind, Anda bisa bekerja nyaman bahkan tanpa desktop penuh
    • Saya tidak setuju bahwa GUI Windows lebih baik. GNOME dan KDE juga kurang bagus, tetapi di Windows Anda tidak bisa lepas dari WM yang rumit milik Microsoft. Secara pribadi saya jauh lebih menyukai antarmuka keluarga mpx/mux daripada keluarga Xerox (misalnya 9wm, cwm, dwm). Itu lebih dekat dengan filosofi Engelbart dan secara umum terasa lebih rapi