Merge "Revert "[RFPM03] Check permission by uid.""
This commit is contained in:
@@ -21,23 +21,14 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
|
|||||||
import static android.Manifest.permission.INTERNET;
|
import static android.Manifest.permission.INTERNET;
|
||||||
import static android.Manifest.permission.NETWORK_STACK;
|
import static android.Manifest.permission.NETWORK_STACK;
|
||||||
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
|
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
|
||||||
|
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
|
||||||
import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
||||||
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
||||||
import static android.net.INetd.PERMISSION_INTERNET;
|
|
||||||
import static android.net.INetd.PERMISSION_NETWORK;
|
|
||||||
import static android.net.INetd.PERMISSION_NONE;
|
|
||||||
import static android.net.INetd.PERMISSION_SYSTEM;
|
|
||||||
import static android.net.INetd.PERMISSION_UNINSTALLED;
|
|
||||||
import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
|
|
||||||
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
||||||
import static android.os.Process.INVALID_UID;
|
import static android.os.Process.INVALID_UID;
|
||||||
import static android.os.Process.SYSTEM_UID;
|
import static android.os.Process.SYSTEM_UID;
|
||||||
|
|
||||||
import static com.android.internal.util.ArrayUtils.convertToIntArray;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
@@ -60,6 +51,7 @@ 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.ArrayUtils;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.SystemConfig;
|
import com.android.server.SystemConfig;
|
||||||
@@ -73,6 +65,7 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A utility class to inform Netd of UID permisisons.
|
* A utility class to inform Netd of UID permisisons.
|
||||||
* Does a mass update at boot and then monitors for app install/remove.
|
* Does a mass update at boot and then monitors for app install/remove.
|
||||||
@@ -121,13 +114,6 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
public int getDeviceFirstSdkInt() {
|
public int getDeviceFirstSdkInt() {
|
||||||
return Build.VERSION.FIRST_SDK_INT;
|
return Build.VERSION.FIRST_SDK_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether given uid has specific permission.
|
|
||||||
*/
|
|
||||||
public int uidPermission(@NonNull final String permission, final int uid) {
|
|
||||||
return ActivityManager.checkUidPermission(permission, uid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) {
|
public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) {
|
||||||
@@ -170,9 +156,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
}
|
}
|
||||||
mAllApps.add(UserHandle.getAppId(uid));
|
mAllApps.add(UserHandle.getAppId(uid));
|
||||||
|
|
||||||
final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
|
boolean isNetwork = hasNetworkPermission(app);
|
||||||
final boolean hasRestrictedPermission =
|
boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
|
||||||
hasRestrictedNetworkPermission(app.applicationInfo);
|
|
||||||
|
|
||||||
if (isNetwork || hasRestrictedPermission) {
|
if (isNetwork || hasRestrictedPermission) {
|
||||||
Boolean permission = mApps.get(uid);
|
Boolean permission = mApps.get(uid);
|
||||||
@@ -184,7 +169,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: unify the management of the permissions into one codepath.
|
//TODO: unify the management of the permissions into one codepath.
|
||||||
final int otherNetdPerms = getNetdPermissionMask(uid);
|
int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
|
||||||
|
app.requestedPermissionsFlags);
|
||||||
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,8 +190,9 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
// Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission.
|
// Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission.
|
||||||
if (perms != null) {
|
if (perms != null) {
|
||||||
netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
|
netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
|
||||||
? PERMISSION_UPDATE_DEVICE_STATS : 0;
|
? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0;
|
||||||
netdPermission |= perms.contains(INTERNET) ? PERMISSION_INTERNET : 0;
|
netdPermission |= perms.contains(INTERNET)
|
||||||
|
? INetd.PERMISSION_INTERNET : 0;
|
||||||
}
|
}
|
||||||
netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
|
netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
|
||||||
}
|
}
|
||||||
@@ -220,33 +207,48 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean hasPermission(@NonNull final String permission, final int uid) {
|
boolean hasPermission(@NonNull final PackageInfo app, @NonNull final String permission) {
|
||||||
return mDeps.uidPermission(permission, uid) == PackageManager.PERMISSION_GRANTED;
|
if (app.requestedPermissions == null || app.requestedPermissionsFlags == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final int index = ArrayUtils.indexOf(app.requestedPermissions, permission);
|
||||||
|
if (index < 0 || index >= app.requestedPermissionsFlags.length) return false;
|
||||||
|
return (app.requestedPermissionsFlags[index] & REQUESTED_PERMISSION_GRANTED) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean hasRestrictedNetworkPermission(@Nullable final ApplicationInfo appInfo) {
|
boolean hasNetworkPermission(@NonNull final PackageInfo app) {
|
||||||
if (appInfo == null) return false;
|
return hasPermission(app, CHANGE_NETWORK_STATE);
|
||||||
// TODO : remove this check in the future(b/162295056). All apps should just
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean hasRestrictedNetworkPermission(@NonNull final PackageInfo app) {
|
||||||
|
// TODO : remove this check in the future(b/31479477). All apps should just
|
||||||
// request the appropriate permission for their use case since android Q.
|
// request the appropriate permission for their use case since android Q.
|
||||||
if ((appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo))
|
if (app.applicationInfo != null) {
|
||||||
// Backward compatibility for b/114245686, on devices that launched before Q daemons
|
// Backward compatibility for b/114245686, on devices that launched before Q daemons
|
||||||
// and apps running as the system UID are exempted from this check.
|
// and apps running as the system UID are exempted from this check.
|
||||||
|| (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q)) {
|
if (app.applicationInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.applicationInfo.targetSdkVersion < VERSION_Q
|
||||||
|
&& isVendorApp(app.applicationInfo)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, appInfo.uid)
|
return hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK)
|
||||||
|| hasPermission(NETWORK_STACK, appInfo.uid)
|
|| hasPermission(app, NETWORK_STACK)
|
||||||
|| hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, appInfo.uid);
|
|| hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether the given uid has using background network permission. */
|
/** Returns whether the given uid has using background network permission. */
|
||||||
public synchronized boolean hasUseBackgroundNetworksPermission(final int uid) {
|
public synchronized boolean hasUseBackgroundNetworksPermission(final int uid) {
|
||||||
// Apps with any of the CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_INTERNAL or
|
// Apps with any of the CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_INTERNAL or
|
||||||
// CONNECTIVITY_USE_RESTRICTED_NETWORKS permission has the permission to use background
|
// CONNECTIVITY_USE_RESTRICTED_NETWORKS permission has the permission to use background
|
||||||
// networks. mApps contains the result of checks for both CHANGE_NETWORK_STATE permission
|
// networks. mApps contains the result of checks for both hasNetworkPermission and
|
||||||
// and hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of
|
// hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of
|
||||||
// permissions at least.
|
// permissions at least.
|
||||||
return mApps.containsKey(uid);
|
return mApps.containsKey(uid);
|
||||||
}
|
}
|
||||||
@@ -271,11 +273,11 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (add) {
|
if (add) {
|
||||||
mNetd.networkSetPermissionForUser(PERMISSION_NETWORK, convertToIntArray(network));
|
mNetd.networkSetPermissionForUser(INetd.PERMISSION_NETWORK, toIntArray(network));
|
||||||
mNetd.networkSetPermissionForUser(PERMISSION_SYSTEM, convertToIntArray(system));
|
mNetd.networkSetPermissionForUser(INetd.PERMISSION_SYSTEM, toIntArray(system));
|
||||||
} else {
|
} else {
|
||||||
mNetd.networkClearPermissionForUser(convertToIntArray(network));
|
mNetd.networkClearPermissionForUser(toIntArray(network));
|
||||||
mNetd.networkClearPermissionForUser(convertToIntArray(system));
|
mNetd.networkClearPermissionForUser(toIntArray(system));
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
loge("Exception when updating permissions: " + e);
|
loge("Exception when updating permissions: " + e);
|
||||||
@@ -321,15 +323,14 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected Boolean highestPermissionForUid(Boolean currentPermission, String name, int uid) {
|
protected Boolean highestPermissionForUid(Boolean currentPermission, String name) {
|
||||||
if (currentPermission == SYSTEM) {
|
if (currentPermission == SYSTEM) {
|
||||||
return currentPermission;
|
return currentPermission;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
|
final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
|
||||||
final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
|
final boolean isNetwork = hasNetworkPermission(app);
|
||||||
final boolean hasRestrictedPermission =
|
final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
|
||||||
hasRestrictedNetworkPermission(app.applicationInfo);
|
|
||||||
if (isNetwork || hasRestrictedPermission) {
|
if (isNetwork || hasRestrictedPermission) {
|
||||||
currentPermission = hasRestrictedPermission;
|
currentPermission = hasRestrictedPermission;
|
||||||
}
|
}
|
||||||
@@ -341,14 +342,23 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getPermissionForUid(final int uid) {
|
private int getPermissionForUid(final int uid) {
|
||||||
|
int permission = INetd.PERMISSION_NONE;
|
||||||
// Check all the packages for this UID. The UID has the permission if any of the
|
// Check all the packages for this UID. The UID has the permission if any of the
|
||||||
// packages in it has the permission.
|
// packages in it has the permission.
|
||||||
final String[] packages = mPackageManager.getPackagesForUid(uid);
|
final String[] packages = mPackageManager.getPackagesForUid(uid);
|
||||||
if (packages == null || packages.length <= 0) {
|
if (packages != null && packages.length > 0) {
|
||||||
|
for (String name : packages) {
|
||||||
|
final PackageInfo app = getPackageInfo(name);
|
||||||
|
if (app != null && app.requestedPermissions != null) {
|
||||||
|
permission |= getNetdPermissionMask(app.requestedPermissions,
|
||||||
|
app.requestedPermissionsFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// The last package of this uid is removed from device. Clean the package up.
|
// The last package of this uid is removed from device. Clean the package up.
|
||||||
return PERMISSION_UNINSTALLED;
|
permission = INetd.PERMISSION_UNINSTALLED;
|
||||||
}
|
}
|
||||||
return getNetdPermissionMask(uid);
|
return permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -365,7 +375,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
|
|
||||||
// If multiple packages share a UID (cf: android:sharedUserId) and ask for different
|
// If multiple packages share a UID (cf: android:sharedUserId) and ask for different
|
||||||
// permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
|
// permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
|
||||||
final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName, uid);
|
final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName);
|
||||||
if (permission != mApps.get(uid)) {
|
if (permission != mApps.get(uid)) {
|
||||||
mApps.put(uid, permission);
|
mApps.put(uid, permission);
|
||||||
|
|
||||||
@@ -421,7 +431,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
String[] packages = mPackageManager.getPackagesForUid(uid);
|
String[] packages = mPackageManager.getPackagesForUid(uid);
|
||||||
if (packages != null && packages.length > 0) {
|
if (packages != null && packages.length > 0) {
|
||||||
for (String name : packages) {
|
for (String name : packages) {
|
||||||
permission = highestPermissionForUid(permission, name, uid);
|
permission = highestPermissionForUid(permission, name);
|
||||||
if (permission == SYSTEM) {
|
if (permission == SYSTEM) {
|
||||||
// An app with this UID still has the SYSTEM permission.
|
// An app with this UID still has the SYSTEM permission.
|
||||||
// Therefore, this UID must already have the SYSTEM permission.
|
// Therefore, this UID must already have the SYSTEM permission.
|
||||||
@@ -457,13 +467,19 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
|
sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getNetdPermissionMask(final int uid) {
|
private static int getNetdPermissionMask(String[] requestedPermissions,
|
||||||
int permissions = PERMISSION_NONE;
|
int[] requestedPermissionsFlags) {
|
||||||
if (hasPermission(INTERNET, uid)) {
|
int permissions = 0;
|
||||||
permissions |= PERMISSION_INTERNET;
|
if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
|
||||||
}
|
for (int i = 0; i < requestedPermissions.length; i++) {
|
||||||
if (hasPermission(UPDATE_DEVICE_STATS, uid)) {
|
if (requestedPermissions[i].equals(INTERNET)
|
||||||
permissions |= PERMISSION_UPDATE_DEVICE_STATS;
|
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
|
||||||
|
permissions |= INetd.PERMISSION_INTERNET;
|
||||||
|
}
|
||||||
|
if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
|
||||||
|
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
|
||||||
|
permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
@@ -632,19 +648,19 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
for (int i = 0; i < netdPermissionsAppIds.size(); i++) {
|
for (int i = 0; i < netdPermissionsAppIds.size(); i++) {
|
||||||
int permissions = netdPermissionsAppIds.valueAt(i);
|
int permissions = netdPermissionsAppIds.valueAt(i);
|
||||||
switch(permissions) {
|
switch(permissions) {
|
||||||
case (PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS):
|
case (INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS):
|
||||||
allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
||||||
break;
|
break;
|
||||||
case PERMISSION_INTERNET:
|
case INetd.PERMISSION_INTERNET:
|
||||||
internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
||||||
break;
|
break;
|
||||||
case PERMISSION_UPDATE_DEVICE_STATS:
|
case INetd.PERMISSION_UPDATE_DEVICE_STATS:
|
||||||
updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
||||||
break;
|
break;
|
||||||
case PERMISSION_NONE:
|
case INetd.PERMISSION_NONE:
|
||||||
noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
|
||||||
break;
|
break;
|
||||||
case PERMISSION_UNINSTALLED:
|
case INetd.PERMISSION_UNINSTALLED:
|
||||||
uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
|
uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
|
||||||
default:
|
default:
|
||||||
Log.e(TAG, "unknown permission type: " + permissions + "for uid: "
|
Log.e(TAG, "unknown permission type: " + permissions + "for uid: "
|
||||||
@@ -655,24 +671,24 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
// TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
|
// TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
|
||||||
if (allPermissionAppIds.size() != 0) {
|
if (allPermissionAppIds.size() != 0) {
|
||||||
mNetd.trafficSetNetPermForUids(
|
mNetd.trafficSetNetPermForUids(
|
||||||
PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
|
INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
|
||||||
convertToIntArray(allPermissionAppIds));
|
ArrayUtils.convertToIntArray(allPermissionAppIds));
|
||||||
}
|
}
|
||||||
if (internetPermissionAppIds.size() != 0) {
|
if (internetPermissionAppIds.size() != 0) {
|
||||||
mNetd.trafficSetNetPermForUids(PERMISSION_INTERNET,
|
mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET,
|
||||||
convertToIntArray(internetPermissionAppIds));
|
ArrayUtils.convertToIntArray(internetPermissionAppIds));
|
||||||
}
|
}
|
||||||
if (updateStatsPermissionAppIds.size() != 0) {
|
if (updateStatsPermissionAppIds.size() != 0) {
|
||||||
mNetd.trafficSetNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
|
mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS,
|
||||||
convertToIntArray(updateStatsPermissionAppIds));
|
ArrayUtils.convertToIntArray(updateStatsPermissionAppIds));
|
||||||
}
|
}
|
||||||
if (noPermissionAppIds.size() != 0) {
|
if (noPermissionAppIds.size() != 0) {
|
||||||
mNetd.trafficSetNetPermForUids(PERMISSION_NONE,
|
mNetd.trafficSetNetPermForUids(INetd.PERMISSION_NONE,
|
||||||
convertToIntArray(noPermissionAppIds));
|
ArrayUtils.convertToIntArray(noPermissionAppIds));
|
||||||
}
|
}
|
||||||
if (uninstalledAppIds.size() != 0) {
|
if (uninstalledAppIds.size() != 0) {
|
||||||
mNetd.trafficSetNetPermForUids(PERMISSION_UNINSTALLED,
|
mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED,
|
||||||
convertToIntArray(uninstalledAppIds));
|
ArrayUtils.convertToIntArray(uninstalledAppIds));
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Pass appId list of special permission failed." + e);
|
Log.e(TAG, "Pass appId list of special permission failed." + e);
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import static android.Manifest.permission.UPDATE_DEVICE_STATS;
|
|||||||
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
|
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
|
||||||
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
|
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
|
||||||
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
|
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
|
||||||
|
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
|
||||||
|
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED;
|
||||||
import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
||||||
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
||||||
import static android.os.Process.SYSTEM_UID;
|
import static android.os.Process.SYSTEM_UID;
|
||||||
@@ -95,6 +97,7 @@ public class PermissionMonitorTest {
|
|||||||
private static final int SYSTEM_UID1 = 1000;
|
private static final int SYSTEM_UID1 = 1000;
|
||||||
private static final int SYSTEM_UID2 = 1008;
|
private static final int SYSTEM_UID2 = 1008;
|
||||||
private static final int VPN_UID = 10002;
|
private static final int VPN_UID = 10002;
|
||||||
|
private static final String REAL_SYSTEM_PACKAGE_NAME = "android";
|
||||||
private static final String MOCK_PACKAGE1 = "appName1";
|
private static final String MOCK_PACKAGE1 = "appName1";
|
||||||
private static final String MOCK_PACKAGE2 = "appName2";
|
private static final String MOCK_PACKAGE2 = "appName2";
|
||||||
private static final String SYSTEM_PACKAGE1 = "sysName1";
|
private static final String SYSTEM_PACKAGE1 = "sysName1";
|
||||||
@@ -125,7 +128,6 @@ public class PermissionMonitorTest {
|
|||||||
new UserInfo(MOCK_USER1, "", 0),
|
new UserInfo(MOCK_USER1, "", 0),
|
||||||
new UserInfo(MOCK_USER2, "", 0),
|
new UserInfo(MOCK_USER2, "", 0),
|
||||||
}));
|
}));
|
||||||
doReturn(PackageManager.PERMISSION_DENIED).when(mDeps).uidPermission(anyString(), anyInt());
|
|
||||||
|
|
||||||
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
|
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
|
||||||
|
|
||||||
@@ -138,22 +140,35 @@ public class PermissionMonitorTest {
|
|||||||
verify(mMockPmi).getPackageList(mPermissionMonitor);
|
verify(mMockPmi).getPackageList(mPermissionMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all permissions from the uid then build new package info and setup permissions to uid
|
|
||||||
* for checking restricted network permission.
|
|
||||||
*/
|
|
||||||
private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
|
private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
|
||||||
String... permissions) {
|
String... permissions) {
|
||||||
final PackageInfo packageInfo = buildPackageInfo(partition, uid, MOCK_USER1);
|
final PackageInfo packageInfo =
|
||||||
|
packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, permissions, partition);
|
||||||
packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
|
packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
|
||||||
removeAllPermissions(uid);
|
packageInfo.applicationInfo.uid = uid;
|
||||||
addPermissions(uid, permissions);
|
return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
|
||||||
return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo.applicationInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PackageInfo packageInfoWithPartition(String partition) {
|
private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
|
||||||
|
return packageInfoWithPermissions(
|
||||||
|
REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PackageInfo vendorPackageInfoWithPermissions(String... permissions) {
|
||||||
|
return packageInfoWithPermissions(
|
||||||
|
REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_VENDOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PackageInfo packageInfoWithPermissions(int permissionsFlags,
|
||||||
|
String[] permissions, String partition) {
|
||||||
|
int[] requestedPermissionsFlags = new int[permissions.length];
|
||||||
|
for (int i = 0; i < permissions.length; i++) {
|
||||||
|
requestedPermissionsFlags[i] = permissionsFlags;
|
||||||
|
}
|
||||||
final PackageInfo packageInfo = new PackageInfo();
|
final PackageInfo packageInfo = new PackageInfo();
|
||||||
|
packageInfo.requestedPermissions = permissions;
|
||||||
packageInfo.applicationInfo = new ApplicationInfo();
|
packageInfo.applicationInfo = new ApplicationInfo();
|
||||||
|
packageInfo.requestedPermissionsFlags = requestedPermissionsFlags;
|
||||||
int privateFlags = 0;
|
int privateFlags = 0;
|
||||||
switch (partition) {
|
switch (partition) {
|
||||||
case PARTITION_OEM:
|
case PARTITION_OEM:
|
||||||
@@ -170,64 +185,84 @@ public class PermissionMonitorTest {
|
|||||||
return packageInfo;
|
return packageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PackageInfo buildPackageInfo(String partition, int uid, int userId) {
|
private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid, int userId) {
|
||||||
final PackageInfo pkgInfo = packageInfoWithPartition(partition);
|
final PackageInfo pkgInfo;
|
||||||
|
if (hasSystemPermission) {
|
||||||
|
pkgInfo = systemPackageInfoWithPermissions(
|
||||||
|
CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
|
||||||
|
} else {
|
||||||
|
pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, "");
|
||||||
|
}
|
||||||
pkgInfo.applicationInfo.uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
|
pkgInfo.applicationInfo.uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
|
||||||
return pkgInfo;
|
return pkgInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This will REMOVE all previously set permissions from given uid. */
|
|
||||||
private void removeAllPermissions(int uid) {
|
|
||||||
doReturn(PackageManager.PERMISSION_DENIED).when(mDeps).uidPermission(anyString(), eq(uid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set up mocks so that given UID has the requested permissions. */
|
|
||||||
private void addPermissions(int uid, String... permissions) {
|
|
||||||
for (String permission : permissions) {
|
|
||||||
doReturn(PackageManager.PERMISSION_GRANTED)
|
|
||||||
.when(mDeps).uidPermission(eq(permission), eq(uid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHasPermission() {
|
public void testHasPermission() {
|
||||||
addPermissions(MOCK_UID1);
|
PackageInfo app = systemPackageInfoWithPermissions();
|
||||||
assertFalse(mPermissionMonitor.hasPermission(CHANGE_NETWORK_STATE, MOCK_UID1));
|
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
|
||||||
assertFalse(mPermissionMonitor.hasPermission(NETWORK_STACK, MOCK_UID1));
|
assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
|
||||||
assertFalse(mPermissionMonitor.hasPermission(
|
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
|
||||||
CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID1));
|
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
|
||||||
assertFalse(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID1));
|
|
||||||
|
|
||||||
addPermissions(MOCK_UID1, CHANGE_NETWORK_STATE, NETWORK_STACK);
|
app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE, NETWORK_STACK);
|
||||||
assertTrue(mPermissionMonitor.hasPermission(CHANGE_NETWORK_STATE, MOCK_UID1));
|
assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
|
||||||
assertTrue(mPermissionMonitor.hasPermission(NETWORK_STACK, MOCK_UID1));
|
assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
|
||||||
assertFalse(mPermissionMonitor.hasPermission(
|
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
|
||||||
CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID1));
|
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
|
||||||
assertFalse(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID1));
|
|
||||||
assertFalse(mPermissionMonitor.hasPermission(CHANGE_NETWORK_STATE, MOCK_UID2));
|
|
||||||
assertFalse(mPermissionMonitor.hasPermission(NETWORK_STACK, MOCK_UID2));
|
|
||||||
|
|
||||||
addPermissions(MOCK_UID2, CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL);
|
app = systemPackageInfoWithPermissions(
|
||||||
assertFalse(mPermissionMonitor.hasPermission(
|
CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL);
|
||||||
CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID1));
|
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
|
||||||
assertFalse(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID1));
|
assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
|
||||||
assertTrue(mPermissionMonitor.hasPermission(
|
assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
|
||||||
CONNECTIVITY_USE_RESTRICTED_NETWORKS, MOCK_UID2));
|
assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
|
||||||
assertTrue(mPermissionMonitor.hasPermission(CONNECTIVITY_INTERNAL, MOCK_UID2));
|
|
||||||
|
app = packageInfoWithPermissions(REQUESTED_PERMISSION_REQUIRED, new String[] {
|
||||||
|
CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL, NETWORK_STACK },
|
||||||
|
PARTITION_SYSTEM);
|
||||||
|
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
|
||||||
|
assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
|
||||||
|
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
|
||||||
|
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
|
||||||
|
|
||||||
|
app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
|
||||||
|
app.requestedPermissions = null;
|
||||||
|
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
|
||||||
|
|
||||||
|
app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
|
||||||
|
app.requestedPermissionsFlags = null;
|
||||||
|
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsVendorApp() {
|
public void testIsVendorApp() {
|
||||||
PackageInfo app = packageInfoWithPartition(PARTITION_SYSTEM);
|
PackageInfo app = systemPackageInfoWithPermissions();
|
||||||
assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
||||||
app = packageInfoWithPartition(PARTITION_OEM);
|
app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
|
||||||
|
new String[] {}, PARTITION_OEM);
|
||||||
assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
||||||
app = packageInfoWithPartition(PARTITION_PRODUCT);
|
app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
|
||||||
|
new String[] {}, PARTITION_PRODUCT);
|
||||||
assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
||||||
app = packageInfoWithPartition(PARTITION_VENDOR);
|
app = vendorPackageInfoWithPermissions();
|
||||||
assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasNetworkPermission() {
|
||||||
|
PackageInfo app = systemPackageInfoWithPermissions();
|
||||||
|
assertFalse(mPermissionMonitor.hasNetworkPermission(app));
|
||||||
|
app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
|
||||||
|
assertTrue(mPermissionMonitor.hasNetworkPermission(app));
|
||||||
|
app = systemPackageInfoWithPermissions(NETWORK_STACK);
|
||||||
|
assertFalse(mPermissionMonitor.hasNetworkPermission(app));
|
||||||
|
app = systemPackageInfoWithPermissions(CONNECTIVITY_USE_RESTRICTED_NETWORKS);
|
||||||
|
assertFalse(mPermissionMonitor.hasNetworkPermission(app));
|
||||||
|
app = systemPackageInfoWithPermissions(CONNECTIVITY_INTERNAL);
|
||||||
|
assertFalse(mPermissionMonitor.hasNetworkPermission(app));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHasRestrictedNetworkPermission() {
|
public void testHasRestrictedNetworkPermission() {
|
||||||
assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
|
assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
|
||||||
@@ -288,27 +323,30 @@ public class PermissionMonitorTest {
|
|||||||
private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
|
private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
|
||||||
String... permissions) throws Exception {
|
String... permissions) throws Exception {
|
||||||
when(mPackageManager.getPackageInfo(eq(name), anyInt()))
|
when(mPackageManager.getPackageInfo(eq(name), anyInt()))
|
||||||
.thenReturn(buildPackageInfo(PARTITION_SYSTEM, uid, MOCK_USER1));
|
.thenReturn(packageInfoWithPermissions(
|
||||||
addPermissions(uid, permissions);
|
REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM));
|
||||||
mPermissionMonitor.onPackageAdded(name, uid);
|
mPermissionMonitor.onPackageAdded(name, uid);
|
||||||
assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
|
assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHasUseBackgroundNetworksPermission() throws Exception {
|
public void testHasUseBackgroundNetworksPermission() throws Exception {
|
||||||
doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
|
|
||||||
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
|
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
|
||||||
assertBackgroundPermission(false, "system1", SYSTEM_UID);
|
assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID);
|
||||||
assertBackgroundPermission(false, "system2", SYSTEM_UID, CONNECTIVITY_INTERNAL);
|
assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL);
|
||||||
assertBackgroundPermission(true, "system3", SYSTEM_UID, CHANGE_NETWORK_STATE);
|
assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE);
|
||||||
|
assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK);
|
||||||
|
|
||||||
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
|
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
|
||||||
assertBackgroundPermission(false, "mock1", MOCK_UID1);
|
assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID1);
|
||||||
assertBackgroundPermission(true, "mock2", MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
|
assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID1,
|
||||||
|
CONNECTIVITY_USE_RESTRICTED_NETWORKS);
|
||||||
|
|
||||||
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
|
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
|
||||||
assertBackgroundPermission(false, "mock3", MOCK_UID2, CONNECTIVITY_INTERNAL);
|
assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2);
|
||||||
assertBackgroundPermission(true, "mock4", MOCK_UID2, NETWORK_STACK);
|
assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2,
|
||||||
|
CONNECTIVITY_INTERNAL);
|
||||||
|
assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2, NETWORK_STACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NetdMonitor {
|
private class NetdMonitor {
|
||||||
@@ -378,14 +416,13 @@ public class PermissionMonitorTest {
|
|||||||
// MOCK_UID1: MOCK_PACKAGE1 only has network permission.
|
// MOCK_UID1: MOCK_PACKAGE1 only has network permission.
|
||||||
// SYSTEM_UID: SYSTEM_PACKAGE1 has system permission.
|
// SYSTEM_UID: SYSTEM_PACKAGE1 has system permission.
|
||||||
// SYSTEM_UID: SYSTEM_PACKAGE2 only has network permission.
|
// SYSTEM_UID: SYSTEM_PACKAGE2 only has network permission.
|
||||||
doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(eq(SYSTEM),
|
doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(eq(SYSTEM), anyString());
|
||||||
anyString(), anyInt());
|
|
||||||
doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(any(),
|
doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(any(),
|
||||||
eq(SYSTEM_PACKAGE1), anyInt());
|
eq(SYSTEM_PACKAGE1));
|
||||||
doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
|
doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
|
||||||
eq(SYSTEM_PACKAGE2), anyInt());
|
eq(SYSTEM_PACKAGE2));
|
||||||
doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
|
doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
|
||||||
eq(MOCK_PACKAGE1), anyInt());
|
eq(MOCK_PACKAGE1));
|
||||||
|
|
||||||
// Add SYSTEM_PACKAGE2, expect only have network permission.
|
// Add SYSTEM_PACKAGE2, expect only have network permission.
|
||||||
mPermissionMonitor.onUserAdded(MOCK_USER1);
|
mPermissionMonitor.onUserAdded(MOCK_USER1);
|
||||||
@@ -436,15 +473,13 @@ public class PermissionMonitorTest {
|
|||||||
public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception {
|
public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception {
|
||||||
when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
|
when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
|
||||||
Arrays.asList(new PackageInfo[] {
|
Arrays.asList(new PackageInfo[] {
|
||||||
buildPackageInfo(PARTITION_SYSTEM, SYSTEM_UID1, MOCK_USER1),
|
buildPackageInfo(/* SYSTEM */ true, SYSTEM_UID1, MOCK_USER1),
|
||||||
buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1),
|
buildPackageInfo(/* SYSTEM */ false, MOCK_UID1, MOCK_USER1),
|
||||||
buildPackageInfo(PARTITION_SYSTEM, MOCK_UID2, MOCK_USER1),
|
buildPackageInfo(/* SYSTEM */ false, MOCK_UID2, MOCK_USER1),
|
||||||
buildPackageInfo(PARTITION_SYSTEM, VPN_UID, MOCK_USER1)
|
buildPackageInfo(/* SYSTEM */ false, VPN_UID, MOCK_USER1)
|
||||||
}));
|
}));
|
||||||
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
|
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
|
||||||
buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1));
|
buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
|
||||||
addPermissions(SYSTEM_UID,
|
|
||||||
CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
|
|
||||||
mPermissionMonitor.startMonitoring();
|
mPermissionMonitor.startMonitoring();
|
||||||
// Every app on user 0 except MOCK_UID2 are under VPN.
|
// Every app on user 0 except MOCK_UID2 are under VPN.
|
||||||
final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] {
|
final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] {
|
||||||
@@ -489,11 +524,11 @@ public class PermissionMonitorTest {
|
|||||||
public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception {
|
public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception {
|
||||||
when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
|
when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
|
||||||
Arrays.asList(new PackageInfo[] {
|
Arrays.asList(new PackageInfo[] {
|
||||||
buildPackageInfo(PARTITION_SYSTEM, SYSTEM_UID1, MOCK_USER1),
|
buildPackageInfo(true, SYSTEM_UID1, MOCK_USER1),
|
||||||
buildPackageInfo(PARTITION_SYSTEM, VPN_UID, MOCK_USER1)
|
buildPackageInfo(false, VPN_UID, MOCK_USER1)
|
||||||
}));
|
}));
|
||||||
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
|
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
|
||||||
buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1));
|
buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
|
||||||
|
|
||||||
mPermissionMonitor.startMonitoring();
|
mPermissionMonitor.startMonitoring();
|
||||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1));
|
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1));
|
||||||
@@ -598,10 +633,10 @@ public class PermissionMonitorTest {
|
|||||||
|
|
||||||
private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
|
private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
final PackageInfo packageInfo = buildPackageInfo(PARTITION_SYSTEM, uid, MOCK_USER1);
|
PackageInfo packageInfo = packageInfoWithPermissions(
|
||||||
|
REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
|
||||||
when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo);
|
when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo);
|
||||||
when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName});
|
when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName});
|
||||||
addPermissions(uid, permissions);
|
|
||||||
return packageInfo;
|
return packageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,13 +663,14 @@ public class PermissionMonitorTest {
|
|||||||
public void testPackageInstallSharedUid() throws Exception {
|
public void testPackageInstallSharedUid() throws Exception {
|
||||||
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
|
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
|
||||||
|
|
||||||
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
|
PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1,
|
||||||
|
new String[] {INTERNET, UPDATE_DEVICE_STATS});
|
||||||
mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
|
mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
|
||||||
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
|
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
|
||||||
|
|
||||||
// Install another package with the same uid and no permissions should not cause the UID to
|
// Install another package with the same uid and no permissions should not cause the UID to
|
||||||
// lose permissions.
|
// lose permissions.
|
||||||
final PackageInfo packageInfo2 = buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1);
|
PackageInfo packageInfo2 = systemPackageInfoWithPermissions();
|
||||||
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
|
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
|
||||||
when(mPackageManager.getPackagesForUid(MOCK_UID1))
|
when(mPackageManager.getPackagesForUid(MOCK_UID1))
|
||||||
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
|
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
|
||||||
@@ -665,7 +701,6 @@ public class PermissionMonitorTest {
|
|||||||
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
|
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
|
||||||
|
|
||||||
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
|
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
|
||||||
removeAllPermissions(MOCK_UID1);
|
|
||||||
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
|
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
|
||||||
mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
|
mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
|
||||||
|
|
||||||
@@ -693,12 +728,10 @@ public class PermissionMonitorTest {
|
|||||||
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
|
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
|
||||||
|
|
||||||
// Mock another package with the same uid but different permissions.
|
// Mock another package with the same uid but different permissions.
|
||||||
final PackageInfo packageInfo2 = buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1);
|
PackageInfo packageInfo2 = systemPackageInfoWithPermissions(INTERNET);
|
||||||
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
|
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
|
||||||
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{
|
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{
|
||||||
MOCK_PACKAGE2});
|
MOCK_PACKAGE2});
|
||||||
removeAllPermissions(MOCK_UID1);
|
|
||||||
addPermissions(MOCK_UID1, INTERNET);
|
|
||||||
|
|
||||||
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
|
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
|
||||||
mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
|
mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
|
||||||
@@ -710,6 +743,9 @@ public class PermissionMonitorTest {
|
|||||||
// necessary permission.
|
// necessary permission.
|
||||||
final Context realContext = InstrumentationRegistry.getContext();
|
final Context realContext = InstrumentationRegistry.getContext();
|
||||||
final PermissionMonitor monitor = new PermissionMonitor(realContext, mNetdService);
|
final PermissionMonitor monitor = new PermissionMonitor(realContext, mNetdService);
|
||||||
assertTrue(monitor.hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, SYSTEM_UID));
|
final PackageManager manager = realContext.getPackageManager();
|
||||||
|
final PackageInfo systemInfo = manager.getPackageInfo(REAL_SYSTEM_PACKAGE_NAME,
|
||||||
|
GET_PERMISSIONS | MATCH_ANY_USER);
|
||||||
|
assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user