Kami memiliki beberapa sistem build dalam produksi yang tidak ada yang peduli dan mesin ini menjalankan versi GCC kuno seperti GCC 3 atau GCC 2.
Dan saya tidak dapat membujuk manajemen untuk memutakhirkannya ke yang lebih baru: mereka berkata, "jika tidak rusak, jangan memperbaikinya".
Karena kita memelihara basis kode yang sangat lama (ditulis pada tahun 80-an), kode C89 ini mengkompilasi dengan baik pada kompiler ini.
Tapi saya tidak yakin sebaiknya menggunakan barang-barang lama ini.
Pertanyaanku adalah:
Bisakah menggunakan kompiler C lama membahayakan keamanan program yang dikompilasi?
MEMPERBARUI:
Kode yang sama dibangun oleh Visual Studio 2008 untuk target Windows, dan MSVC belum mendukung C99 atau C11 (Saya tidak tahu apakah MSVC yang lebih baru melakukannya), dan saya dapat membangunnya di kotak Linux saya menggunakan GCC terbaru. Jadi jika kita hanya memasukkan GCC yang lebih baru, itu mungkin akan membangun sama baiknya dengan sebelumnya.
-O3 -Wall -Wextra -fsanitize=undefined
dengan gcc dan dentang modern akan membantu.Jawaban:
Sebenarnya saya berpendapat sebaliknya.
Ada sejumlah kasus di mana perilaku tidak ditentukan oleh standar C tetapi di mana jelas apa yang akan terjadi dengan "kompiler bodoh" pada platform tertentu. Kasus-kasus seperti membiarkan integer yang ditandatangani meluap atau mengakses memori yang sama melalui variabel dari dua tipe yang berbeda.
Versi terbaru gcc (dan dentang) telah mulai memperlakukan kasus-kasus ini sebagai peluang optimisasi yang tidak peduli jika mereka mengubah perilaku biner dalam kondisi "perilaku tidak terdefinisi". Ini sangat buruk jika basis kode Anda ditulis oleh orang-orang yang memperlakukan C seperti "assembler portabel". Seiring berjalannya waktu optimisers mulai melihat potongan kode yang lebih besar dan lebih besar ketika melakukan optimisasi ini meningkatkan kemungkinan biner pada akhirnya melakukan sesuatu selain dari "apa yang biner dibangun oleh kompiler bodoh" akan lakukan.
Ada switch kompiler untuk mengembalikan perilaku "tradisional" (-fwrapv dan -fno-strict-aliasing untuk dua yang saya sebutkan di atas), tetapi pertama-tama Anda harus tahu tentang mereka.
Sementara pada prinsipnya bug kompiler dapat mengubah kode yang sesuai menjadi lubang keamanan saya akan mempertimbangkan risiko ini diabaikan dalam skema besar hal.
sumber
people who treated C like a "portable assembler"
bukankah itu C?Ada risiko dalam kedua tindakan tersebut.
Kompiler yang lebih tua memiliki keuntungan jatuh tempo, dan apa pun yang rusak di dalamnya mungkin (tetapi tidak ada jaminan) berhasil diselesaikan.
Dalam hal ini, kompiler baru adalah sumber potensial bug baru.
Di sisi lain, kompiler yang lebih baru hadir dengan tooling tambahan :
Menginstruksikan biner Anda dengan pembersih (Pembersih Alamat, Pembersih Memori atau Pembersih Perilaku Tidak Terdefinisi) dan kemudian mengaburkannya (menggunakan American Fuzzy Lop misalnya) telah menemukan kerentanan dalam sejumlah perangkat lunak profil tinggi, lihat misalnya artikel LWN.net ini .
Alat-alat baru itu, dan semua alat masa depan, tidak dapat diakses oleh Anda kecuali Anda meningkatkan kompiler Anda.
Dengan tetap menggunakan kompiler yang kurang bertenaga, Anda meletakkan kepala di pasir dan menyilangkan jari yang tidak menemukan kerentanan. Jika produk Anda adalah target bernilai tinggi, saya mendorong Anda untuk mempertimbangkan kembali.
Catatan: bahkan jika Anda TIDAK meningkatkan kompiler produksi, Anda mungkin ingin menggunakan kompiler baru untuk memeriksa kerentanannya; Sadarilah bahwa karena mereka adalah kompiler yang berbeda, jaminannya berkurang.
sumber
Kode kompilasi Anda mengandung bug yang dapat dieksploitasi. Bug berasal dari tiga sumber: Bug dalam kode sumber Anda, bug di kompiler dan pustaka, dan perilaku yang tidak terdefinisi dalam kode sumber Anda bahwa kompiler berubah menjadi bug. (Perilaku tidak terdefinisi adalah bug, tetapi belum bug dalam kode yang dikompilasi. Sebagai contoh, i = i ++; di C atau C ++ adalah bug, tetapi dalam kode yang dikompilasi Anda dapat meningkatkan i sebesar 1 dan menjadi OK, atau mengatur saya ke beberapa sampah dan menjadi bug).
Tingkat bug dalam kode yang dikompilasi Anda mungkin rendah karena pengujian dan untuk memperbaiki bug karena laporan bug pelanggan. Jadi mungkin ada sejumlah besar bug pada awalnya, tetapi itu sudah turun.
Jika Anda memutakhirkan ke kompiler yang lebih baru, Anda mungkin kehilangan bug yang diperkenalkan oleh bug kompiler. Tetapi semua bug ini akan menjadi bug yang sepengetahuan Anda tidak ada yang ditemukan dan dieksploitasi. Tetapi kompiler baru mungkin memiliki bug sendiri, dan yang penting kompiler baru memiliki kecenderungan yang lebih kuat untuk mengubah perilaku tidak terdefinisi menjadi bug dalam kode yang dikompilasi.
Jadi Anda akan memiliki banyak bug baru dalam kode kompilasi Anda; semua bug yang dapat ditemukan dan dieksploitasi oleh peretas. Dan kecuali Anda melakukan banyak pengujian, dan meninggalkan kode Anda dengan pelanggan untuk menemukan bug untuk waktu yang lama, itu akan kurang aman.
sumber
getaddrinfo()
: access.redhat.com/articles/2161461 . Contoh itu sebenarnya bukan cacat keamanan kompiler, tetapi lebih dari 10+ tahun pasti ada beberapa kelemahan tetap yang diketahui.Jika tidak rusak, jangan memperbaikinya
Bos Anda kedengarannya benar mengatakan ini, namun, faktor yang lebih penting , adalah melindungi input, output, buffer overflows. Kurangnya itu selalu merupakan tautan terlemah dalam rantai dari sudut pandang itu terlepas dari kompiler yang digunakan.
Namun, jika basis kode adalah kuno, dan pekerjaan telah dilakukan untuk mengurangi kelemahan K&R C yang digunakan, seperti kurangnya keamanan jenis, tidak amannya anggaran, dll, menimbang pertanyaan " Apakah meningkatkan kompiler ke C99 yang lebih modern / Standar C11 menghancurkan segalanya? "
Asalkan, ada jalur yang jelas untuk bermigrasi ke standar C yang lebih baru, yang dapat menyebabkan efek samping, mungkin yang terbaik adalah mencoba garpu basis kode lama, menilai dan memasukkan cek tipe tambahan, pemeriksaan kewarasan, dan menentukan apakah meningkatkan ke kompiler yang lebih baru memiliki efek pada dataset input / output.
Kemudian Anda dapat menunjukkannya kepada atasan Anda, " Ini basis kode yang diperbarui, dire-refoured, lebih sesuai dengan standar C99 / C11 yang diterima industri ... ".
Itu pertaruhan yang harus dipertimbangkan, dengan sangat hati-hati , penolakan terhadap perubahan mungkin terlihat di sana di lingkungan itu dan mungkin menolak untuk menyentuh barang-barang baru.
EDIT
Hanya duduk santai selama beberapa menit, menyadari ini banyak, kode yang dihasilkan K&R dapat berjalan pada platform 16bit, kemungkinannya, peningkatan ke kompiler yang lebih modern benar-benar dapat memecahkan basis kode, saya berpikir dalam hal arsitektur, kode 32 bit akan dihasilkan , ini bisa memiliki efek samping yang lucu pada struktur yang digunakan untuk dataset input / output, yang merupakan faktor besar lainnya untuk dipertimbangkan dengan cermat.
Juga, karena OP telah menyebutkan menggunakan Visual Studio 2008 untuk membangun basis kode, menggunakan gcc dapat mendorong membawa ke lingkungan baik MinGW atau Cygwin, yang dapat memiliki dampak perubahan pada lingkungan, kecuali, targetnya adalah untuk Linux, maka itu akan menjadi layak dicoba, mungkin harus menyertakan sakelar tambahan ke kompiler untuk meminimalkan kebisingan pada basis kode K&R yang lama, hal penting lainnya adalah melakukan banyak pengujian untuk memastikan tidak ada fungsi yang rusak, dapat berubah menjadi latihan yang menyakitkan.
sumber
Tentu saja bisa, jika kompiler lama berisi bug yang dikenal yang Anda tahu akan memengaruhi program Anda.
Pertanyaannya adalah, bukan? Untuk mengetahui dengan pasti, Anda harus membaca seluruh log perubahan dari versi Anda hingga tanggal sekarang dan memeriksa setiap bug yang diperbaiki selama bertahun-tahun.
Jika Anda tidak menemukan bukti bug kompiler yang akan memengaruhi program Anda, memperbarui GCC hanya demi itu kelihatannya agak paranoid. Anda harus ingat bahwa versi yang lebih baru mungkin mengandung bug baru, yang belum ditemukan. Banyak perubahan yang dilakukan baru-baru ini dengan dukungan GCC 5 dan C11.
Yang sedang berkata, kode yang ditulis pada tahun 80-an kemungkinan besar sudah diisi sampai penuh dengan lubang keamanan dan bergantung pada perilaku yang tidak didefinisikan dengan baik, tidak peduli kompilator. Kita berbicara tentang pra-standar C di sini.
sumber
Ada risiko keamanan di mana pengembang jahat dapat menyelinap melalui pintu belakang melalui bug kompiler. Bergantung pada jumlah bug yang diketahui dalam kompiler yang digunakan, pintu belakang mungkin terlihat kurang menarik (dalam hal apa pun, intinya adalah bahwa kode tersebut benar, bahkan jika berbelit-belit, di tingkat sumber. Kode sumber mengulas dan menguji menggunakan kompiler non-kereta tidak akan menemukan backdoor, karena backdoor tidak ada dalam kondisi ini). Untuk poin penyangkalan tambahan, pengembang jahat juga dapat mencari bug kompiler yang sebelumnya tidak dikenal. Sekali lagi, kualitas kamuflase akan tergantung pada pilihan bug penyusun yang ditemukan.
Serangan ini diilustrasikan pada program sudo dalam artikel ini . bcrypt menulis tindak lanjut yang bagus untuk Javascript minifiers .
Terlepas dari keprihatinan ini, evolusi C compiler telah mengeksploitasi perilaku undefined lebih dan lebih dan lebih agresif, sehingga kode C lama yang ditulis dengan itikad baik akan benar-benar lebih secure dikompilasi dengan kompiler C dari waktu, atau disusun di -O0 (tetapi beberapa optimisasi eksploitasi UB pemecah-program baru diperkenalkan dalam versi baru kompiler bahkan pada -O0 ).
sumber
Kompiler lama mungkin tidak memiliki perlindungan terhadap serangan peretasan yang diketahui. Perlindungan menabrak tumpukan, misalnya, tidak diperkenalkan sampai GCC 4.1 . Jadi ya, kode yang dikompilasi dengan kompiler lama mungkin rentan dengan cara yang melindungi kompiler baru.
sumber
Aspek lain yang perlu dikhawatirkan adalah pengembangan kode baru .
Kompiler yang lebih lama mungkin memiliki perilaku yang berbeda untuk beberapa fitur bahasa daripada yang dibakukan dan diharapkan oleh programmer. Ketidakcocokan ini dapat memperlambat pengembangan dan memperkenalkan bug halus yang dapat dieksploitasi.
Kompiler lama menawarkan lebih sedikit fitur (termasuk fitur bahasa!) Dan tidak mengoptimalkan juga. Pemrogram akan meretas kekurangan ini - misalnya dengan mengimplementasikan kembali fitur yang hilang, atau menulis kode pintar yang tidak jelas tetapi berjalan lebih cepat - menciptakan peluang baru untuk pembuatan bug yang halus.
sumber
Nggak
Alasannya sederhana, kompiler lama mungkin memiliki bug dan exploit lama, tetapi kompiler baru akan memiliki bug dan exploit baru.
Anda tidak "memperbaiki" bug apa pun dengan memutakhirkan ke kompiler baru. Peralihan bug lama dan eksploitasi untuk bug dan exploit baru.
sumber
Yah ada kemungkinan yang lebih tinggi bahwa setiap bug dalam kompiler lama dikenal dan didokumentasikan sebagai lawan menggunakan kompiler baru sehingga tindakan dapat diambil untuk menghindari bug tersebut dengan pengkodean di sekitar mereka. Jadi dengan cara yang tidak cukup sebagai argumen untuk peningkatan. Kami memiliki diskusi yang sama di mana saya bekerja, kami menggunakan GCC 4.6.1 pada basis kode untuk perangkat lunak tertanam dan ada keengganan besar (di antara manajemen) untuk memutakhirkan ke kompiler terbaru karena takut akan bug baru yang tidak berdokumen.
sumber
Pertanyaan Anda terbagi dalam dua bagian:
Mungkin Anda bisa menjawab keduanya dengan menemukan kelemahan yang dapat dieksploitasi di basis kode yang ada dan menunjukkan bahwa kompiler yang lebih baru akan mendeteksinya. Tentu saja manajemen Anda mungkin mengatakan "Anda menemukan itu dengan kompiler lama", tetapi Anda dapat menunjukkan bahwa itu membutuhkan usaha yang cukup besar. Atau Anda menjalankannya melalui kompiler baru untuk menemukan kerentanan, kemudian mengeksploitasinya, jika Anda dapat / diizinkan untuk mengkompilasi kode dengan kompiler baru. Anda mungkin memerlukan bantuan dari peretas yang ramah, tetapi itu tergantung pada kepercayaan mereka dan kemampuan / diizinkan untuk menunjukkan kode (dan menggunakan kompiler baru).
Tetapi jika sistem Anda tidak terkena peretas, Anda mungkin harus lebih tertarik pada apakah peningkatan kompiler akan meningkatkan efektivitas Anda: Analisis Kode MSVS 2013 cukup sering menemukan bug potensial lebih cepat daripada MSVS 2010, dan itu kurang lebih mendukung C99 / C11 - tidak yakin apakah itu secara resmi, tetapi deklarasi dapat mengikuti pernyataan dan Anda dapat mendeklarasikan variabel di
for
-loops.sumber