-
Crash yang hanya terjadi di ARM64
- Dalam proses mem-porting kode network I/O EdgeDB dari Python ke Rust, muncul masalah di mana pengujian gagal secara intermiten pada runner CI ARM64.
- Awalnya terlihat seperti deadlock, tetapi sebenarnya proses mengalami crash dan test runner gagal mendeteksinya.
-
Teori awal
- Untuk memahami mengapa masalah ini hanya terjadi di ARM64, perbedaan model memori ikut dipertimbangkan.
- Model memori Intel bersifat ketat, sedangkan ARM memiliki model memori yang lebih lemah.
-
Debugging di mesin CI
- Masalah diselidiki dengan terhubung langsung ke runner ARM64 di AWS.
- Proses mengalami crash dan meninggalkan core dump, yang kemudian diperiksa untuk menemukan penyebab masalah.
-
Penyebab sebenarnya: setenv dan getenv
setenv tidak aman dalam lingkungan multithread dan dapat menyebabkan crash saat berinteraksi dengan getenv.
- Penetapan ulang variabel lingkungan terungkap sebagai penyebab masalah.
-
Kaitan dengan openssl_probe
- Masalah muncul ketika
openssl-probe menetapkan variabel lingkungan SSL_CERT_FILE dan SSL_CERT_DIR.
- Crash terjadi selama
rust-native-tls milik Rust menetapkan variabel lingkungan tersebut.
-
Mengapa hanya terjadi di ARM64 Linux
- Crash hanya terjadi jika beberapa kondisi terpenuhi sekaligus, termasuk jumlah variabel lingkungan dan kegagalan I/O.
-
Solusi
- Diputuskan untuk beralih dari backend
rust-native-tls/openssl milik reqwest ke rustls.
- Proyek Rust berencana menjadikan fungsi pengaturan lingkungan sebagai tidak aman, dan proyek
glibc meningkatkan keamanan thread pada getenv.
4 komentar
setenvtidak thread-safe, dan C tidak ingin memperbaikinyaFungsi
setenvbikin masalah lagi.Saya akan menulis judulnya sebagai, "Ketidakamanan thread pada stdlib C bahkan tidak bisa diselamatkan oleh Rust yang katanya aman." :)
Saya benar-benar memahaminya.
Komentar Hacker News
Di edisi Rust berikutnya, pengubah environment akan dibuat tidak aman. Ini bisa memengaruhi crate yang saling bertabrakan
set_vardanremove_varakan mewajibkan penggunaan blokunsafe {}pada edisi 2024Patch untuk glibc membuat
getenvlebih aman, tetapi C masih mengizinkan akses langsung ke environment sehingga tetap tidak sepenuhnya amansetenvaman untuk multithread, tetapi setidaknya API thread-safe yang baru seharusnya didefinisikanMengalami bug terkait environment di Linux dianggap semacam ritual peralihan
getenv_r(), menyinkronkannya dengansetenv(), serta memberi peringatan saat kompilasi/linking mungkin akan membantu menyelesaikan masalahKonfigurasi menggunakan variabel environment adalah bagian dari gerakan "12-factor app", tetapi ini dianggap sebagai pendekatan yang bodoh
Mesin CI yang berjalan di Amazon AWS punya kelebihan karena menyediakan pengguna root yang sesungguhnya
Ini artikel yang sangat bagus dalam mengupas bug yang tidak intuitif
env::set_varkini tidak amanset_varatauremove_varIni mengingatkan pada pengalaman ketika
setproctitletidak berfungsi di codebase tertentunumpy,setproctitletidak berfungsi, karena pemanggilangetenvatausetenvsaat inisialisasinumpymengubah alamatenviron