Skip to content

gmscompat: allow remote credential entries from GmsCore - #413

Open
maade93791 wants to merge 493 commits into
GrapheneOS:17from
maade93791:17-cred
Open

gmscompat: allow remote credential entries from GmsCore#413
maade93791 wants to merge 493 commits into
GrapheneOS:17from
maade93791:17-cred

Conversation

@maade93791

Copy link
Copy Markdown
Member

Play services use
com.google.android.gms.auth.api.credentials.credman.service.RemoteService for credential manager.
remote entries are used for for both create and get requests:

mtu mtuVar = msbVar.b;
if (mtuVar != null) {
    builder.setRemoteCreateEntry(new RemoteEntry(mtt.b(mtuVar)));
}

...

mtu mtuVar = msiVar.d;
if (mtuVar != null) {
    builder.setRemoteCredentialEntry(new RemoteEntry(mtt.b(mtuVar)));
}

Credential Manager rejected the valid response because no hybrid service is configured, so allow the enabled RemoteService when no OEM provied service is enabled.

Test: enable Play Services as credential provider & login into a 2FA-protected Google Account in Play Store

muhomorr and others added 30 commits June 16, 2026 18:17
Google TTS app is forceQueryable on stock OS. Third-party apps expect to be able to query it without
holding the QUERY_ALL_PACKAGES permission.
Before this change, touch-to-unlock was always active there, regardless of the setting value.
See the corresponding commit in device/google/tangorpro for more info.
Pixel stock OS now enables FRP by default for everyone who has secure lock screen and a Google
account.
Crash report snippet:

signal: 11 (SIGSEGV), code 9 (SEGV_MTESERR), faultAddr 300d6a4a30c285c
threadName: BG Thread GrapheneOS#2

backtrace:
    /product/priv-app/PixelCameraServices/PixelCameraServices.apk!libHdrPlusJni.so (Java_com_google_googlex_gcam_GcamModuleJNI_FrameRequest_1type_1get+0, pc 1495320)
    /system/framework/arm64/boot.oat (art_jni_trampoline+124, pc 9c76c)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (td.h+2748, pc 46472c)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (tc.b+104, pc 53bee8)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (bwv.aq+96, pc 4224f0)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (cat.run+1016, pc 4239c8)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (aph.run+180, pc 1a27c4)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (akd.run+72, pc 17c6a8)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (bjf.run+464, pc 21ab80)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (mf.run+2440, pc 305da8)
    /data/dalvik-cache/arm64/product@priv-app@PixelCameraServices@PixelCameraServices.apk@classes.dex (alo.run+404, pc 1810f4)
This bug led to PackageInstallerSession#computeUserActionRequirement() allowing unprivileged
installer to install a package without confirmation when that installer had already installed the
same package in another user.
onBind() is always called immediately after onCreate() for these services. onBind() is called from
binder threads, it's not thread-safe to perform lazy initialization there without locking.
Location providers aren't expected to be removed at runtime by the apps and by the OS itself.

Removing a location provider leads to app and system_server crashes when they attempt to use the
previously existing provider.

Upstream removes location providers in just one case: when a test (mock) location provider is added
and then removed for a non-existing location provider.
inthewaves and others added 29 commits July 8, 2026 09:44
Test: atest SystemUITests -- \
  --atest-include-filter SystemUITests:com.android.systemui.screenrecord.domain.interactor.ScreenRecordingServiceRepositoryTest \
  --atest-include-filter SystemUITests:com.android.systemui.screencapture.ScreenCaptureCoreStartableTest
Recent Android Auto version use the AudioManager.setCommunicationDevice() method which is protected
by this permission.
…ess init

Run the onBind() hook at an earlier point by removing its dependency on the app context object.
This is required by the next commit.
Use AppBindArgs to pass systemIdmapPaths to the app instead of performing an extra Binder IPC call
to ActivityManagerService during app process launch.
For background, see https://grapheneos.org/usage#exec-spawning

New app processes are created by forking zygote, then immediately exec()-ing a new zygote and
replaying commands that were sent to the original zygote in the new zygote. Commands are passed to
the new zygote through a memfd.

