Ubuntu's `apt-get` fails with "Could not switch saved set-user-ID" when running inside an Android work profile
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 1.1k
- Forks
- 276
- PR merge metrics
- No merged PRs in 30d
Description
Problem description
apt-get update fails inside an Ubuntu Questing rootfs when proot is running inside an Android work profile (managed profile) with http erroring out on Could not switch saved set-user-ID.
$ apt-get update
Reading package lists...
E: Method gave invalid 400 URI Failure message: Could not switch saved set-user-ID
E: Method http has died unexpectedly!
E: Sub-process http returned an error code (112)
Full verbose logs: proot.log
The same rootfs and configuration works correctly in the personal (non-work) Android profile.
Steps to reproduce
This is a bit tricky, because it requires a work profile setup first. The easiest way I can think of is to:
- Set up an emulator running a Google APIs system image.
- Install Google's TestDPC app (can be downloaded directly from github).
- Run the TestDPC app to set up the work profile.
- Install the proot test app in the personal profile.
- Install the proot test app in the work profile with
adb:
$ adb shell pm list users <-- to get the work profile user ID
$ adb root
$ adb shell pm install-existing --user <work-profile-user-id> <proot-app-package>
The proot test app should require nothing more than executing the proot -0 command running apt-get update inside an Ubuntu Questing rootfs.
I can provide an MVP, if needed.
Expected behavior
apt-get update completes successfully, as it does in the personal profile.
Additional information
Test environment
Model: Google Pixel 8a
Android Version: 16 (API level 36)
Possible cause
I investigated the issue a bit with the AI and one plausible explanation that it gave me was that in the Android work profiles there's additional seccomp filter which enforces a UID range before proot gets a chance to intercept the call:
Android work profile processes run under an additional seccomp BPF filter (install_setuidgid_seccomp_filter in bionic, called from set_app_zygote_seccomp_filter in Zygote.cpp) that validates all arguments of setresuid/setresgid against the app's UID range. Since _apt's UID (~100) and the saved UID argument of 0 fall outside the work profile UID range (~1010000+), the filter returns SECCOMP_RET_ERRNO(EINVAL) before proot can intercept the call.
This is based on AOSP source references found online (bionic commit d269d9b9e930ae1fb0df49813fbcdc3d3a5850a7)
However, I don't have enough knowledge in that subject to be able to verify the information is correct and not just a hallucination.
While debugging the issue, I've tried setting PROOT_NO_SECCOMP=1 to disable proot's seccomp mode. This seemed to fix the user ID issue, however, apt-get update would still fail but with E: Method gave invalid 400 URI Failure message: Could not switch group and it broke a bunch of other unrelated calls.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing apt-get update with proot -v 9 inside the Android work profile and inspect the linked proot.log. Compare the behavior with PROOT_NO_SECCOMP=1, then read the mentioned AOSP install_setuidgid_seccomp_filter and set_app_zygote_seccomp_filter paths. Done means the Ubuntu Questing rootfs updates successfully in the work profile without the set-user-ID or group errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, c, linux
- Domain
- operating-systems, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100