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

SoLoader causes crashes on migration to an Android 12 device #100

Closed
millmore-google opened this issue May 9, 2022 · 2 comments
Closed
Assignees

Comments

@millmore-google
Copy link

Background

When Android users get a new device, they use Android Backup & Restore to transfer their data (including app data) to the new device. This can be done from a cloud backup or directly from their old device via a D2D (device-to-device) transfer. Apps which use SoLoader are seeing fatal problems after this process. The incidence of these problems has increased very significantly in Android 12 due to changes which opt apps into the data transfer by default.

Problem

When app data is copied to a new device, the copying of SoLoader library data is not a complete clone. SoLoader stores the downloaded content in a read-only directory, but while the Android transfer process copies the read-only directory, it cannot then populate the contents of that directory (because it is read-only), resulting in the directory existing without the libraries on the new device. On app launch, the presence of library directories (e.g. lib-main, lib-0, etc.) causes SoLoader to crash the app, when trying to access the dso_lock file as follows:

java.lang.RuntimeException: Unable to create application com.xxx: java.lang.RuntimeException: java.io.FileNotFoundException: /data/user/0/com.xxx/lib-0/dso_lock: open failed: EACCES (Permission denied)
...
Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: /data/user/0/com.xxx/lib-0/dso_lock: open failed: EACCES (Permission denied)
        at libcore.io.IoBridge.open(IoBridge.java:575)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
        at com.facebook.soloader.FileLocker.<init>(SourceFile:2)
        at com.facebook.soloader.FileLocker.lock(SourceFile:1)
        at com.facebook.soloader.UnpackingSoSource.prepare(SourceFile:3)
        at com.facebook.soloader.SoLoader.initSoSources(SourceFile:40)
        at com.facebook.soloader.SoLoader.init(SourceFile:5)
        at com.facebook.soloader.SoLoader.init(SourceFile:1)
        at com.facebook.soloader.SoLoader.init(SourceFile:9)

It seems the error is happening in FileLocker.java:

private void init(File lockFile, boolean tryLock) throws IOException {
    // Output stream creation fails as the file is not there and 
    // it can't be created automatically, since the directory is    
    // read-only.
    mLockFileOutputStream = new FileOutputStream(lockFile);
    FileLock lock = null;
    ...
}

This is causing many apps that use SoLoader to crash on launch after transfer to a new device, and the user needs to clear app data for it to work, which is not something obvious to users.

This is due to a bug in Android which has been fixed in Android 12 QPR 3 (in which read-only directories are not copied at all), but in reality many OEMs do not do OTAs for non-security issues, so many Android devices will never receive the bug fix. It is therefore important for SoLoader to account for this scenario if apps which use SoLoader are to work when users move to an Android 12 device.

Steps to reproduce

To reproduce you need two devices running Android 12 using the standard android setup code. Install an app which uses SoLoader on the first device and open the app to load the libraries. Factory reset the second device and on setup choose to copy the content using cable transfer. On the new device open the app after transfer and you should experience the crash.

To simulate the problem more easily on a device with root access you can simply open the app to download the libraries, close it and delete the contents of the lib-* directories and re-open the app.

Action Required

Ensure that SoLoader correctly handles the situation where an empty library directory is present / dso_lock is not found.

@millmore-google
Copy link
Author

This appears to be resolved from version 0.10.2 where SoLoader doesn't seem to generate the libs in the lib-main, lib-0 etc. directories. Not sure if this is intentional?

@simpleton simpleton self-assigned this Jun 22, 2022
@simpleton
Copy link
Member

@millmore-google thanks for the report and detailed issue description, much appreciated! Sry for late reply. I will address this issue asap.

facebook-github-bot pushed a commit to facebook/react-native that referenced this issue Jun 30, 2022
Summary:
**Feature**

Support pre-computing the dependency

**Fixes**

Wrongly loaded directApkLdPath(facebook/SoLoader#104)
SoLoader causes crashes on migration to an Android 12 device(facebook/SoLoader#100, facebook/SoLoader#88 )
Fix race condition in SoLoader#init(facebook/SoLoader#99)

**Full Changelog**: facebook/SoLoader@v0.10.3...v0.10.4

Reviewed By: charles011

Differential Revision: D37525875

fbshipit-source-id: a64e4021012128fe4a78d3ec9e955dae2ae35926
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants