Skip to content

Commit a3bfa6f

Browse files
committed
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 <[email protected]>
1 parent 7778ff6 commit a3bfa6f

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

ui/src/main/java/com/wireguard/android/activity/LogViewerActivity.kt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,21 @@ class LogViewerActivity : AppCompatActivity() {
112112
}
113113

114114
binding.shareFab.setOnClickListener {
115-
revokeLastUri()
116-
val key = KeyPair().privateKey.toHex()
117-
LOGS[key] = rawLogBytes()
118-
lastUri = Uri.parse("content://${BuildConfig.APPLICATION_ID}.exported-log/$key")
119-
val shareIntent = ShareCompat.IntentBuilder(this)
115+
lifecycleScope.launch {
116+
revokeLastUri()
117+
val key = KeyPair().privateKey.toHex()
118+
LOGS[key] = rawLogBytes()
119+
lastUri = Uri.parse("content://${BuildConfig.APPLICATION_ID}.exported-log/$key")
120+
val shareIntent = ShareCompat.IntentBuilder(this@LogViewerActivity)
120121
.setType("text/plain")
121122
.setSubject(getString(R.string.log_export_subject))
122123
.setStream(lastUri)
123124
.setChooserTitle(R.string.log_export_title)
124125
.createChooserIntent()
125126
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
126-
grantUriPermission("android", lastUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
127-
revokeLastActivityResultLauncher.launch(shareIntent)
127+
grantUriPermission("android", lastUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
128+
revokeLastActivityResultLauncher.launch(shareIntent)
129+
}
128130
}
129131
}
130132

@@ -151,11 +153,13 @@ class LogViewerActivity : AppCompatActivity() {
151153

152154
private val downloadsFileSaver = DownloadsFileSaver(this)
153155

154-
private fun rawLogBytes() : ByteArray {
156+
private suspend fun rawLogBytes() : ByteArray {
155157
val builder = StringBuilder()
156-
for (i in 0 until rawLogLines.size()) {
157-
builder.append(rawLogLines[i])
158-
builder.append('\n')
158+
withContext(Dispatchers.IO) {
159+
for (i in 0 until rawLogLines.size()) {
160+
builder.append(rawLogLines[i])
161+
builder.append('\n')
162+
}
159163
}
160164
return builder.toString().toByteArray(Charsets.UTF_8)
161165
}

0 commit comments

Comments
 (0)