Skip to content

fix: map the app's cache group like its real group - #10

Merged
oonid merged 4 commits into
mainfrom
fix/app-cache-gid
Oct 17, 2026
Merged

oonid merged 4 commits into
mainfrom
fix/app-cache-gid

Conversation

@oonid

@oonid oonid commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

In the app, /tmp is the app's cache dir, which Android makes setgid to the app's cache group (u0_a515_cache, gid 20515). Files created there showed that gid in a fake-root session (ls -ln /tmp → 0 20515), because the owner rule (#9) mapped only the app's primary gid. Found while verifying #9.

  • fake_id0 computes the cache gid at initialization (AOSP multiuser_get_cache_gid: app id - 10000 + 20000) and keeps it in Config.app_cache_gid only if PRoot's process is in that group. An app process is; run-as, the VM and desktop Linux get (gid_t) -1, so nothing changes there.
  • fake_owner_gid() maps it like the real gid, so stat, statx and the USERLAND fstat path show the fake group. The gid and the constants match bionic's u0_aNNNN_cache mapping (grp_pwd.cpp).
  • New fakeroot test: a new file in /tmp has geteuid():getegid(). Docs: proot-improvement.md §35, counts 54 → 55.

Verification

  • Android 16 (Samsung), in-app terminal (the cache dir is /tmp only there): before the fix the new test fails (/tmp/pit-fr-tmp-group is 0:20515, want 0:0); after it fakeroot 7/7 and ls -ln /tmp/pit shows 0 0. pit all from in-app terminals 55/55 on alpine and ubuntu; pr-cli test alpine and pr-cli test ubuntu 55/55.
  • Alpine arm64 VM (mapping disabled there): alpine 51/51, .l2s 51/51 (ssh skipped), Ubuntu 26.04 55/55, fakeroot without link2symlink 7/7; as a uid != gid user general 9/9, chroot 2/2, fakeroot 7/7.
  • Host cargo test 169; every commit builds with only the 8 upstream warnings.
  • Committed libproot.so and libpr-cli.so rebuild bit-identically from the branch.

Found, not changed

Directories created in the app's /tmp inherit the cache dir's setgid bit (drwxr-sr-x). Mode bits are not faked: the bit is real and decides the group of files created inside.

oonid added 4 commits October 17, 2026 17:04
Android gives every app a cache group (app id - 10000 + 20000, e.g.
u0_a515_cache = 20515) and makes the app's cache dir setgid to it.
pr-cli binds that dir at /tmp, so files created there showed gid 20515
in a fake-root session instead of the fake group.

fake_id0 now computes the cache gid from the real uid at initialization
and keeps it in Config.app_cache_gid, only if PRoot's process is in
that group (an app process is; run-as, the VM and desktop Linux get
-1). fake_owner_gid() maps it like the real gid, so stat, statx and
the USERLAND fstat path show the fake group.
In the app /tmp is the cache dir, setgid to the app's cache group; the
test fails there before the fix (0:20515, want 0:0). Under run-as and
in the VM /tmp is not the cache dir, so it passes either way.
proot-improvement.md section 35, the new fakeroot test, and test
counts 54 -> 55.
libproot.so maps the app cache group; libpr-cli.so embeds the test
binary with the /tmp group test.
@oonid
oonid force-pushed the fix/app-cache-gid branch from 2c86d29 to 2bdf722 Compare October 17, 2026 10:05
@oonid
oonid merged commit e6794b0 into main Oct 17, 2026
1 check passed
@oonid
oonid deleted the fix/app-cache-gid branch October 17, 2026 10:30
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 this pull request may close these issues.

1 participant