Merge "Setup permissions for SDK sandbox UIDs."
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index ac46054..2885ba7 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -52,6 +52,7 @@
import android.net.Uri;
import android.net.util.SharedLog;
import android.os.Build;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.SystemConfigManager;
@@ -66,7 +67,10 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.CollectionUtils;
+import com.android.networkstack.apishim.ProcessShimImpl;
+import com.android.networkstack.apishim.common.ProcessShim;
import com.android.server.BpfNetMaps;
import java.util.ArrayList;
@@ -95,6 +99,8 @@
private final Context mContext;
private final BpfNetMaps mBpfNetMaps;
+ private static final ProcessShim sProcessShim = ProcessShimImpl.newInstance();
+
@GuardedBy("this")
private final Set<UserHandle> mUsers = new HashSet<>();
@@ -235,6 +241,10 @@
}
}
+ private static boolean hasSdkSandbox(final int uid) {
+ return SdkLevel.isAtLeastT() && Process.isApplicationUid(uid);
+ }
+
// Return the network permission for the passed list of apps. Note that this depends on the
// current settings of the device (See isUidAllowedOnRestrictedNetworks).
private SparseIntArray makeUidsNetworkPerm(final List<PackageInfo> apps) {
@@ -247,6 +257,10 @@
final int permission = getPackageNetdNetworkPermission(app);
if (isHigherNetworkPermission(permission, uidsPerm.get(uid, PERMISSION_NONE))) {
uidsPerm.put(uid, permission);
+ if (hasSdkSandbox(uid)) {
+ int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
+ uidsPerm.put(sdkSandboxUid, permission);
+ }
}
}
return uidsPerm;
@@ -262,7 +276,11 @@
}
final int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
app.requestedPermissionsFlags);
- appIdsPerm.put(appId, appIdsPerm.get(appId) | otherNetdPerms);
+ final int permission = appIdsPerm.get(appId) | otherNetdPerms;
+ appIdsPerm.put(appId, permission);
+ if (hasSdkSandbox(appId)) {
+ appIdsPerm.put(sProcessShim.toSdkSandboxUid(appId), permission);
+ }
}
return appIdsPerm;
}
@@ -288,11 +306,19 @@
final SparseIntArray appIdsPerm = new SparseIntArray();
for (final int uid : mSystemConfigManager.getSystemPermissionUids(INTERNET)) {
final int appId = UserHandle.getAppId(uid);
- appIdsPerm.put(appId, appIdsPerm.get(appId) | PERMISSION_INTERNET);
+ final int permission = appIdsPerm.get(appId) | PERMISSION_INTERNET;
+ appIdsPerm.put(appId, permission);
+ if (hasSdkSandbox(appId)) {
+ appIdsPerm.put(sProcessShim.toSdkSandboxUid(appId), permission);
+ }
}
for (final int uid : mSystemConfigManager.getSystemPermissionUids(UPDATE_DEVICE_STATS)) {
final int appId = UserHandle.getAppId(uid);
- appIdsPerm.put(appId, appIdsPerm.get(appId) | PERMISSION_UPDATE_DEVICE_STATS);
+ final int permission = appIdsPerm.get(appId) | PERMISSION_UPDATE_DEVICE_STATS;
+ appIdsPerm.put(appId, permission);
+ if (hasSdkSandbox(appId)) {
+ appIdsPerm.put(sProcessShim.toSdkSandboxUid(appId), permission);
+ }
}
return appIdsPerm;
}
@@ -592,6 +618,12 @@
SparseIntArray apps = new SparseIntArray();
apps.put(uid, permission);
+
+ if (hasSdkSandbox(uid)) {
+ int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
+ mUidToNetworkPerm.put(sdkSandboxUid, permission);
+ apps.put(sdkSandboxUid, permission);
+ }
sendUidsNetworkPermission(apps, true /* add */);
}
@@ -654,13 +686,25 @@
+ ", tPerm=" + permissionToString(trafficPerm));
if (permission != currentPermission) {
final SparseIntArray apps = new SparseIntArray();
+ int sdkSandboxUid = -1;
+ if (hasSdkSandbox(uid)) {
+ sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
+ }
if (permission == PERMISSION_NONE) {
mUidToNetworkPerm.delete(uid);
apps.put(uid, PERMISSION_NETWORK); // doesn't matter which permission we pick here
+ if (sdkSandboxUid != -1) {
+ mUidToNetworkPerm.delete(sdkSandboxUid);
+ apps.put(sdkSandboxUid, PERMISSION_NETWORK);
+ }
sendUidsNetworkPermission(apps, false);
} else {
mUidToNetworkPerm.put(uid, permission);
apps.put(uid, permission);
+ if (sdkSandboxUid != -1) {
+ mUidToNetworkPerm.put(sdkSandboxUid, permission);
+ apps.put(sdkSandboxUid, permission);
+ }
sendUidsNetworkPermission(apps, true);
}
}
@@ -828,6 +872,10 @@
void sendPackagePermissionsForAppId(int appId, int permissions) {
SparseIntArray netdPermissionsAppIds = new SparseIntArray();
netdPermissionsAppIds.put(appId, permissions);
+ if (hasSdkSandbox(appId)) {
+ int sdkSandboxAppId = sProcessShim.toSdkSandboxUid(appId);
+ netdPermissionsAppIds.put(sdkSandboxAppId, permissions);
+ }
sendAppIdsTrafficPermission(netdPermissionsAppIds);
}
@@ -925,9 +973,19 @@
// Doesn't matter which permission is set here.
removedUids.put(uid, PERMISSION_NETWORK);
mUidToNetworkPerm.delete(uid);
+ if (hasSdkSandbox(uid)) {
+ int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
+ removedUids.put(sdkSandboxUid, PERMISSION_NETWORK);
+ mUidToNetworkPerm.delete(sdkSandboxUid);
+ }
} else {
updatedUids.put(uid, permission);
mUidToNetworkPerm.put(uid, permission);
+ if (hasSdkSandbox(uid)) {
+ int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
+ updatedUids.put(sdkSandboxUid, permission);
+ mUidToNetworkPerm.put(sdkSandboxUid, permission);
+ }
}
}
diff --git a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
index 6590543..6b379e8 100644
--- a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -77,6 +77,7 @@
import android.net.UidRange;
import android.net.Uri;
import android.os.Build;
+import android.os.Process;
import android.os.SystemConfigManager;
import android.os.UserHandle;
import android.os.UserManager;
@@ -88,7 +89,10 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.CollectionUtils;
+import com.android.networkstack.apishim.ProcessShimImpl;
+import com.android.networkstack.apishim.common.ProcessShim;
import com.android.server.BpfNetMaps;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
@@ -153,6 +157,8 @@
private NetdMonitor mNetdMonitor;
private BpfMapMonitor mBpfMapMonitor;
+ private ProcessShim mProcessShim = ProcessShimImpl.newInstance();
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -197,6 +203,10 @@
return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
}
+ private boolean hasSdkSandbox(final int uid) {
+ return SdkLevel.isAtLeastT() && Process.isApplicationUid(uid);
+ }
+
private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
return packageInfoWithPermissions(
REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
@@ -493,6 +503,11 @@
String... permissions) throws Exception {
addPackage(name, uid, permissions);
assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
+ if (hasSdkSandbox(uid)) {
+ final int sdkSandboxUid = mProcessShim.toSdkSandboxUid(uid);
+ assertEquals(hasPermission,
+ mPermissionMonitor.hasUseBackgroundNetworksPermission(sdkSandboxUid));
+ }
}
@Test
@@ -531,7 +546,7 @@
}).when(mockBpfmap).setNetPermForUids(anyInt(), any(int[].class));
}
- public void expectTrafficPerm(int permission, int... appIds) {
+ public void expectTrafficPerm(int permission, Integer... appIds) {
for (final int appId : appIds) {
if (mAppIdsTrafficPermission.get(appId, DOES_NOT_EXIST) == DOES_NOT_EXIST) {
fail("appId " + appId + " does not exist.");
@@ -540,6 +555,17 @@
fail("appId " + appId + " has wrong permission: "
+ mAppIdsTrafficPermission.get(appId));
}
+ if (hasSdkSandbox(appId)) {
+ int sdkSandboxAppId = mProcessShim.toSdkSandboxUid(appId);
+ if (mAppIdsTrafficPermission.get(sdkSandboxAppId, DOES_NOT_EXIST)
+ == DOES_NOT_EXIST) {
+ fail("SDK sandbox appId " + sdkSandboxAppId + " does not exist.");
+ }
+ if (mAppIdsTrafficPermission.get(sdkSandboxAppId) != permission) {
+ fail("SDK sandbox appId " + sdkSandboxAppId + " has wrong permission: "
+ + mAppIdsTrafficPermission.get(sdkSandboxAppId));
+ }
+ }
}
}
}
@@ -589,6 +615,17 @@
if (mUidsNetworkPermission.get(uid) != permission) {
fail("uid " + uid + " has wrong permission: " + permission);
}
+ if (hasSdkSandbox(uid)) {
+ int sdkSandboxUid = mProcessShim.toSdkSandboxUid(uid);
+ if (mUidsNetworkPermission.get(sdkSandboxUid, DOES_NOT_EXIST)
+ == DOES_NOT_EXIST) {
+ fail("SDK sandbox uid " + uid + " does not exist.");
+ }
+ if (mUidsNetworkPermission.get(sdkSandboxUid) != permission) {
+ fail("SDK sandbox uid " + uid + " has wrong permission: "
+ + permission);
+ }
+ }
}
}
}
@@ -600,6 +637,14 @@
if (mUidsNetworkPermission.get(uid, DOES_NOT_EXIST) != DOES_NOT_EXIST) {
fail("uid " + uid + " has listed permissions, expected none.");
}
+ if (hasSdkSandbox(uid)) {
+ int sdkSandboxUid = mProcessShim.toSdkSandboxUid(uid);
+ if (mUidsNetworkPermission.get(sdkSandboxUid, DOES_NOT_EXIST)
+ != DOES_NOT_EXIST) {
+ fail("SDK sandbox uid " + sdkSandboxUid
+ + " has listed permissions, expected none.");
+ }
+ }
}
}
}
@@ -785,9 +830,18 @@
// MOCK_APPID2: MOCK_PACKAGE2 does not have any permission.
// SYSTEM_APPID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission
// SYSTEM_APPID2: SYSTEM_PACKAGE2 has only update device stats permission.
+ // The SDK sandbox APPIDs must have permissions mirroring the app
SparseIntArray netdPermissionsAppIds = new SparseIntArray();
netdPermissionsAppIds.put(MOCK_APPID1, PERMISSION_INTERNET);
+ if (hasSdkSandbox(MOCK_APPID1)) {
+ netdPermissionsAppIds.put(mProcessShim.toSdkSandboxUid(MOCK_APPID1),
+ PERMISSION_INTERNET);
+ }
netdPermissionsAppIds.put(MOCK_APPID2, PERMISSION_NONE);
+ if (hasSdkSandbox(MOCK_APPID2)) {
+ netdPermissionsAppIds.put(mProcessShim.toSdkSandboxUid(MOCK_APPID2),
+ PERMISSION_NONE);
+ }
netdPermissionsAppIds.put(SYSTEM_APPID1, PERMISSION_TRAFFIC_ALL);
netdPermissionsAppIds.put(SYSTEM_APPID2, PERMISSION_UPDATE_DEVICE_STATS);