Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OOM on Import Vault when encrypted vault file is large #1298

Open
chamilad opened this issue Mar 11, 2024 · 5 comments
Open

OOM on Import Vault when encrypted vault file is large #1298

chamilad opened this issue Mar 11, 2024 · 5 comments
Labels
bug A bug report

Comments

@chamilad
Copy link

chamilad commented Mar 11, 2024

Version

v2.2.2

Source

F-Droid

Vault encryption

Yes

Device

OnePlus6

Android version

11

ROM

OxygenOS (stock OnePlus6) v 11.1.2.2

Steps to reproduce

  1. Enable encrypted backups (with or without biometrics)
  2. Build the number of tokens until the backup file exceeds a certain size (for me, a size of 36.96MB of the encrypted backup seems to trigger this behavior)
  3. Mine crashed when adding a new token (17th) and the app started to crash on startup. So I reinstalled the app and reimported the last backup
  4. Import Vault fails with the following OOM stack trace
03-12 08:45:23.633 22889 22889 D AndroidRuntime: Shutting down VM
--------- beginning of crash
03-12 08:45:23.634 22889 22889 E AndroidRuntime: FATAL EXCEPTION: main
03-12 08:45:23.634 22889 22889 E AndroidRuntime: Process: com.beemdevelopment.aegis, PID: 22889
03-12 08:45:23.634 22889 22889 E AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 27294192 byte allocation with 16558384 free bytes and 15MB until OOM, target footprint 268435456, growth limit 268435456
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.org.conscrypt.OpenSSLAeadCipher.reset(OpenSSLAeadCipher.java:140)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.org.conscrypt.OpenSSLAeadCipher.doFinalInternal(OpenSSLAeadCipher.java:377)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:374)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at javax.crypto.Cipher.doFinal(Cipher.java:2055)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at kotlin.LazyKt__LazyKt.decrypt(SourceFile:18)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.vault.VaultFileCredentials.decrypt(SourceFile:19)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.vault.VaultFile.getContent(SourceFile:15)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.vault.VaultManager.loadFrom(SourceFile:71)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.ui.AuthActivity.access$200(SourceFile:14)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.bumptech.glide.GlideBuilder$1.onTaskFinished(SourceFile:73)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.ui.tasks.PBKDFTask.onPostExecute(SourceFile:28)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.AsyncTask.finish(AsyncTask.java:771)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.AsyncTask.access$900(AsyncTask.java:199)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:233)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8068)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)

Following the contribution guide and a few comments on the past issues, I did the following to fix this.

  1. Opened the APK with apktool and added android:largeHeap="true" to AndroidManifest.xml.
  2. Repackaged the APK, signed, and sideloaded with adb
  3. Import Vault now goes through without a crash

This solves my problem for the moment, but my issue is keeping up with the updates and general security. Is there anyway this could be addressed by the released packages? I'm guessing this happens because db entry becomes too large during decryption/encryption. Maybe (somehow) encrypt entries separately (or group up to a certain number)? That could limit the memory occupied by an encrypt/decrypt operation.

I'm unfamiliar with Android development, but can't largeHeap attribute be enabled by default somehow? Guessing that would just prolong the time it takes for this to reproduce again.

Let me know if you need me to generate more detailed logs. I didn't include the entire file because I collected system logs too.

What do you expect to happen?

Import the tokens without crashing

What happens instead?

Application crashes

Log

03-12 08:45:23.633 22889 22889 D AndroidRuntime: Shutting down VM
--------- beginning of crash
03-12 08:45:23.634 22889 22889 E AndroidRuntime: FATAL EXCEPTION: main
03-12 08:45:23.634 22889 22889 E AndroidRuntime: Process: com.beemdevelopment.aegis, PID: 22889
03-12 08:45:23.634 22889 22889 E AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 27294192 byte allocation with 16558384 free bytes and 15MB until OOM, target footprint 268435456, growth limit 268435456
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.org.conscrypt.OpenSSLAeadCipher.reset(OpenSSLAeadCipher.java:140)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.org.conscrypt.OpenSSLAeadCipher.doFinalInternal(OpenSSLAeadCipher.java:377)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:374)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at javax.crypto.Cipher.doFinal(Cipher.java:2055)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at kotlin.LazyKt__LazyKt.decrypt(SourceFile:18)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.vault.VaultFileCredentials.decrypt(SourceFile:19)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.vault.VaultFile.getContent(SourceFile:15)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.vault.VaultManager.loadFrom(SourceFile:71)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.ui.AuthActivity.access$200(SourceFile:14)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.bumptech.glide.GlideBuilder$1.onTaskFinished(SourceFile:73)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.beemdevelopment.aegis.ui.tasks.PBKDFTask.onPostExecute(SourceFile:28)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.AsyncTask.finish(AsyncTask.java:771)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.AsyncTask.access$900(AsyncTask.java:199)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:233)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8068)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
03-12 08:45:23.634 22889 22889 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
@chamilad chamilad added the bug A bug report label Mar 11, 2024
@alexbakker
Copy link
Member

This is a known issue that really only occurs if you selected high resolution JPG or PNG images as icons for your entries. Is that the case here as well? We don't currently scale down selected icons, so they retain their original resolution and thus the size of the vault file quickly increases if you have a couple of those. We probably should scale them down to something like 512x512.

Either way, I'd suggest using SVG icons instead. My vault contains ~80 entries, most of which have SVG icons, and is under 250KB in size. Take a look at the available icons packs: https://github.com/beemdevelopment/Aegis?tab=readme-ov-file#icon-packs

@elliotwutingfeng
Copy link

We probably should scale them down to something like 512x512

I think it is a good idea to notify the user when this happens for high resolution icons. Scaling down would also prevent users from accidentally soft-locking themselves out of the app, should they choose not to use SVG icons.

@chamilad
Copy link
Author

🤦 I can't believe I didn't think of that. The images are exactly the cause. I've added a couple of images that I took with my phone camera, so that should add a couple of tens of MBs.

Thanks! I'm keeping the issue open if the developers decide to address with a workaround. Please close if that's not the case.

@chamilad
Copy link
Author

I could also try adding the feature to crop and scale down images. I'm not familiar with Android development, and it's a bad time in terms of work, but with some time and effort I could get a PR up. Will pick this up if no one else has started.

@echuber2
Copy link

I'm not sure, but it looks like the data is loaded from the image file here:

iconBytes = IOUtils.readFile(inStream);

And there may also be some reason to put checks in the serialization code:

obj.put("icon", icon == null ? JSONObject.NULL : Base64.encode(icon.getBytes()));

This article may be relevant: https://developer.android.com/topic/performance/graphics/load-bitmap.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug report
Projects
None yet
Development

No branches or pull requests

4 participants