ui: collect logs from IO thread only

Otherwise the pop() from the producer might causes an OOB read in the
consumer:

Exception java.lang.ArrayIndexOutOfBoundsException:
  at androidx.collection.CircularArray.get (CircularArray.java)
  at com.wireguard.android.activity.LogViewerActivity.rawLogBytes (LogViewerActivity.java)
  at com.wireguard.android.activity.LogViewerActivity.onCreate$lambda$3 (LogViewerActivity.java:133)
  at android.view.View.performClick (View.java:6935)
  at android.view.View$PerformClick.run (View.java:26214)
  at android.os.Handler.handleCallback (Handler.java:790)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:7000)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:441)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1408)

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2023-05-05 02:56:51 +02:00
parent 7778ff63b5
commit a3bfa6f1ab

View File

@ -112,19 +112,21 @@ class LogViewerActivity : AppCompatActivity() {
} }
binding.shareFab.setOnClickListener { binding.shareFab.setOnClickListener {
revokeLastUri() lifecycleScope.launch {
val key = KeyPair().privateKey.toHex() revokeLastUri()
LOGS[key] = rawLogBytes() val key = KeyPair().privateKey.toHex()
lastUri = Uri.parse("content://${BuildConfig.APPLICATION_ID}.exported-log/$key") LOGS[key] = rawLogBytes()
val shareIntent = ShareCompat.IntentBuilder(this) lastUri = Uri.parse("content://${BuildConfig.APPLICATION_ID}.exported-log/$key")
val shareIntent = ShareCompat.IntentBuilder(this@LogViewerActivity)
.setType("text/plain") .setType("text/plain")
.setSubject(getString(R.string.log_export_subject)) .setSubject(getString(R.string.log_export_subject))
.setStream(lastUri) .setStream(lastUri)
.setChooserTitle(R.string.log_export_title) .setChooserTitle(R.string.log_export_title)
.createChooserIntent() .createChooserIntent()
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
grantUriPermission("android", lastUri, Intent.FLAG_GRANT_READ_URI_PERMISSION) grantUriPermission("android", lastUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
revokeLastActivityResultLauncher.launch(shareIntent) revokeLastActivityResultLauncher.launch(shareIntent)
}
} }
} }
@ -151,11 +153,13 @@ class LogViewerActivity : AppCompatActivity() {
private val downloadsFileSaver = DownloadsFileSaver(this) private val downloadsFileSaver = DownloadsFileSaver(this)
private fun rawLogBytes() : ByteArray { private suspend fun rawLogBytes() : ByteArray {
val builder = StringBuilder() val builder = StringBuilder()
for (i in 0 until rawLogLines.size()) { withContext(Dispatchers.IO) {
builder.append(rawLogLines[i]) for (i in 0 until rawLogLines.size()) {
builder.append('\n') builder.append(rawLogLines[i])
builder.append('\n')
}
} }
return builder.toString().toByteArray(Charsets.UTF_8) return builder.toString().toByteArray(Charsets.UTF_8)
} }