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

Weird problem with most recent CalyxOS OTA (March) - claims attempt to downgrade security patch and abort #51

Closed
oddgirl opened this issue Apr 2, 2024 · 41 comments · Fixed by #52

Comments

@oddgirl
Copy link

oddgirl commented Apr 2, 2024

So long story short I'm updating my CalyxOS on a redfin (Pixel 5)
I grab the OTA from OTA full section of here https://calyxos.org/get/ota/
Full link (stable)
https://release.calyxinstitute.org/redfin-ota_update-24505020.zip

(security-express produces same behavior)

when I try to run OTAtool (recent version) it displays following message

Enter passphrase for "/home/user/avbr/keyman-slave/ota.key":
Verifying OTA signature...
Device name: redfin
Fingerprint: google/redfin/redfin:14/UP1A.231105.001.B2/11260668:user/release-keys
Security patch: 2023-11-05

That's helluva old security patch!

And of course, needless to say, when I attempt to load it up in custota on the phone, it complains of security patch being downgraded and aborts.

What is going on here ?

@oddgirl
Copy link
Author

oddgirl commented Apr 2, 2024

Okay I just re-ran it against OTA that I have previously successfully installed

link to ota https://release.calyxinstitute.org/redfin-ota_update-24503000.zip

and it says

Verifying OTA signature...
Device name: redfin
Fingerprint: google/redfin/redfin:14/UP1A.231105.001/10817346:user/release-keys
Security patch: 2023-11-05

No indication of a "2024-01-05" patchlevel anyplace anywhere (the patchlevel the Custota now, for some terrifying reason, expects)

Custota keeps saying Bad Format Exception - downgrading to older security patch is not allowed

and refusing these updates

I really don't know how I ... screwed up this bad.

Fatal breakage? Do I have any chance of fixing this ?

@oddgirl
Copy link
Author

oddgirl commented Apr 2, 2024

I have managed to extract two old logs (check and install log) from back when it successfully loaded the OTA, as well as current, terrifying failure check log where it complains about (seemingly totally non-existent?!) 2024-01-05 patch level

Attaching them
old-install.log
old-log-where-it-worked.log
terrifying-failure-check.log

@chenxiaolong
Copy link
Owner

Can you post the output of adb shell getprop ro.build.version.security_patch? And any chance you have any Magisk module installed that fake properties?

I took a look at the OTA you linked and I'm seeing 2023-11-05 in both the system/build.prop file as well as the OTA metadata (META-INF/com/android/metadata). I can't find any indication of 2024-01-05--not sure where that's coming from.