Exec spawning can be disabled on a per-app basis.

App processes that are spawned through secondary zygotes (WebView processes and service processes
which use an app zygote) are instead spawned through the primary zygote. Boot-time WebView zygote
startup is disabled to reduce memory usage. The WebView zygote is started on-demand to support apps
that are opted out of exec spawning.

Test: atest GosCompatSecureSpawnTests HardeningTest CtsExternalServiceTestCases CtsNativeServiceTest CtsAppServiceTestCases CtsSeccompHostTestCases
This zygote instance is used when both exec spawning and hardened_malloc are disabled.
Mount namespace is setup already by the parent zygote.

Some banking apps check whether Linux mount IDs are below 1024 and refuse to work otherwise.

Mount IDs increase over time, i.e. new mount IDs for the new mount namespace break that check.
Some banking apps check whether Linux mount IDs are below 1024 and refuse to work otherwise.

Mount IDs increase over time, which means that starting compat zygote on-demand breaks this check.
Compat zygote is used only for app processes which disable both hardened_malloc and exec spawning.
Check framework and shared memory descriptor mount state under secure exec, primary zygote and
compatibility zygote process startup. Select the compatibility zygote through the allocator package
state instead of the umbrella compatibility mode.

Test: atest GosCompatSecureSpawnTests:SecureSpawn{Enabled,Disabled}HostTest#fdStateCheck
GosCompatSecureSpawnTests:SecureSpawnDisabledHostTest#hardenedMallocOffFdStateCheck
Package dumps include one dataDir entry for every user. getDataDir searched the whole dump and
required exactly one result, causing tests to fail before migration on devices with secondary users
and profiles.

Restrict the lookup to the main package section and select the foreground user entry. This keeps
the data preservation check associated with the user running the test.

Test: atest PackageManagerServiceHostTests:com.android.server.pm.test.OriginalPackageMigrationTest
…ties

Vanadium uses app.vanadium.browser as its manifest package while migrated installations retain
org.chromium.chrome as their effective package. PackageManager.Property retains the manifest name,
so PackageProperty indexes native service properties under app.vanadium.browser.

NativeApplicationThreadWrapper looks up the native service library with:

```java
PackageManager.Property libNameProperty =
        mMgr.getPackageManager()
                .getPropertyAsUser(
                        PackageManager.PROPERTY_NATIVE_SERVICE_LIBRARY_NAME,
                        info.packageName,
                        info.getComponentName().getClassName(),
                        userId);
if (libNameProperty != null) libName = libNameProperty.getString();
```

info is the ServiceInfo passed to scheduleCreateService() for the native service. Its packageName is
the effective org.chromium.chrome identity. Looking up the property with that name misses the entry
stored under app.vanadium.browser, leaving libName as libmain.so instead of libmonochrome_64.so.
Upstream original-package doesn't handle manifest properties.

Keep validating package installation and visibility with the effective name. Look up that property
key first, then retry with the manifest name only when both identities on the parsed package exactly
match migrated Vanadium. This keeps the workaround from affecting other package renames and
preserves an effective name property if one is present.

Test: manual, with Vanadium using old org.chromium.chrome app id, updating to a Vanadium APK with
app.vanadium.browser app id with javaless renderers enabled. Browser pages load instead of showing
errors logcat about failing to open libmain.so
Play services use
`com.google.android.gms.auth.api.credentials.credman.service.RemoteService`
for credential manager.
remote entries are used for for both create and get requests:

```
mtu mtuVar = msbVar.b;
if (mtuVar != null) {
    builder.setRemoteCreateEntry(new RemoteEntry(mtt.b(mtuVar)));
}

...

mtu mtuVar = msiVar.d;
if (mtuVar != null) {
    builder.setRemoteCredentialEntry(new RemoteEntry(mtt.b(mtuVar)));
}
```

Credential Manager rejected the valid response because no hybrid service
is configured, so allow the enabled RemoteService when no OEM provied service
is enabled.

Test: enable Play Services as credential provider & login into a
2FA-protected Google Account in Play Store
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.