Setup permissions for SDK sandbox UIDs.
Applications may have an additional SDK sandbox process that should run with the same network policy as the app itself. There is a 1:1 mapping between appId and the SDK sandbox process that belongs to it; use that mapping to set the same policy for SDK sandbox processes as for the app that they belong to. Bug: 215012578 Test: atest com.android.server.PermissionMonitorTest Change-Id: Ibd2ada09c94d46e048f5731b90a721d8e85d3289
This commit is contained in:
@@ -52,6 +52,7 @@ import android.net.UidRange;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceSpecificException;
|
import android.os.ServiceSpecificException;
|
||||||
import android.os.SystemConfigManager;
|
import android.os.SystemConfigManager;
|
||||||
@@ -66,7 +67,10 @@ import android.util.SparseIntArray;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
import com.android.modules.utils.build.SdkLevel;
|
||||||
import com.android.net.module.util.CollectionUtils;
|
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.server.BpfNetMaps;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -95,6 +99,8 @@ public class PermissionMonitor {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final BpfNetMaps mBpfNetMaps;
|
private final BpfNetMaps mBpfNetMaps;
|
||||||
|
|
||||||
|
private static final ProcessShim sProcessShim = ProcessShimImpl.newInstance();
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private final Set<UserHandle> mUsers = new HashSet<>();
|
private final Set<UserHandle> mUsers = new HashSet<>();
|
||||||
|
|
||||||
@@ -235,6 +241,10 @@ public class PermissionMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// Return the network permission for the passed list of apps. Note that this depends on the
|
||||||
// current settings of the device (See isUidAllowedOnRestrictedNetworks).
|
// current settings of the device (See isUidAllowedOnRestrictedNetworks).
|
||||||
private SparseIntArray makeUidsNetworkPerm(final List<PackageInfo> apps) {
|
private SparseIntArray makeUidsNetworkPerm(final List<PackageInfo> apps) {
|
||||||
@@ -247,6 +257,10 @@ public class PermissionMonitor {
|
|||||||
final int permission = getPackageNetdNetworkPermission(app);
|
final int permission = getPackageNetdNetworkPermission(app);
|
||||||
if (isHigherNetworkPermission(permission, uidsPerm.get(uid, PERMISSION_NONE))) {
|
if (isHigherNetworkPermission(permission, uidsPerm.get(uid, PERMISSION_NONE))) {
|
||||||
uidsPerm.put(uid, permission);
|
uidsPerm.put(uid, permission);
|
||||||
|
if (hasSdkSandbox(uid)) {
|
||||||
|
int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
|
||||||
|
uidsPerm.put(sdkSandboxUid, permission);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return uidsPerm;
|
return uidsPerm;
|
||||||
@@ -262,7 +276,11 @@ public class PermissionMonitor {
|
|||||||
}
|
}
|
||||||
final int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
|
final int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
|
||||||
app.requestedPermissionsFlags);
|
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;
|
return appIdsPerm;
|
||||||
}
|
}
|
||||||
@@ -288,11 +306,19 @@ public class PermissionMonitor {
|
|||||||
final SparseIntArray appIdsPerm = new SparseIntArray();
|
final SparseIntArray appIdsPerm = new SparseIntArray();
|
||||||
for (final int uid : mSystemConfigManager.getSystemPermissionUids(INTERNET)) {
|
for (final int uid : mSystemConfigManager.getSystemPermissionUids(INTERNET)) {
|
||||||
final int appId = UserHandle.getAppId(uid);
|
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)) {
|
for (final int uid : mSystemConfigManager.getSystemPermissionUids(UPDATE_DEVICE_STATS)) {
|
||||||
final int appId = UserHandle.getAppId(uid);
|
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;
|
return appIdsPerm;
|
||||||
}
|
}
|
||||||
@@ -592,6 +618,12 @@ public class PermissionMonitor {
|
|||||||
|
|
||||||
SparseIntArray apps = new SparseIntArray();
|
SparseIntArray apps = new SparseIntArray();
|
||||||
apps.put(uid, permission);
|
apps.put(uid, permission);
|
||||||
|
|
||||||
|
if (hasSdkSandbox(uid)) {
|
||||||
|
int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
|
||||||
|
mUidToNetworkPerm.put(sdkSandboxUid, permission);
|
||||||
|
apps.put(sdkSandboxUid, permission);
|
||||||
|
}
|
||||||
sendUidsNetworkPermission(apps, true /* add */);
|
sendUidsNetworkPermission(apps, true /* add */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,13 +686,25 @@ public class PermissionMonitor {
|
|||||||
+ ", tPerm=" + permissionToString(trafficPerm));
|
+ ", tPerm=" + permissionToString(trafficPerm));
|
||||||
if (permission != currentPermission) {
|
if (permission != currentPermission) {
|
||||||
final SparseIntArray apps = new SparseIntArray();
|
final SparseIntArray apps = new SparseIntArray();
|
||||||
|
int sdkSandboxUid = -1;
|
||||||
|
if (hasSdkSandbox(uid)) {
|
||||||
|
sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
|
||||||
|
}
|
||||||
if (permission == PERMISSION_NONE) {
|
if (permission == PERMISSION_NONE) {
|
||||||
mUidToNetworkPerm.delete(uid);
|
mUidToNetworkPerm.delete(uid);
|
||||||
apps.put(uid, PERMISSION_NETWORK); // doesn't matter which permission we pick here
|
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);
|
sendUidsNetworkPermission(apps, false);
|
||||||
} else {
|
} else {
|
||||||
mUidToNetworkPerm.put(uid, permission);
|
mUidToNetworkPerm.put(uid, permission);
|
||||||
apps.put(uid, permission);
|
apps.put(uid, permission);
|
||||||
|
if (sdkSandboxUid != -1) {
|
||||||
|
mUidToNetworkPerm.put(sdkSandboxUid, permission);
|
||||||
|
apps.put(sdkSandboxUid, permission);
|
||||||
|
}
|
||||||
sendUidsNetworkPermission(apps, true);
|
sendUidsNetworkPermission(apps, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -828,6 +872,10 @@ public class PermissionMonitor {
|
|||||||
void sendPackagePermissionsForAppId(int appId, int permissions) {
|
void sendPackagePermissionsForAppId(int appId, int permissions) {
|
||||||
SparseIntArray netdPermissionsAppIds = new SparseIntArray();
|
SparseIntArray netdPermissionsAppIds = new SparseIntArray();
|
||||||
netdPermissionsAppIds.put(appId, permissions);
|
netdPermissionsAppIds.put(appId, permissions);
|
||||||
|
if (hasSdkSandbox(appId)) {
|
||||||
|
int sdkSandboxAppId = sProcessShim.toSdkSandboxUid(appId);
|
||||||
|
netdPermissionsAppIds.put(sdkSandboxAppId, permissions);
|
||||||
|
}
|
||||||
sendAppIdsTrafficPermission(netdPermissionsAppIds);
|
sendAppIdsTrafficPermission(netdPermissionsAppIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -925,9 +973,19 @@ public class PermissionMonitor {
|
|||||||
// Doesn't matter which permission is set here.
|
// Doesn't matter which permission is set here.
|
||||||
removedUids.put(uid, PERMISSION_NETWORK);
|
removedUids.put(uid, PERMISSION_NETWORK);
|
||||||
mUidToNetworkPerm.delete(uid);
|
mUidToNetworkPerm.delete(uid);
|
||||||
|
if (hasSdkSandbox(uid)) {
|
||||||
|
int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
|
||||||
|
removedUids.put(sdkSandboxUid, PERMISSION_NETWORK);
|
||||||
|
mUidToNetworkPerm.delete(sdkSandboxUid);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
updatedUids.put(uid, permission);
|
updatedUids.put(uid, permission);
|
||||||
mUidToNetworkPerm.put(uid, permission);
|
mUidToNetworkPerm.put(uid, permission);
|
||||||
|
if (hasSdkSandbox(uid)) {
|
||||||
|
int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid);
|
||||||
|
updatedUids.put(sdkSandboxUid, permission);
|
||||||
|
mUidToNetworkPerm.put(sdkSandboxUid, permission);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ import android.net.INetd;
|
|||||||
import android.net.UidRange;
|
import android.net.UidRange;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Process;
|
||||||
import android.os.SystemConfigManager;
|
import android.os.SystemConfigManager;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
@@ -88,7 +89,10 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.test.InstrumentationRegistry;
|
import androidx.test.InstrumentationRegistry;
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.modules.utils.build.SdkLevel;
|
||||||
import com.android.net.module.util.CollectionUtils;
|
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.server.BpfNetMaps;
|
||||||
import com.android.testutils.DevSdkIgnoreRule;
|
import com.android.testutils.DevSdkIgnoreRule;
|
||||||
import com.android.testutils.DevSdkIgnoreRunner;
|
import com.android.testutils.DevSdkIgnoreRunner;
|
||||||
@@ -153,6 +157,8 @@ public class PermissionMonitorTest {
|
|||||||
private NetdMonitor mNetdMonitor;
|
private NetdMonitor mNetdMonitor;
|
||||||
private BpfMapMonitor mBpfMapMonitor;
|
private BpfMapMonitor mBpfMapMonitor;
|
||||||
|
|
||||||
|
private ProcessShim mProcessShim = ProcessShimImpl.newInstance();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
@@ -197,6 +203,10 @@ public class PermissionMonitorTest {
|
|||||||
return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
|
return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasSdkSandbox(final int uid) {
|
||||||
|
return SdkLevel.isAtLeastT() && Process.isApplicationUid(uid);
|
||||||
|
}
|
||||||
|
|
||||||
private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
|
private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
|
||||||
return packageInfoWithPermissions(
|
return packageInfoWithPermissions(
|
||||||
REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
|
REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
|
||||||
@@ -493,6 +503,11 @@ public class PermissionMonitorTest {
|
|||||||
String... permissions) throws Exception {
|
String... permissions) throws Exception {
|
||||||
addPackage(name, uid, permissions);
|
addPackage(name, uid, permissions);
|
||||||
assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
|
assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
|
||||||
|
if (hasSdkSandbox(uid)) {
|
||||||
|
final int sdkSandboxUid = mProcessShim.toSdkSandboxUid(uid);
|
||||||
|
assertEquals(hasPermission,
|
||||||
|
mPermissionMonitor.hasUseBackgroundNetworksPermission(sdkSandboxUid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -531,7 +546,7 @@ public class PermissionMonitorTest {
|
|||||||
}).when(mockBpfmap).setNetPermForUids(anyInt(), any(int[].class));
|
}).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) {
|
for (final int appId : appIds) {
|
||||||
if (mAppIdsTrafficPermission.get(appId, DOES_NOT_EXIST) == DOES_NOT_EXIST) {
|
if (mAppIdsTrafficPermission.get(appId, DOES_NOT_EXIST) == DOES_NOT_EXIST) {
|
||||||
fail("appId " + appId + " does not exist.");
|
fail("appId " + appId + " does not exist.");
|
||||||
@@ -540,6 +555,17 @@ public class PermissionMonitorTest {
|
|||||||
fail("appId " + appId + " has wrong permission: "
|
fail("appId " + appId + " has wrong permission: "
|
||||||
+ mAppIdsTrafficPermission.get(appId));
|
+ 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 @@ public class PermissionMonitorTest {
|
|||||||
if (mUidsNetworkPermission.get(uid) != permission) {
|
if (mUidsNetworkPermission.get(uid) != permission) {
|
||||||
fail("uid " + uid + " has wrong permission: " + 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 @@ public class PermissionMonitorTest {
|
|||||||
if (mUidsNetworkPermission.get(uid, DOES_NOT_EXIST) != DOES_NOT_EXIST) {
|
if (mUidsNetworkPermission.get(uid, DOES_NOT_EXIST) != DOES_NOT_EXIST) {
|
||||||
fail("uid " + uid + " has listed permissions, expected none.");
|
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 @@ public class PermissionMonitorTest {
|
|||||||
// MOCK_APPID2: MOCK_PACKAGE2 does not have any permission.
|
// MOCK_APPID2: MOCK_PACKAGE2 does not have any permission.
|
||||||
// SYSTEM_APPID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission
|
// SYSTEM_APPID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission
|
||||||
// SYSTEM_APPID2: SYSTEM_PACKAGE2 has only 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();
|
SparseIntArray netdPermissionsAppIds = new SparseIntArray();
|
||||||
netdPermissionsAppIds.put(MOCK_APPID1, PERMISSION_INTERNET);
|
netdPermissionsAppIds.put(MOCK_APPID1, PERMISSION_INTERNET);
|
||||||
|
if (hasSdkSandbox(MOCK_APPID1)) {
|
||||||
|
netdPermissionsAppIds.put(mProcessShim.toSdkSandboxUid(MOCK_APPID1),
|
||||||
|
PERMISSION_INTERNET);
|
||||||
|
}
|
||||||
netdPermissionsAppIds.put(MOCK_APPID2, PERMISSION_NONE);
|
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_APPID1, PERMISSION_TRAFFIC_ALL);
|
||||||
netdPermissionsAppIds.put(SYSTEM_APPID2, PERMISSION_UPDATE_DEVICE_STATS);
|
netdPermissionsAppIds.put(SYSTEM_APPID2, PERMISSION_UPDATE_DEVICE_STATS);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user