Merge pull request #630 from vector-im/feature/crypto_lock

Fix dead lock on crypto
This commit is contained in:
Benoit Marty 2019-10-22 16:53:33 +02:00 committed by GitHub
commit 7890e83204
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 36 additions and 45 deletions

View File

@ -134,7 +134,7 @@ data class Event(
}
fun toContentStringWithIndent(): String {
val contentMap = toContent()?.toMutableMap() ?: HashMap()
val contentMap = toContent().toMutableMap()
return JSONObject(contentMap).toString(4)
}

View File

@ -21,7 +21,6 @@ package im.vector.matrix.android.internal.crypto
import android.content.Context
import android.os.Handler
import android.os.Looper
import arrow.core.Try
import com.squareup.moshi.Types
import com.zhuinden.monarchy.Monarchy
import dagger.Lazy

View File

@ -38,9 +38,9 @@ internal class EnsureOlmSessionsForUsersAction @Inject constructor(private val o
devices.filter {
// Don't bother setting up session to ourself
it.identityKey() != olmDevice.deviceCurve25519Key &&
it.identityKey() != olmDevice.deviceCurve25519Key
// Don't bother setting up sessions with blocked users
!it.isVerified
&& !it.isVerified
}
}
return ensureOlmSessionsForDevicesAction.handle(devicesByUser)

View File

@ -244,13 +244,6 @@ internal class MXMegolmDecryption(private val userId: String,
keysClaimed = event.getKeysClaimed().toMutableMap()
}
if (roomKeyContent.sessionId == null
|| roomKeyContent.sessionKey == null
|| roomKeyContent.roomId == null) {
Timber.e("## invalid roomKeyContent")
return
}
val added = olmDevice.addInboundGroupSession(roomKeyContent.sessionId,
roomKeyContent.sessionKey,
roomKeyContent.roomId,

View File

@ -66,7 +66,7 @@ internal class MXOlmEncryption(
)
messageEncrypter.encryptMessage(messageMap, deviceInfos)
return messageMap.toContent()!!
return messageMap.toContent()
}
/**

View File

@ -21,7 +21,6 @@ import android.os.Looper
import androidx.annotation.UiThread
import androidx.annotation.VisibleForTesting
import androidx.annotation.WorkerThread
import arrow.core.Try
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.failure.Failure
@ -70,9 +69,6 @@ import org.matrix.olm.OlmPkMessage
import timber.log.Timber
import java.security.InvalidParameterException
import javax.inject.Inject
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
import kotlin.random.Random
/**

View File

@ -38,23 +38,24 @@ internal class TimelineEventDecryptor(
private val newSessionListener = object : NewSessionListener {
override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) {
synchronized(unknownSessionsFailure) {
val toDecryptAgain = ArrayList<String>()
val eventIds = unknownSessionsFailure[sessionId]
if (eventIds != null) toDecryptAgain.addAll(eventIds)
if (toDecryptAgain.isNotEmpty()) {
eventIds?.clear()
toDecryptAgain.forEach {
requestDecryption(it)
}
}
unknownSessionsFailure[sessionId]
.orEmpty()
.toList()
.also {
unknownSessionsFailure[sessionId]?.clear()
}
}.forEach {
requestDecryption(it)
}
}
}
private var executor: ExecutorService? = null
private val existingRequests = HashSet<String>()
private val unknownSessionsFailure = HashMap<String, MutableList<String>>()
// Set of eventIds which are currently decrypting
private val existingRequests = mutableSetOf<String>()
// sessionId -> list of eventIds
private val unknownSessionsFailure = mutableMapOf<String, MutableList<String>>()
fun start() {
executor = Executors.newSingleThreadExecutor()
@ -65,11 +66,23 @@ internal class TimelineEventDecryptor(
cryptoService.removeSessionListener(newSessionListener)
executor?.shutdownNow()
executor = null
unknownSessionsFailure.clear()
existingRequests.clear()
synchronized(unknownSessionsFailure) {
unknownSessionsFailure.clear()
}
synchronized(existingRequests) {
existingRequests.clear()
}
}
fun requestDecryption(eventId: String) {
synchronized(unknownSessionsFailure) {
for (eventIds in unknownSessionsFailure.values) {
if (eventId in eventIds) {
Timber.d("Skip Decryption request for event $eventId, unknown session")
return
}
}
}
synchronized(existingRequests) {
if (eventId in existingRequests) {
Timber.d("Skip Decryption request for event $eventId, already requested")
@ -77,14 +90,6 @@ internal class TimelineEventDecryptor(
}
existingRequests.add(eventId)
}
synchronized(unknownSessionsFailure) {
for (it in unknownSessionsFailure.values) {
if (eventId in it) {
Timber.d("Skip Decryption request for event $eventId, unknown session")
break
}
}
}
executor?.execute {
Realm.getInstance(realmConfiguration).use { realm ->
processDecryptRequest(eventId, realm)
@ -106,7 +111,7 @@ internal class TimelineEventDecryptor(
eventEntity.setDecryptionResult(result)
}
} catch (e: MXCryptoError) {
Timber.v("Failed to decrypt event $eventId $e")
Timber.v(e, "Failed to decrypt event $eventId")
if (e is MXCryptoError.Base && e.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID) {
// Keep track of unknown sessions to automatically try to decrypt on new session
realm.executeTransaction {

View File

@ -213,10 +213,10 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
}
} else {
if (notifiableEvent is NotifiableMessageEvent) {
if (notifiableEvent.senderName.isEmpty()) {
if (notifiableEvent.senderName.isNullOrEmpty()) {
notifiableEvent.senderName = data["sender_display_name"] ?: data["sender"] ?: ""
}
if (notifiableEvent.roomName.isEmpty()) {
if (notifiableEvent.roomName.isNullOrEmpty()) {
notifiableEvent.roomName = findRoomNameBestEffort(data, session) ?: ""
}
}

View File

@ -126,7 +126,7 @@ fun getFileExtension(fileUri: String): String? {
* Size
* ========================================================================================== */
fun getSizeOfFiles(context: Context, root: File): Int {
fun getSizeOfFiles(root: File): Int {
return root.walkTopDown()
.onEnter {
Timber.v("Get size of ${it.absolutePath}")

View File

@ -185,8 +185,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
// clear medias cache
findPreference<VectorPreference>(VectorPreferences.SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY)!!.let {
val size = getSizeOfFiles(requireContext(),
File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
val size = getSizeOfFiles(File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
it.summary = TextUtils.formatFileSize(requireContext(), size.toLong())
@ -203,8 +202,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
// On BG thread
Glide.get(requireContext()).clearDiskCache()
newSize = getSizeOfFiles(requireContext(),
File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
newSize = getSizeOfFiles(File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
}
it.summary = TextUtils.formatFileSize(requireContext(), newSize.toLong())