Repository navigation
Android 15: ContentResolver.query returns null from hooked app to external ContentProvider #253
Description
Steps to reproduce/复现步骤
LSPosed framework installed and active.
Install the AllTrans Xposed module APK (akhil.alltrans).
Install a target application, for example, eu.toldi.infinityforlemmy.
Have adb available for logcat.
Configuration:
Open LSPosed Manager.
Go to "Modules" and ensure the "AllTrans" module is enabled globally (toggle switch is ON).
Tap on the "AllTrans" module entry to configure its scope.
Find and check the box next to the target application (eu.toldi.infinityforlemmy) to enable the module for this app's scope.
Reboot the device to ensure the module scope changes take effect.
(Optional but recommended): Open the AllTrans application itself and configure global settings (e.g., enable translation, set languages). This isn't strictly necessary to see the query fail, but confirms general setup.
(Verification): Confirm that the AllTrans ContentProvider (akhil.alltrans.sharedPrefProvider) is functional by running adb shell content query --uri content://akhil.alltrans.sharedPrefProvider/some.test.package. This command should successfully return at least one row with the global preferences JSON.
Trigger the Issue:
Start adb logcat (you can filter for the target app's process or the "AllTrans" tag, e.g., adb logcat | findstr eu.toldi.infinityforlemmy or adb logcat -s AllTrans).
Launch the target application (eu.toldi.infinityforlemmy).
Observe the Failure:
Monitor the logcat output corresponding to the eu.toldi.infinityforlemmy process.
Look for the specific log lines generated by the AllTrans module during the app's initialization.
Expected behaviour/预期行为
The logcat for the target app should show lines indicating successful initialization, similar to:
I/AllTrans: readPrefAndHook: Executing contentResolver.query...
I/AllTrans: readPrefAndHook: contentResolver.query finished.
I/AllTrans: readPrefAndHook: Query successful, cursor received. Row count: X. Attempting to read data...
I/AllTrans: readPrefAndHook: Preferences parsed. Enabled=true, LocalEnabled=true, ...
I/AllTrans: readPrefAndHook: AllTrans is ENABLED for Package eu.toldi.infinityforlemmy...
I/AllTrans: registerTranslationHooks: Attempting to register hooks...
I/AllTrans: registerWebViewHooks: Registering WebView hooks...
Translation features within the target app should start working.
Actual behaviour/实际行为
The logcat for the target app shows the following critical failure line:
I/AllTrans: !!! readPrefAndHook: Cursor is NULL after query for URI: content://akhil.alltrans.sharedPrefProvider/eu.toldi.infinityforlemmy. Cannot read preferences. Check Provider status, Permissions (SELinux), Visibility. !!!
The contentResolver.query call returns null without throwing any Java exception in the hooked app's process.
Consequently, the AllTrans module fails to initialize completely within the target app, and no translation occurs.
This failure happens despite the ContentProvider working correctly when queried directly via adb shell content query. The issue is specific to the IPC call originating from the LSPosed-hooked application process.
Xposed Module List/Xposed 模块列表
alltransRoot implementation/Root 方案
magisk28103
System Module List/系统模块列表
systemless hosts
zygiskNextLSPosed version/LSPosed 版本
1.10.1 718
Android version/Android 版本
15
Version requirement/版本要求
- I am using the latest debug build from GitHub Actions./我正在使用 GitHub Actions 中最新的调试版本。
Activity
pbzin commentedon Apr 19, 2025
use my most updated version of the apk
https://mega.nz/file/AD1iTZgZ#wcaOS_P1jxqTguTInxY88mQYFd2smCOHxPxzbwLM8Js
or the latest one present here I think it still works
https://github.com/akhilkedia/AllTrans/releases
JingMatrix commentedon Apr 19, 2025
It is a module problem, mostly due to null
Gobal context.pbzin commentedon Apr 19, 2025
I've added more detailed logging to my module (AllTrans) right before the ContentResolver.query call is made from within the hooked application (eu.toldi.infinityforlemmy).
The new logs confirm that the module's static Context object (alltrans.context) is NOT null when the query is attempted. You can see this here:
2025-04-19 19:22:53.526 ... I/AllTrans: readPrefAndHook: Pre-Query Check for eu.toldi.infinityforlemmy:
2025-04-19 19:22:53.526 ... I/AllTrans: -> Global alltrans.context instance: 111240373 (Package: eu.toldi.infinityforlemmy)
2025-04-19 19:22:53.526 ... I/AllTrans: -> ContentResolver instance from applicationContext: 14356937
2025-04-19 19:22:53.527 ... I/AllTrans: readPrefAndHook: Executing contentResolver.query...
2025-04-19 19:22:53.527 ... I/AllTrans: readPrefAndHook: contentResolver.query finished.
2025-04-19 19:22:53.527 ... I/AllTrans: !!! readPrefAndHook: Cursor is NULL after query for URI: content://akhil.alltrans.sharedPrefProvider/eu.toldi.infinityforlemmy. Trying fallback methods...
Despite the context being valid, the query() call still returns null without any Java exception being thrown in the hooked app.
However, the crucial finding is this: when I temporarily set SELinux to Permissive mode (setenforce 0), the ContentResolver.query() call from the hooked app WORKED correctly and returned a valid Cursor. Returning to Enforcing mode (setenforce 1) causes the query to return null again.
This strongly points to an SELinux policy blocking the specific IPC (Binder) communication between the hooked app process and the module's ContentProvider process in Enforcing mode on Android 15. (While I couldn't pinpoint a specific avc: denied log for this exact interaction, the Permissive/Enforcing difference is clear evidence).
Could you perhaps look into potential interactions between LSPosed's IPC/Binder handling and SELinux policies on Android 15 that might be causing this specific type of ContentProvider query from a hooked app to be blocked?
pbzin commentedon Apr 19, 2025
My latest logs confirm the Context object is definitely NOT null right before the query attempt.
The critical new finding is: the query() works perfectly when SELinux is set to Permissive mode (setenforce 0). It only returns null when SELinux is Enforcing.
While in Permissive mode, I captured these specific avc: denied logs happening exactly when the hooked app tries the query:
avc: denied { find } for pid=[PID_HOOKED_APP] ... scontext=u:r:untrusted_app:s0... tcontext=u:r:system_server:s0 tclass=service_manager ... app=[HOOKED_APP_PKG_NAME]
avc: denied { call } for pid=[PID_HOOKED_APP] ... scontext=u:r:untrusted_app:s0... tcontext=u:r:system_server:s0 tclass=binder ... app=[HOOKED_APP_PKG_NAME]
This strongly indicates the issue is SELinux blocking the required IPC (binder call / service_manager find) from the hooked app context in Enforcing mode.
Could you please reconsider the issue in light of this SELinux evidence? It seems related to LSPosed's interaction with SELinux/IPC rules on Android 15.
Thanks!
JingMatrix commentedon Apr 20, 2025
Please provide the full
avcdeny messages.Also if possible, please compare the results for different target apps. It seems that this query failure only happens for apps with null global context.
pbzin commentedon Apr 20, 2025
2025-04-20 15:51:17.462 7189-7189 FinalizerDaemon usap64 W type=1400 audit(0.0:15128): avc: denied { getopt } for path="/dev/socket/usap_pool_primary" scontext=u:r:untrusted_app:s0:c73,c258,c512,c768 tcontext=u:r:zygote:s0 tclass=unix_stream_socket permissive=0 app=eu.toldi.infinityforlemmy
2025-04-20 15:35:47.166 8573-8573 FinalizerDaemon usap64 W type=1400 audit(0.0:15151): avc: denied { getopt } for path="/dev/socket/usap_pool_primary" scontext=u:r:untrusted_app:s0:c81,c258,c512,c768 tcontext=u:r:zygote:s0 tclass=unix_stream_socket permissive=0 app=com.simon.harmonichackernews
I compared two different apps, and it's worth saying that they both work with lspatch
JingMatrix commentedon Jul 15, 2025
I think this is more a problem for module developer instead of LSPosed.
You may need to find a way to avoid this SELinux violation.
It is not proper for LSPosed to add these rules apprently useful for your module.
Now I transfer this issue into Discussions, as it could be possible to find a solution for your module desiging via the community.