Dalam artikel ini, kami akan menunjukkan cara keadaan perlumbaan mempengaruhi sistem kebenaran masa jalan Android.
Jika anda seorang pembangun, anda mungkin pernah mendengar tentang keadaan perlumbaan. Mereka sering dikaitkan dengan operasi latar belakang serentak yang dilakukan dalam pecahan saat. Walau bagaimanapun, keadaan perlumbaan tertentu juga mungkin muncul dalam UI dan bertahan untuk masa yang tidak terhingga. Dalam artikel ini, kami akan menunjukkan cara keadaan perlumbaan mempengaruhi sistem kebenaran masa jalan Android.
Pertama sekali, kita perlu menerangkan beberapa istilah asas.
Keadaan perlumbaan berlaku jika berbilang operasi berlaku pada masa yang sama dan susunannya menjejaskan keputusan. Contoh buku teks ialah dua utas yang menambah pembolehubah yang sama. Nampaknya ia remeh, namun, biasanya, kita perlu menggunakan elemen khas yang selamat dari benang untuk melaksanakannya dengan betul.
Masa semakan ke masa penggunaan (TOCTTOU atau TOCTOU, disebut TOCK juga) ialah sejenis keadaan perlumbaan tertentu di mana operasi yang dijalankan didahului dengan semakan keadaan dan keadaan itu diubah suai dalam masa antara semakan dan pelaksanaan sebenar. Ia sering digambarkan dengan menyemak keistimewaan pengguna pada masa log masuk sahaja. Contohnya, jika anda seorang pentadbir pada masa anda log masuk dan anda boleh menggunakan keistimewaan anda sehingga anda log keluar, walaupun akses pentadbir anda dibatalkan dalam masa yang sama.
Mari kita ringkaskan juga asas kebenaran masa jalan Android.
Bermula dari Android 6.0 (API tahap 23) kebenaran yang paling berbahaya perlu diberikan secara eksplisit oleh pengguna pada masa jalan dan bukannya sekaligus pada masa pemasangan apl. Elemen yang paling ketara di sini ialah dialog sistem dengan butang TOLAK dan BENAR seperti yang ditunjukkan dalam rajah 1.
Rajah 1. Dialog kebenaran masa jalan
Selepas mengklik butang TOLAK, kami menerima PERMISSION_DENIED dalam panggilan balik onRequestPermissionsResult dan kami harus melumpuhkan fungsi yang bergantung pada kebenaran ini. Mengikut coretan rasmi.
Selain itu, pengguna juga boleh memberikan atau menafikan kebenaran dengan menggunakan skrin Kebenaran apl dalam tetapan aplikasi. Anda boleh melihat skrin itu dalam rajah 2.
Rajah 2. Skrin kebenaran apl
Kebanyakan daripada anda mungkin berpendapat bahawa penafian kebenaran masa jalan adalah ciri yang sangat mudah dan tiada unsur yang boleh dipecahkan. Nah, tiada apa yang boleh jauh dari kebenaran!
Dialog muncul hanya jika kebenaran tidak diberikan. Jadi kita mempunyai masa semakan sejurus sebelum memaparkan dialog. Dan masa penggunaan apabila butang DENY diklik. Tempoh di antara mereka boleh bertahan selama-lamanya - pengguna boleh membuka dialog kemudian tekan butang utama atau terbaharu untuk mengalihkan tugas dengan apl ke latar belakang dan kembali bila-bila masa kemudian.
Mari periksa sama ada dialog kebenaran masa jalan terdedah kepada TOCTTOU. Untuk berbuat demikian, kita boleh mencipta aktiviti yang sangat mudah yang menyemak kebenaran yang diberikan selepas kembali daripada dialog. Ambil perhatian bahawa selain daripada semakan argumen onRequestPermissionsResult standard, kami akan memanggil Context#checkSelfPermission() untuk mendapatkan status pemberian kebenaran semasa. Jangan lupa untuk menetapkan targetSdkVersion kepada 23 atau lebih tinggi. Kod sepatutnya kelihatan seperti ini:
class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) requestPermissions(arrayOf(WRITE_EXTERNAL_STORAGE), 1) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) val checkResultTextView = findViewById<TextView>(R.id.grantResultTextView) val grantResultTextView = findViewById<TextView>(R.id.checkResultTextView) val checkPermissionResult = checkSelfPermission(WRITE_EXTERNAL_STORAGE).toPermissionResult() val grantPermissionResult = grantResults.firstOrNull()?.toPermissionResult() checkResultTextView.text = "checkSelfPermission: $checkPermissionResult" grantResultTextView.text = "onRequestPermissionsResult: $grantPermissionResult" } private fun Int.toPermissionResult() = when (this) { PERMISSION_GRANTED -> "granted" PERMISSION_DENIED -> "denied" else -> "unknown" } }
Kini kita boleh melakukan ujian. Untuk melakukannya, kami memerlukan peranti atau AVD dengan Android 6.0 (API 23) atau lebih baharu. Keputusan ujian ditunjukkan pada rajah 3.
Rajah 3. TOCTTOU yang ditangkap
Kita dapat lihat bahawa keputusan berbeza. onRequestPermissionsResult argumen tidak sah. Jadi butang DENY tidak menafikan apa-apa! Ia hanya melakukan apa-apa dengan status kebenaran tetapi mengembalikan hasil yang ditolak kepada apl.
Adalah penting untuk mengambil kira masa semasa menyemak pelbagai perkara dalam kod. Keputusan semakan caching boleh menyebabkan pepijat dan kesan pelik. Kerentanan TOCTTOU tidak bergantung pada platform atau bahasa pengaturcaraan jadi ia telah diklasifikasikan sebagai CWE-367.
Anda boleh menyemak kod sumber penuh di GitHub.
Projek ini juga mengandungi ujian UI automatik yang menunjukkan isu tersebut.
Pada asalnya diterbitkan di www.thedroidsonroids.com pada 14 Disember 2017.
Atas ialah kandungan terperinci Kes Tepi yang Perlu Diingati. Sambilan Semakan ke Masa Penggunaan Syarat Perlumbaan dalam Android UI. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!