Merge "Fix privilege escalation for preferred activities"
This commit is contained in:
@@ -51,6 +51,22 @@ import java.util.HashMap;
|
|||||||
public final class DeviceAdminInfo implements Parcelable {
|
public final class DeviceAdminInfo implements Parcelable {
|
||||||
static final String TAG = "DeviceAdminInfo";
|
static final String TAG = "DeviceAdminInfo";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of policy that this device admin can use: device owner meta-policy
|
||||||
|
* for an admin that is designated as owner of the device.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int USES_POLICY_DEVICE_OWNER = -2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of policy that this device admin can use: profile owner meta-policy
|
||||||
|
* for admins that have been installed as owner of some user profile.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int USES_POLICY_PROFILE_OWNER = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type of policy that this device admin can use: limit the passwords
|
* A type of policy that this device admin can use: limit the passwords
|
||||||
* that the user can select, via {@link DevicePolicyManager#setPasswordQuality}
|
* that the user can select, via {@link DevicePolicyManager#setPasswordQuality}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
int mActivePasswordNonLetter = 0;
|
int mActivePasswordNonLetter = 0;
|
||||||
int mFailedPasswordAttempts = 0;
|
int mFailedPasswordAttempts = 0;
|
||||||
|
|
||||||
int mUserHandle;;
|
int mUserHandle;
|
||||||
int mPasswordOwner = -1;
|
int mPasswordOwner = -1;
|
||||||
long mLastMaximumTimeToLock = -1;
|
long mLastMaximumTimeToLock = -1;
|
||||||
|
|
||||||
@@ -722,6 +722,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
final int callingUid = Binder.getCallingUid();
|
final int callingUid = Binder.getCallingUid();
|
||||||
final int userHandle = UserHandle.getUserId(callingUid);
|
final int userHandle = UserHandle.getUserId(callingUid);
|
||||||
final DevicePolicyData policy = getUserData(userHandle);
|
final DevicePolicyData policy = getUserData(userHandle);
|
||||||
|
|
||||||
|
List<ActiveAdmin> candidates = new ArrayList<ActiveAdmin>();
|
||||||
|
|
||||||
|
// Build a list of admins for this uid matching the given ComponentName
|
||||||
if (who != null) {
|
if (who != null) {
|
||||||
ActiveAdmin admin = policy.mAdminMap.get(who);
|
ActiveAdmin admin = policy.mAdminMap.get(who);
|
||||||
if (admin == null) {
|
if (admin == null) {
|
||||||
@@ -731,22 +735,43 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
throw new SecurityException("Admin " + who + " is not owned by uid "
|
throw new SecurityException("Admin " + who + " is not owned by uid "
|
||||||
+ Binder.getCallingUid());
|
+ Binder.getCallingUid());
|
||||||
}
|
}
|
||||||
if (!admin.info.usesPolicy(reqPolicy)) {
|
candidates.add(admin);
|
||||||
throw new SecurityException("Admin " + admin.info.getComponent()
|
|
||||||
+ " did not specify uses-policy for: "
|
|
||||||
+ admin.info.getTagForPolicy(reqPolicy));
|
|
||||||
}
|
|
||||||
return admin;
|
|
||||||
} else {
|
} else {
|
||||||
final int N = policy.mAdminList.size();
|
for (ActiveAdmin admin : policy.mAdminList) {
|
||||||
for (int i=0; i<N; i++) {
|
if (admin.getUid() == callingUid) {
|
||||||
ActiveAdmin admin = policy.mAdminList.get(i);
|
candidates.add(admin);
|
||||||
if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find an admin which can use reqPolicy
|
||||||
|
for (ActiveAdmin admin : candidates) {
|
||||||
|
boolean ownsDevice = isDeviceOwner(admin.info.getPackageName());
|
||||||
|
boolean ownsProfile = (getProfileOwner(userHandle) != null
|
||||||
|
&& getProfileOwner(userHandle).equals(admin.info.getPackageName()));
|
||||||
|
|
||||||
|
if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
|
||||||
|
if (ownsDevice) {
|
||||||
|
return admin;
|
||||||
|
}
|
||||||
|
} else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
|
||||||
|
if (ownsDevice || ownsProfile) {
|
||||||
|
return admin;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (admin.info.usesPolicy(reqPolicy)) {
|
||||||
return admin;
|
return admin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (who != null) {
|
||||||
|
throw new SecurityException("Admin " + candidates.get(0).info.getComponent()
|
||||||
|
+ " did not specify uses-policy for: "
|
||||||
|
+ candidates.get(0).info.getTagForPolicy(reqPolicy));
|
||||||
|
} else {
|
||||||
throw new SecurityException("No active admin owned by uid "
|
throw new SecurityException("No active admin owned by uid "
|
||||||
+ Binder.getCallingUid() + " for policy #" + reqPolicy);
|
+ Binder.getCallingUid() + " for policy:" + reqPolicy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2966,64 +2991,41 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isProfileOwner(String packageName, int userId) {
|
public void addPersistentPreferredActivity(ComponentName who, IntentFilter filter,
|
||||||
String profileOwnerPackage = getProfileOwner(userId);
|
|
||||||
// TODO: make public and connect with isProfileOwnerApp in DPM
|
|
||||||
return profileOwnerPackage != null && profileOwnerPackage.equals(packageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPersistentPreferredActivity(ComponentName admin, IntentFilter filter,
|
|
||||||
ComponentName activity) {
|
ComponentName activity) {
|
||||||
int callingUserId = UserHandle.getCallingUserId();
|
|
||||||
Slog.d(LOG_TAG,"called by user " + callingUserId);
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
ActiveAdmin aa = getActiveAdminUncheckedLocked(admin, callingUserId);
|
if (who == null) {
|
||||||
if (aa == null) {
|
throw new NullPointerException("ComponentName is null");
|
||||||
throw new SecurityException("No active admin " + admin);
|
}
|
||||||
} else {
|
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
|
||||||
if (isProfileOwner(admin.getPackageName(), callingUserId)
|
|
||||||
|| isDeviceOwner(admin.getPackageName())) {
|
IPackageManager pm = AppGlobals.getPackageManager();
|
||||||
IPackageManager pm = AppGlobals.getPackageManager();
|
long id = Binder.clearCallingIdentity();
|
||||||
long id = Binder.clearCallingIdentity();
|
try {
|
||||||
try {
|
pm.addPersistentPreferredActivity(filter, activity, UserHandle.getCallingUserId());
|
||||||
pm.addPersistentPreferredActivity(filter, activity, callingUserId);
|
} catch (RemoteException re) {
|
||||||
} catch (RemoteException re) {
|
// Shouldn't happen
|
||||||
// Shouldn't happen
|
} finally {
|
||||||
} finally {
|
restoreCallingIdentity(id);
|
||||||
restoreCallingIdentity(id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new SecurityException("Admin " + admin +
|
|
||||||
"is not device owner or profile owner" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearPackagePersistentPreferredActivities(ComponentName admin,
|
public void clearPackagePersistentPreferredActivities(ComponentName who, String packageName) {
|
||||||
String packageName) {
|
|
||||||
int callingUserId = UserHandle.getCallingUserId();
|
|
||||||
Slog.d(LOG_TAG,"called by user " + callingUserId);
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
ActiveAdmin aa = getActiveAdminUncheckedLocked(admin, callingUserId);
|
if (who == null) {
|
||||||
if (aa == null) {
|
throw new NullPointerException("ComponentName is null");
|
||||||
throw new SecurityException("No active admin " + admin);
|
}
|
||||||
} else {
|
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
|
||||||
if (isProfileOwner(admin.getPackageName(), callingUserId)
|
|
||||||
|| isDeviceOwner(admin.getPackageName())) {
|
IPackageManager pm = AppGlobals.getPackageManager();
|
||||||
IPackageManager pm = AppGlobals.getPackageManager();
|
long id = Binder.clearCallingIdentity();
|
||||||
long id = Binder.clearCallingIdentity();
|
try {
|
||||||
try{
|
pm.clearPackagePersistentPreferredActivities(packageName, UserHandle.getCallingUserId());
|
||||||
pm.clearPackagePersistentPreferredActivities(packageName, callingUserId);
|
} catch (RemoteException re) {
|
||||||
} catch (RemoteException re) {
|
// Shouldn't happen
|
||||||
// Shouldn't happen
|
} finally {
|
||||||
} finally {
|
restoreCallingIdentity(id);
|
||||||
restoreCallingIdentity(id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new SecurityException("Admin " + admin +
|
|
||||||
"is not device owner or profile owner" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user