Fix the INTERNET related permissions

Change the INTERNET permission implementation so it only block socket
creation when non of the packages under the same uid have internet
permission. Fix the UPDATE_DEVICE_STATS permission so only the uid that
own the permission can change it.

Bug: 111560570
Test: CtsNetTestCasesUpdateStatsPermission
      CtsNetTestCasesInternetPermission
Change-Id: I42385526c191d4429f486cde01293b27fcc1374b
This commit is contained in:
Chenbo Feng
2019-03-08 11:55:12 -08:00
parent 67cfb00800
commit 0c4742527b

View File

@@ -22,6 +22,7 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.INTERNET;
import static android.Manifest.permission.NETWORK_STACK;
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.MATCH_ANY_USER;
import static android.os.Process.INVALID_UID;
@@ -43,7 +44,6 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import android.util.Slog;
import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -83,41 +83,32 @@ public class PermissionMonitor {
private final Map<Integer, Boolean> mApps = new HashMap<>();
private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
@Override
public void onPackageAdded(String packageName, int uid) {
final PackageInfo app = getPackageInfo(packageName);
if (app == null) {
Slog.wtf(TAG, "Failed to get information of installed package: " + packageName);
return;
}
if (uid == INVALID_UID) {
Slog.wtf(TAG, "Failed to get the uid of installed package: " + packageName
+ "uid: " + uid);
return;
}
if (app.requestedPermissions == null) {
return;
}
sendPackagePermissionsForUid(uid,
getNetdPermissionMask(app.requestedPermissions));
}
@Override
public void onPackageRemoved(String packageName, int uid) {
private int getPermissionForUid(int uid) {
int permission = 0;
// If there are still packages remain under the same uid, check the permission of the
// remaining packages. We only remove the permission for a given uid when all packages
// for that uid no longer have that permission.
// Check all the packages for this UID. The UID has the permission if any of the
// packages in it has the permission.
String[] packages = mPackageManager.getPackagesForUid(uid);
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);
permission |= getNetdPermissionMask(app.requestedPermissions,
app.requestedPermissionsFlags);
}
}
}
sendPackagePermissionsForUid(uid, permission);
return permission;
}
@Override
public void onPackageAdded(String packageName, int uid) {
sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
}
@Override
public void onPackageRemoved(String packageName, int uid) {
sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
}
}
@@ -167,12 +158,9 @@ public class PermissionMonitor {
}
//TODO: unify the management of the permissions into one codepath.
if (app.requestedPermissions != null) {
int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions);
if (otherNetdPerms != 0) {
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
}
}
int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
app.requestedPermissionsFlags);
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
}
List<UserInfo> users = mUserManager.getUsers(true); // exclude dying users
@@ -403,13 +391,17 @@ public class PermissionMonitor {
}
}
private static int getNetdPermissionMask(String[] requestedPermissions) {
private static int getNetdPermissionMask(String[] requestedPermissions,
int[] requestedPermissionsFlags) {
int permissions = 0;
for (String permissionName : requestedPermissions) {
if (permissionName.equals(INTERNET)) {
if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
for (int i = 0; i < requestedPermissions.length; i++) {
if (requestedPermissions[i].equals(INTERNET)
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
permissions |= INetd.PERMISSION_INTERNET;
}
if (permissionName.equals(UPDATE_DEVICE_STATS)) {
if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
}
}