Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6348,6 +6348,7 @@ private String bringUpServiceInnerLocked(ServiceRecord r, int intentFlags, boole

if (AswUseExecSpawning.isEnabledFor(mAm.mContext, userId, definingAppInfo,
GosPackageState.get(definingPkgName, userId), isNativeService)) {
hostingRecord.setAppZygoteReplacement();
boolean preload = (isNativeService ?
definingAppInfo.zygotePreloadNativeLib :
definingAppInfo.zygotePreloadName) != null;
Expand Down
11 changes: 11 additions & 0 deletions services/core/java/com/android/server/am/HostingRecord.java
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,17 @@ public ApplicationInfo getAppInfoForPreloading() {
return mAppInfoForPreloading;
}

// Whether exec spawning replaces an app zygote requested for this process.
private boolean mIsAppZygoteReplacement;

void setAppZygoteReplacement() {
mIsAppZygoteReplacement = true;
}

boolean isAppZygoteReplacement() {
return mIsAppZygoteReplacement;
}

/**
* @return if the process should be spawned from the Native App Zygote
*/
Expand Down
9 changes: 9 additions & 0 deletions services/core/java/com/android/server/am/ProcessList.java
Original file line number Diff line number Diff line change
Expand Up @@ -2119,6 +2119,15 @@ boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
}
}
}
// App and WebView zygote children inherit the defining package's shared app GID.
// Exec-spawned replacements start from the primary zygote, so request it explicitly.
if (zygoteExtArgs.shouldUseExecSpawning() && ArrayUtils.isEmpty(gids)
&& (hostingRecord.usesWebviewZygote_()
|| hostingRecord.isAppZygoteReplacement())) {
gids = new int[] { UserHandle.getSharedAppGid(
UserHandle.getAppId(hostingRecord.getDefiningUid())) };
app.setGids(gids);
}

// the per-user SELinux context must be set
if (TextUtils.isEmpty(app.info.seInfoUser)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
<application
android:debuggable="false"
android:label="GOS Secure Spawn Checks"
android:theme="@android:style/Theme.DeviceDefault.DayNight">
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:zygotePreloadNativeLib="libgoscompat_native_signal_probe.so">
<uses-library android:name="android.test.runner" />

<activity
Expand All @@ -17,6 +18,23 @@
</intent-filter>
</activity>

<activity
android:name=".WebViewRendererActivity"
android:exported="false" />

<service
android:name=".ManagedAppZygoteProbeService"
android:exported="false"
android:isolatedProcess="true"
android:process=":managed_app_zygote_probe"
android:useAppZygote="true" />

<service
android:name=".ManagedIsolatedProbeService"
android:exported="false"
android:isolatedProcess="true"
android:process=":managed_isolated_probe" />

<service
android:name=".NativeSignalProbeService"
android:exported="false"
Expand All @@ -27,6 +45,18 @@
android:name="android.app.PROPERTY_NATIVE_SERVICE_LIBRARY_NAME"
android:value="libgoscompat_native_signal_probe.so" />
</service>

<service
android:name=".NativeAppZygoteSignalProbeService"
android:exported="false"
android:isolatedProcess="true"
android:nativeService="true"
android:process=":native_app_zygote_signal_probe"
android:useAppZygote="true">
<property
android:name="android.app.PROPERTY_NATIVE_SERVICE_LIBRARY_NAME"
android:value="libgoscompat_native_signal_probe.so" />
</service>
</application>

<instrumentation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package app.grapheneos.goscompat.securespawn;

interface IManagedProcessProbe {
int getPid();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ package app.grapheneos.goscompat.securespawn;

interface INativeSignalProbe {
oneway void terminateWithSigterm();
int[] getSupplementaryGroups();
int getPid();
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include <aidl/app/grapheneos/goscompat/securespawn/BnNativeSignalProbe.h>
#include <android/binder_ibinder.h>
#include <android/native_service.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>

#include <memory>
#include <vector>

namespace {

Expand All @@ -16,6 +18,34 @@ class NativeSignalProbe final : public BnNativeSignalProbe {
kill(getpid(), SIGTERM);
return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus getSupplementaryGroups(
std::vector<int32_t>* _aidl_return) override {
int groupCount = getgroups(0, nullptr);
if (groupCount < 0) {
return ndk::ScopedAStatus::fromServiceSpecificError(errno);
}

std::vector<gid_t> groups(static_cast<size_t>(groupCount));
if (groupCount > 0) {
groupCount = getgroups(groupCount, groups.data());
if (groupCount < 0) {
return ndk::ScopedAStatus::fromServiceSpecificError(errno);
}
}

_aidl_return->resize(static_cast<size_t>(groupCount));
for (int i = 0; i < groupCount; ++i) {
(*_aidl_return)[i] = static_cast<int32_t>(groups[i]);
}

return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus getPid(int32_t* _aidl_return) override {
*_aidl_return = static_cast<int32_t>(getpid());
return ndk::ScopedAStatus::ok();
}
};

std::shared_ptr<NativeSignalProbe> gService;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package app.grapheneos.goscompat.securespawn;

public final class ManagedAppZygoteProbeService extends ManagedProcessProbeService {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package app.grapheneos.goscompat.securespawn;

public final class ManagedIsolatedProbeService extends ManagedProcessProbeService {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package app.grapheneos.goscompat.securespawn;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Process;

public abstract class ManagedProcessProbeService extends Service {
private final IManagedProcessProbe.Stub mBinder = new IManagedProcessProbe.Stub() {
@Override
public int getPid() {
return Process.myPid();
}
};

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
Loading