Skip to content

Ubuntu's apt-get fails with "Could not switch saved set-user-ID" when running inside an Android work profile #369

@jsamol

Description

@jsamol

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:

  1. Set up an emulator running a Google APIs system image.
  2. Install Google's TestDPC app (can be downloaded directly from github).
  3. Run the TestDPC app to set up the work profile.
  4. Install the proot test app in the personal profile.
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions