Dakwaan Keselamatan Memori Bahasa Go Diserang Kerana Perlumbaan Data Membolehkan Tingkah Laku Tidak Ditentukan

Pasukan Komuniti BigGo
Dakwaan Keselamatan Memori Bahasa Go Diserang Kerana Perlumbaan Data Membolehkan Tingkah Laku Tidak Ditentukan

Komuniti pengaturcaraan sedang terlibat dalam perdebatan sengit tentang sama ada Go benar-benar boleh dianggap sebagai bahasa yang selamat dari segi memori. Perbincangan ini berpusat pada persoalan asas: bolehkah sesuatu bahasa mendakwa keselamatan memori apabila pengaturcaraan serentak boleh membawa kepada tingkah laku tidak ditentukan dan potensi kelemahan keselamatan?

Kontroversi ini berpunca daripada pendekatan Go dalam mengendalikan struktur data berbilang perkataan seperti antara muka dan hirisan dalam persekitaran serentak. Tidak seperti bahasa seperti Java atau C#, yang melabur besar-besaran dalam memastikan bahawa program dengan perlumbaan data tetap ditakrifkan dengan baik, Go membenarkan keadaan perlumbaan tertentu memecahkan jaminan keselamatan asas bahasa tersebut.

Masalah Teknikal

Apabila berbilang goroutine mengakses jenis antara muka Go atau hirisan secara serentak tanpa penyegerakan yang betul, runtime boleh mengalami bacaan terkoyak - situasi di mana benang membaca data yang dikemas kini sebahagian. Ini berlaku kerana struktur data ini dilaksanakan sebagai nilai berbilang perkataan yang tidak boleh dikemas kini secara atom pada kebanyakan pemproses.

Isu ini timbul apabila satu goroutine mengemas kini pemboleh ubah antara muka sementara yang lain membacanya. Goroutine yang membaca mungkin melihat campuran data lama dan baharu, berpotensi menganggap nilai integer sebagai penunjuk memori. Ini boleh membawa kepada kegagalan segmentasi apabila program cuba untuk merujuk alamat memori yang tidak sah.

Struktur Data Go yang Bermasalah

  • Jenis interface: Disimpan sebagai pasangan penunjuk (data + vtable) yang tidak boleh dikemas kini secara atomik
  • Slices: Struktur berbilang perkataan yang mengandungi penunjuk data, panjang, dan kapasiti
  • Maps: Tidak selamat untuk thread mengikut reka bentuk, boleh menyebabkan kerosakan di bawah akses serentak
  • Channels: Selamat untuk kes penggunaan yang dimaksudkan tetapi tidak menghalang perkongsian data yang tidak selamat

Respons Komuniti dan Kesan Industri

Komuniti pengaturcaraan telah menunjukkan reaksi bercampur-campur terhadap penemuan ini. Sesetengah pembangun berpendapat bahawa ini mewakili jurang yang ketara antara keselamatan yang dipasarkan oleh Go dan jaminan sebenarnya. Yang lain berpendapat bahawa senario sedemikian jarang berlaku dalam amalan dan bahawa pengesan perlumbaan terbina dalam Go membantu mengenal pasti isu ini semasa pembangunan.

Setiap kali perbualan ini timbul, saya teringat pasukan saya di Dropbox, di mana ia merupakan ritual peralihan untuk jurutera baharu memperkenalkan segfault dalam pelayan Go kami dengan tidak menyegerakkan penulisan kepada struktur data.

Perdebatan ini mempunyai implikasi yang lebih luas untuk cara industri mengkategorikan bahasa pengaturcaraan. Organisasi seperti NSA dan pelbagai agensi kerajaan telah memasukkan Go dalam senarai bahasa selamat memori mereka, cadangan yang mungkin memerlukan pertimbangan semula memandangkan batasan teknikal ini.

Landskap Keselamatan Memori yang Lebih Luas

Perbincangan ini menyerlahkan perselisihan asas tentang terminologi dalam dunia pengaturcaraan. Profesional keselamatan sering mentakrifkan keselamatan memori berdasarkan potensi eksploitasi praktikal, sementara ahli teori bahasa pengaturcaraan memberi tumpuan kepada jaminan formal dan pencegahan tingkah laku tidak ditentukan.

Bahasa seperti Rust dan Swift telah mengambil pendekatan yang berbeza, menggunakan sistem jenis yang canggih untuk mencegah perlumbaan data sepenuhnya. Java dan C# melabur dalam model memori yang memastikan program berlumba tetap ditakrifkan dengan baik, walaupun berpotensi tidak betul dalam logiknya.

Perbandingan Keselamatan Memori Mengikut Bahasa

Bahasa Model Memori Pengendalian Data Race Keselamatan Formal
Go Asas Boleh menyebabkan UB Terhad
Java JMM ( Java Memory Model ) Tingkah laku yang jelas Kuat
C CLR Memory Model Tingkah laku yang jelas Kuat
Rust Ownership + Send/Sync Pencegahan masa kompilasi Kuat
Swift Strict Concurrency Pencegahan masa kompilasi Kuat
JavaScript Single-threaded + Web Workers Penghantaran mesej Kuat

Kesimpulan

Walaupun Go kekal lebih selamat berbanding bahasa seperti C atau C++, bukti menunjukkan ia tidak dapat memberikan tahap jaminan keselamatan memori yang sama seperti bahasa yang benar-benar selamat. Untuk kebanyakan aplikasi, keselamatan praktikal Go mungkin mencukupi, tetapi organisasi yang memerlukan jaminan keselamatan formal harus mempertimbangkan dengan teliti batasan ini apabila membuat pilihan teknologi.

Perdebatan ini akhirnya mencerminkan pemahaman yang berkembang tentang apa yang membentuk pengaturcaraan selamat dan pertukaran antara prestasi, kesederhanaan, dan ketepatan formal dalam pembangunan perisian moden.

Rujukan: There is no memory safety without thread safety