(I'm guessing the old date is because Google no longer supports the device and CalyxOS doesn't increment the security patch date when only the OS is updated, but the drivers aren't.)

@chenxiaolong
Copy link
Owner

Oh dammit, I see the problem. Thanks for posting a link to the OTA you're currently running.

CalyxOS is lying about the security patch level. Custota queries for ro.build.version.security_patch, but based on what you're seeing, it looks like CalyxOS actually returns ro.build.version.real_security_patch. I'll take a look tomorrow and see if there's any way to get the proper value (2023-11-05).

[22:27:08] cxl-desktop-1 …/24503000/system
❯ grep patch system/build.prop
ro.build.version.security_patch=2023-11-05
ro.build.version.real_security_patch=2024-01-05

@oddgirl
Copy link
Author

oddgirl commented Apr 2, 2024

ro.build.version.security_patch
is
2023-11-05

I don't have anything that should be faking properties (there's LSposed and Sui, but Lsposed loads one little tweak that has nothing to do with props and was last updated in 2022 and sui is there mostly for appops stuff, so nothing should be "imagining" a patch level.

@oddgirl
Copy link
Author

oddgirl commented Apr 2, 2024

Oh dammit, I see the problem. Thanks for posting a link to the OTA you're currently running.

CalyxOS is lying about the security patch level. Custota queries for ro.build.version.security_patch, but based on what you're seeing, it looks like CalyxOS actually returns ro.build.version.real_security_patch. I'll take a look tomorrow and see if there's any way to get the proper value (2023-11-05).

[22:27:08] cxl-desktop-1 …/24503000/system
❯ grep patch system/build.prop
ro.build.version.security_patch=2023-11-05
ro.build.version.real_security_patch=2024-01-05

Thank you very much.
Also, really angery at Calyx here lol

@nad0vs
Copy link

nad0vs commented Apr 2, 2024

Oh, so THAT is why my update process for my Calyx rooted phones is broken

@chenxiaolong
Copy link
Owner

Yep, they're indeed ignoring ro.build.version.security_patch when reading Build.VERSION.SECURITY_PATCH: https://github.com/CalyxOS/platform_frameworks_base/blob/bcee2772abf7b58067ac6a12557043479407ae1b/core/java/android/os/Build.java#L365-L366

Please give #52 a try. Test build: Custota-4.0.r7.gc43e3a6-release.zip

@oddgirl
Copy link
Author

oddgirl commented Apr 4, 2024

Thanks! Will try to run it as soon as I get back to my build box.

BTW, I reckon I should manually disable/uninstall "normal" custota before trying this test build?

Also, any risk of explosions (how worried should I be about first siphoning off 20 GB+ data off my phone ;-) ?

@chenxiaolong
Copy link
Owner

chenxiaolong commented Apr 4, 2024

Nope, you should be able to just directly flash it. It will replace the release build you have installed. My test builds are signed with the same keys as the release builds.

There shouldn't be any risk of explosions. If there is, it'd be update_engine's fault 😄

In all seriousness, it's really hard for any Custota to cause any damage. Even if Custota incorrectly allows an invalid OTA to be flashed, update_engine would very likely reject it. Also, I do a test OTA update on my own device for every commit to ensure that things work fine.

@oddgirl
Copy link
Author

oddgirl commented Apr 5, 2024

Hi @chenxiaolong I have some good news and some bad news.
The good news - the phone updated and is now running, all my data seems intact and so far I don't see any terrible dire consequences beyond what goes into the bad news section.

Now for the bad news:

something about the update has initially sort of soft-locked the phone (permanent "phone is starting" screen) which I resolved by booting into safe mode (which disables most things but preserves root and ADB debug and I was so wise and clever as to set adb debug on before update yay me) and wipe all magisk modules.

That allowed to boot into normal mode, complete the update configuration (it still initially jumped to "phone starting" screen but this time it had a working progress bar and went away in like two seconds) and proceed with fiddling

What works - call recorder's magisk module and the Sui Zygisk module for the fat app-ops manager I'm using

What died

  1. LSPosed-Zygisk is now hard-ruined (not sure if it something about the update or the weird hickup in the update process, but it now just crashes all the time, trying different versions, re-installing, nothing works at all. Total LSPosed death syndrome.
    The problem at least superficially seems identical to a known "shell keeps stopping" problem LSPosed occasionally manifests and appears to have multiple causes, multiple hacky solutions that don't work very well between android versions.
    Given that now LSPosed is thoroughly abandoned by devs I think it's end of the road for my favorite Xposed tricks

  2. this is most relevant to the issue at hand - Custota is also "hard-ruined" now.

It installs, but the app can't be opened (immediate crash, "keeps stopping" message)

Re-installing (remove - reboot - install - reboot) does not help.

Using older versions doesn't seem to help but I didn't try them all.

I caught a logcat tho, hope it contains some useful information .

Logcat starts before first attempt to open custota app and continues through several attempts to open it (multiple crashes).

Could you please take a look at it ?

custotadead.txt

@chenxiaolong
Copy link
Owner

chenxiaolong commented Apr 6, 2024

Glad to hear the update worked!

I'm sad, but not surprised, that LSPosed no longer works correctly. With how Google changed its development model recently, the quarterly releases are closer to full Android releases. Android 14 QPR2 (March update) pulled in many changes from the upcoming Android 15.

For Custota, it looks like the root cause is this:

04-06 01:35:17.934  5062  5062 W hiller3.custota: Accessing hidden method Landroid/os/ServiceManager;->getServiceOrThrow(Ljava/lang/String;)Landroid/os/IBinder; (max-target-o, reflection, denied)
...
04-06 01:35:17.935  5062  5062 E AndroidRuntime: Caused by: java.lang.NoSuchMethodException: android.os.ServiceManager.getServiceOrThrow [class java.lang.String]
04-06 01:35:17.935  5062  5062 E AndroidRuntime: 	at java.lang.Class.getMethod(Class.java:2950)
04-06 01:35:17.935  5062  5062 E AndroidRuntime: 	at java.lang.Class.getDeclaredMethod(Class.java:2929)
04-06 01:35:17.935  5062  5062 E AndroidRuntime: 	at com.chiller3.custota.wrapper.ServiceManagerProxy.<clinit>(Unknown Source:14)
04-06 01:35:17.935  5062  5062 E AndroidRuntime: 	... 23 more

Android is blocking Custota from calling a method that allows it to connect to update_engine. Custota's Magisk module normally allows this by creating the /system/etc/sysconfig/config-com.chiller3.custota.xml config file.

Can you run this in a root shell and check that the permissions on Custota's file is the same as all the other files?

ls -lZ /system/etc/sysconfig/

Also, can you upload /data/local/tmp/custota_selinux.log?

EDIT: Also, if you happen to use Magisk's deny list (or other root hiding things), which apps is it enabled for?

@oddgirl
Copy link
Author

oddgirl commented Apr 6, 2024

Okay here it goes:


redfin:/ # ls -lZ /system/etc/sysconfig/
total 44
-rw-r--r-- 1 root root u:object_r:system_file:s0 182 2024-04-06 01:34 config-com.chiller3.custota.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 3606 2009-01-01 03:00 framework-sysconfig.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 3608 2009-01-01 03:00 hiddenapi-package-whitelist.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 1871 2009-01-01 03:00 initial-package-stopped-states.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 938 2009-01-01 03:00 preinstalled-packages-asl-files.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 952 2009-01-01 03:00 preinstalled-packages-com.android.providers.media.module.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 1329 2009-01-01 03:00 preinstalled-packages-platform-generic-system.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 1546 2009-01-01 03:00 preinstalled-packages-platform-handheld-system.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 5822 2009-01-01 03:00 preinstalled-packages-platform.xml
-rw-r--r-- 1 root root u:object_r:system_file:s0 1004 2009-01-01 03:00 preinstalled-packages-strict-signature.xml

redfin:/ # cat /data/local/tmp/custota_selinux.log
----- Environment -----
Timestamp: Fri Sep 4 14:18:52 MSK 1970
Script: /data/adb/modules/com.chiller3.custota/post-fs-data.sh
App ID: com.chiller3.custota
App version: v4.0.r7.gc43e3a6
UID/GID/Context: uid=0(root) gid=0(root) context=u:r:magisk:s0
----- Creating custota_app domain -----
Policy version: 30
----- Updating seapp_contexts -----
----- Linking CA store -----
Standard trust store: /apex/com.android.conscrypt/cacerts
update_engine trust store: /system/etc/security/cacerts


Denylist or other hiding measures are currently disabled and were not enabled during (or after) the update

@chenxiaolong
Copy link
Owner

Hmm, I'm baffled then. That all looks good.

Can you check one last thing? Whether the config file is visible to the system_server process:

cat /proc/$(pidof system_server)/root/system/etc/sysconfig/config-com.chiller3.custota.xml

If that prints out the file contents, then I have no idea why the config file isn't being respected.

Enabling access to hidden APIs globally might work as a workaround: https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#how_can_i_enable_access_to_non-sdk_interfaces

@chenxiaolong chenxiaolong reopened this Apr 6, 2024
chenxiaolong added a commit that referenced this issue Apr 6, 2024
Some devices seem to have trouble respecting the `hidden-api-whitelist`
option in the sysconfig file. When this happens, show a useful
notification instead of crashing hard.

Issue: #51

Signed-off-by: Andrew Gunnerson <[email protected]>
@nad0vs
Copy link

nad0vs commented Apr 6, 2024

Okay I have same behavior and here's a fun one - I uninstalled Custota fully via magisk menu and tried to install the 3.1 version.
The App Info says it's the 4+ RC version after 3.1 install.

Mysterious

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

Can you check one last thing? Whether the config file is visible to the system_server process:

Hey, I just tried this and it only works if I do it as root.

If non-root then no cigar (permission denied when run in adb without first calling su)

OH one more thing - the Custota apk is not in Magisk root list and does not at any point try to ask for magisk root permission.

Does that help?

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

Here are some wild photos (taken by another phone)

First, installing custota 3.1 after full uninstall

2024-04-06-21-34-19-815

Then, after reboot, check the version according-to-magisk

2024-04-06-21-41-32-441

then, after that, check out what the system's app info tool says about the app version

2024-04-06-21-35-31-743

Somehow, the 4.0-rc version persists !

Does magisk have some cursed cache squirreled away somewhere ?

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

I suspect I have a bearing on what's going on.

I have a multi-user config AND calyxos, so I have user0 with work profile and I have user 10 with work profile

@oddgirl you same ?

@chenxiaolong
Copy link
Owner

chenxiaolong commented Apr 6, 2024

I think @nad0vs might be on to something. I wonder if CalyxOS is (re)installing Custota's system app as a user app.

After uninstalling the module, run this to list all users (which includes both multi-user and work profiles):

husky:/ $ pm list users
Users:
        UserInfo{0:Owner:4c13} running
#                ^ the user ID

For each user, you can run:

pm path --user <user ID> com.chiller3.custota

to get the path of the APK if it's installed. If it is, it can be uninstalled for that user by running:

pm uninstall --user <user ID> com.chiller3.custota

After it's gone from every user, Android should delete the APK.


OH one more thing - the Custota apk is not in Magisk root list and does not at any point try to ask for magisk root permission.

This is expected. Custota use a script that runs during boot to configure SELinux, but that's the thing that ever uses root. The app only requires system app permissions, which is accomplished by the Magisk module putting files into the right places (eg. /system/priv-app).

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

Okay, I've tried the above and also ran pm uninstall --user [number] com.chiller3.custota
and it always said
Failure [not installed for [number]]

Needless to say when I re-install (and I tried reinstalling version 2.5 for crying out loud) nothing good happens and the system weirdly still reports the RC version

It's like it's cached - somewhere.
Could you maybe quickly cook up a version-number incremented release candidate? Just a weird superstitious hunch

@chenxiaolong
Copy link
Owner

Hmm, wtf. I've never seen Android have an app show up, but not be recognized by pm before.

Could you maybe quickly cook up a version-number incremented release candidate? Just a weird superstitious hunch

Sure. Here's a build from the latest commit in the master branch (e4cc1aa): Custota-4.0.r10.ge4cc1aa-release.zip

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

One more observation (I'll download and install the new build right after) - every time I re-install the module (no matter the version) it always gets the same base UID
dumpsys says (among a host of other things)

Packages:
Package [com.chiller3.custota] (2b1d1b8):
appId=10194

Is that normal for app to always get same UID upon re-installs ? I was under impression that it is assigned randomly no ?

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

Ooookay this is interesting, I flashed the above release candidate and it

  1. still crashes dead, the same behavior

and

  1. App info (from the app menu) still thinks it's 4.0.r7.gc43e3a6

I am about 70% positive it is cached somewhere, somehow.

Would it be safe to run pm uninstall --user x when the module is still installed ?

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

Done the pm unistall --user [number] thing while the module was installed, then re-installed the entire thing and

no good news

exact same behaviors and exact same weird report in system app picker ("stuck" on r7 version)

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

A trial balloon - would it be very hard to make a custom "custota-test" module with a "custota-test" name and new identifiers and signing keys and everything ?

I realize you probably would not rename the entire project to just help out one weird stuck edge case (which can get re-stuck later) but making an app and module with different "fingerprints" may help diagnose what ghostly hell is going on here, I suspect

@chenxiaolong
Copy link
Owner

Is that normal for app to always get same UID upon re-installs ? I was under impression that it is assigned randomly no ?

If nothing else was uninstalled around that time, then this is pretty normal. If I remember correctly, Android does not use random IDs. It starts sequentially from 10000 and picks the first available unused number.

  1. still crashes dead, the same behavior

and

  1. App info (from the app menu) still thinks it's 4.0.r7.gc43e3a6

Darn, yeah, it's definitely not picking up the new apk for some reason then.

Would it be safe to run pm uninstall --user x when the module is still installed ?

Yes, that's always safe to run. Worst case is you lose Custota's settings.


Out of curiosity, does the second line of /data/local/tmp/custota_selinux.log show an incorrect timestamp? I noticed that in @oddgirl's log. If it's incorrect, the timestamp may be the cause of Android's stale package info cache. I just remembered I had worked around this in my other project (BCR).

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

I get 1970s too despite the system time settings being correct.

@chenxiaolong
Copy link
Owner

OK, give me a few minutes to port the workaround from my other project to Custota. There's a chance it might fix the issue.

chenxiaolong added a commit that referenced this issue Apr 6, 2024
Some devices don't set the system time properly during boot, causing
Android's package manager to fail to invalidate cached package info.
Work around this by forcibly deleting the relevant cache files.

Issue: #51
See: chenxiaolong/BCR#323

Signed-off-by: Andrew Gunnerson <[email protected]>
@chenxiaolong
Copy link
Owner

chenxiaolong commented Apr 6, 2024

Please give this a try and upload /data/local/tmp/custota_selinux.log after a reboot: Custota-4.0.r11.g418c4e8-release.zip

If it did anything, I'd expect to see something like this in the log:

----- Clear package manager caches -----
Deleting: /data/system/package_cache/a167ba66ac524abe0d17222444705ee4b32b238b/com.chiller3.custota-16--512457307
Exit status: 0

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

Haven't run the app yet but

redfin:/ # cat /data/local/tmp/custota_selinux.log
----- Environment -----
Timestamp: Sat Sep 5 12:35:48 MSK 1970
Script: /data/adb/modules/com.chiller3.custota/post-fs-data.sh
App ID: com.chiller3.custota
App version: v4.0.r11.g418c4e8
CLI APK: /data/adb/modules/com.chiller3.custota/system/priv-app/com.chiller3.custota/app-release.apk
UID/GID/Context: uid=0(root) gid=0(root) context=u:r:magisk:s0
----- Creating custota_app domain -----
Policy version: 30
----- Updating seapp_contexts -----
-rw-r--r-- 1 root root u:object_r:system_file:s0 7637392 Apr 7 2024 /data/adb/modules/com.chiller3.custota/system/priv-app/com.chiller3.custota/app-release.apk
ls: /system/priv-app/com.chiller3.custota/app-release.apk: No such file or directory
-rw------- 1 system system u:object_r:system_data_file:s0 5864 2024-04-06 00:04 /data/system/package_cache/3b21e1d05bd1c1e89afc5ca3f674d9f3ecd0519e/com.chiller3.custota-16--512457307
----- Clear package manager caches -----
Deleting: /data/system/package_cache/3b21e1d05bd1c1e89afc5ca3f674d9f3ecd0519e/com.chiller3.custota-16--512457307
Exit status: 0
Logcat:
--------- beginning of main
09-05 12:35:48.661 1033 1033 D AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<
09-05 12:35:48.670 1033 1033 I AndroidRuntime: Using default boot image
09-05 12:35:48.670 1033 1033 I AndroidRuntime: Leaving lock profiling enabled
09-05 12:35:48.694 1033 1033 I app_process: Using CollectorTypeCC GC.
09-05 12:35:48.886 1033 1033 D nativeloader: InitDefaultPublicLibraries for_preload=1: libandroid.so:libaaudio.so:libamidi.so:libbinder_ndk.so:libc.so:libcamera2ndk.so:libdl.so:libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libicu.so:libicui18n.so:libicuuc.so:libjnigraphics.so:liblog.so:libmediandk.so:libm.so:libnativehelper.so:libnativewindow.so:libOpenMAXAL.so:libOpenSLES.so:libRS.so:libstdc++.so:libsync.so:libvulkan.so:libwebviewchromium_plat_support.so:libz.so
09-05 12:35:48.966 1033 1033 D app_process: Time zone APEX ICU file found: /apex/com.android.tzdata/etc/icu/icu_tzdata.dat
09-05 12:35:48.967 1033 1033 D app_process: I18n APEX ICU file found: /apex/com.android.i18n/etc/icu/icudt72l.dat
09-05 12:35:49.016 1033 1033 W ziparchive: Unable to open '/data/adb/modules/com.chiller3.custota/system/priv-app/com.chiller3.custota/app-release.dm': No such file or directory
09-05 12:35:49.199 1033 1033 D AndroidRuntime: Calling main entry com.chiller3.custota.standalone.ClearPackageManagerCachesKt
09-05 12:35:49.344 1033 1033 D AndroidRuntime: Shutting down VM
----- Linking CA store -----
Standard trust store: /apex/com.android.conscrypt/cacerts
update_engine trust store: /system/etc/security/cacerts
redfin:/ #

Timestamp is still 1970s tho. WTF.

Anyway will try launching the app now

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

oooookay the app launched and didn't show any warnings.

Any way to positively established we defeated the weird evil problem ?

@chenxiaolong
Copy link
Owner

Nice! Yep, try the "check for updates" option. If that doesn't fail, then we should be all good.

@chenxiaolong
Copy link
Owner

I have no idea what's causing the incorrect timestamps, but I'm guessing it's some bug introduced in the latest CalyxOS update.

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

"OS Already Up to Date"
No other notification / message

Should be allrightey-o ?

@chenxiaolong
Copy link
Owner

Yep! Should be completely fixed. I'll merge #54 and release version 4.1.

@nad0vs
Copy link

nad0vs commented Apr 6, 2024

a couple more questions if you don't mind :-)

  1. is it safe to "hide" (or disable) the Custota app in other users (so it doesn't clutter everything up) and would I need to un-hide the app in those when updating?

I am most comfortable with it staying in user 0 and just there

  1. could you go into more details on how it gets the timestamp?

I think it is worth reporting to the Calyx folks. While support of magisk modules is obviously outside of scope for them, the anomalous timestamp behavior might be involved in more than that and eventually come back to bite in some other, more "mainstream" parts of the system on unmodified installs (my gut feel)
So I'd like to copy/paste some useful info in the issue to make things easier on that end

@chenxiaolong
Copy link
Owner

  1. is it safe to "hide" (or disable) the Custota app in other users (so it doesn't clutter everything up) and would I need to un-hide the app in those when updating?

Yep, perfectly safe. It shouldn't really be installed in other profiles anyway, but I don't know how to prevent Android from doing that.

  1. could you go into more details on how it gets the timestamp?

Custota's boot script grabs the timestamp by running the date command. Anything else that queries the system time would be affected as well.

I think it may be most useful to them if you're able to grab a logcat as soon as possible after booting. Maybe the log file will catch the point during the boot process where the system time gets "fixed". If you're able to adb before unlocking the device, that'd probably work best. Otherwise, the logs from the earlier parts of the boot process might already be gone.

@chenxiaolong
Copy link
Owner

Version 4.1 has been released with all the fixes!

(Since the root cause appears to be fixed/worked around, I'm closing this issue. Feel free to keep discussing stuff--I get notifications for everything.)

@oddgirl
Copy link
Author

oddgirl commented Apr 11, 2024

Hi! Thank you very much, great to see it resolved.
I have a question though, @chenxiaolong
How would one purge this package manager cache for other apps / magisk modules?

Or maybe even for all the apps on the system (frankly don't quite grok what benefit package manager cache's existence brings)?

I suspect my inability to make some other magisk things work (including lsposed) is due to this very same bug.

I did look through the commit and... well...

Would nuking everything in "/data/system/package_cache/*" to smithereens after installing a likely-affected magisk module (or other likely affected app) be unwise and unsafe?

On a related note, do both the system apps (priv-app etc.) and the "normal person user apps" all have their package manager caches in that same "/data/system/package_cache" path ?

EDIT yeah that was two questions sorry 😊

@chenxiaolong
Copy link
Owner

chenxiaolong commented Apr 11, 2024

The only purpose of the cache is to save a couple seconds of boot time. It really isn't very useful. Some OS's, like GrapheneOS, disable the feature entirely.

Deleting /data/system/package_cache/* is indeed the way to go, but I wouldn't recommend doing that while the system is running. I'd suggest creating a super basic Magisk module containing only:

module.prop
post-fs-data.sh
META-INF/com/google/android/update-binary
META-INF/com/google/android/updater-script

post-fs-data.sh can be a script that does nothing else besides:

find /data/system/package_cache -mindepth 1 -delete

The script is guaranteed to run early enough during boot that nothing will be trying to read from the cache yet.

EDIT: Adding setprop pm.boot.disable_package_cache true to the script should prevent Android from putting things into the cache again.

@chenxiaolong
Copy link
Owner

chenxiaolong commented Apr 11, 2024

Whoops, forgot to answer your second question.

On a related note, do both the system apps (priv-app etc.) and the "normal person user apps" all have their package manager caches in that same "/data/system/package_cache" path ?

Yes. The cache is for all apks across all users. The filename pattern is:

/data/system/package_cache/<partition fingerprint hash>/<parent>-<flags>-<parent hash>

In case you're curious, these are the components are:

  • <partition fingerprint hash>: This is equal to:

    (
        echo ro.system.build.fingerprint=$(getprop ro.system.build.fingerprint)
        echo ro.vendor.build.fingerprint=$(getprop ro.vendor.build.fingerprint)
        echo ro.odm.build.fingerprint=$(getprop ro.odm.build.fingerprint)
        echo ro.oem.build.fingerprint=$(getprop ro.oem.build.fingerprint)
        echo ro.product.build.fingerprint=$(getprop ro.product.build.fingerprint)
        echo ro.system_ext.build.fingerprint=$(getprop ro.system_ext.build.fingerprint)
        echo ro.build.fingerprint=$(getprop ro.build.fingerprint)
    ) | sha1sum

    Because these values contain the OS's version number, this is what causes cache to be invalidated with the OS is upgraded.

  • <parent>: This is the name of the directory containing the apk. Eg. Custota is at /system/priv-app/com.chiller3.custota/app-release.apk, so the value would be com.chiller3.custota. For user apps, it'll be some ugly hash (matching the subdirectory name inside /data/app/).

  • <flags>: These are the flags that Android uses when reading the apk. This will be 16 for most system apps, which means that the apk is being loaded from a system directory (16 == PARSE_IS_SYSTEM_DIR). This will likely be 0 for user apps.

  • <parent hash>: This is the hash of the full path of the apk's parent directory. It's not any standard hash, like SHA-1, but rather Java's File.hashCode(). This allow distinguishing between apps where the directory name is the same. For example, /system/app/blah and /vendor/app/blah.

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

Successfully merging a pull request may close this issue.

3 participants