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,11 +112,12 @@ class LogViewerActivity : AppCompatActivity() {
}
binding.shareFab.setOnClickListener {
lifecycleScope.launch {
revokeLastUri()
val key = KeyPair().privateKey.toHex()
LOGS[key] = rawLogBytes()
lastUri = Uri.parse("content://${BuildConfig.APPLICATION_ID}.exported-log/$key")
val shareIntent = ShareCompat.IntentBuilder(this)
val shareIntent = ShareCompat.IntentBuilder(this@LogViewerActivity)
.setType("text/plain")
.setSubject(getString(R.string.log_export_subject))
.setStream(lastUri)
@ -127,6 +128,7 @@ class LogViewerActivity : AppCompatActivity() {
revokeLastActivityResultLauncher.launch(shareIntent)
}
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.log_viewer, menu)
@ -151,12 +153,14 @@ class LogViewerActivity : AppCompatActivity() {
private val downloadsFileSaver = DownloadsFileSaver(this)
private fun rawLogBytes() : ByteArray {
private suspend fun rawLogBytes() : ByteArray {
val builder = StringBuilder()
withContext(Dispatchers.IO) {
for (i in 0 until rawLogLines.size()) {
builder.append(rawLogLines[i])
builder.append('\n')
}
}
return builder.toString().toByteArray(Charsets.UTF_8)
}