Skip to content

Commit b7583ae

Browse files
Adnan BegovicGerrit Code Review
authored andcommitted
am: Handle unchecked activity starts for protected components.
Previously if you received a notification from a protected app, since AM would state that the calling package was also the target package, the protected apps implementation would allow you to launch into the application. Mitigate this by hooking into the unchecked activity start stack (pending intent launches) globally. Change-Id: I0371593ade9e4af2554962873d89a0f82a639b57 TICKET: PAELLA-216 FEIJ-160 FEIJ-177
1 parent 2da425e commit b7583ae

6 files changed

Lines changed: 55 additions & 10 deletions

File tree

core/java/android/app/ApplicationPackageManager.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,9 +2048,11 @@ public void setComponentProtectedSetting(ComponentName componentName, boolean ne
20482048

20492049
/** @hide */
20502050
@Override
2051-
public boolean isComponentProtected(String callingPackage, ComponentName componentName) {
2051+
public boolean isComponentProtected(String callingPackage, int callingUid,
2052+
ComponentName componentName) {
20522053
try {
2053-
return mPM.isComponentProtected(callingPackage, componentName, mContext.getUserId());
2054+
return mPM.isComponentProtected(callingPackage, callingUid, componentName,
2055+
mContext.getUserId());
20542056
} catch (RemoteException re) {
20552057
Log.e(TAG, "Failed to get component protected setting", re);
20562058
return false;

core/java/android/content/pm/IPackageManager.aidl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,6 @@ interface IPackageManager {
521521
int processThemeResources(String themePkgName);
522522

523523
/** Protected Apps */
524-
boolean isComponentProtected(in String callingPackage, in ComponentName componentName,
525-
int userId);
524+
boolean isComponentProtected(in String callingPackage, in int callingUid,
525+
in ComponentName componentName, int userId);
526526
}

core/java/android/content/pm/PackageManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4564,7 +4564,7 @@ public void onCreated(int moveId, Bundle extras) {}
45644564
* Return whether or not a specific component is protected
45654565
* @hide
45664566
*/
4567-
public abstract boolean isComponentProtected(String callingPackage,
4567+
public abstract boolean isComponentProtected(String callingPackage, int callingUid,
45684568
ComponentName componentName);
45694569

45704570
/**

services/core/java/com/android/server/am/ActivityStackSupervisor.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,8 @@ final int startActivityMayWait(IApplicationThread caller, int callingUid,
961961
//TODO: This needs to be a flushed out API in the future.
962962
boolean isProtected = intent.getComponent() != null
963963
&& AppGlobals.getPackageManager()
964-
.isComponentProtected(callingPackage, intent.getComponent(), userId) &&
964+
.isComponentProtected(callingPackage, callingUid,
965+
intent.getComponent(), userId) &&
965966
(intent.getFlags()&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
966967

967968
if (isProtected) {
@@ -977,6 +978,7 @@ final int startActivityMayWait(IApplicationThread caller, int callingUid,
977978
} catch (RemoteException e) {
978979
e.printStackTrace();
979980
}
981+
980982
final int realCallingPid = Binder.getCallingPid();
981983
final int realCallingUid = Binder.getCallingUid();
982984
int callingPid;
@@ -1873,6 +1875,28 @@ final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord so
18731875
inTask = null;
18741876
}
18751877

1878+
try {
1879+
//TODO: This needs to be a flushed out API in the future.
1880+
boolean isProtected = intent.getComponent() != null
1881+
&& AppGlobals.getPackageManager()
1882+
.isComponentProtected(null, r.launchedFromUid,
1883+
intent.getComponent(), r.userId) &&
1884+
(intent.getFlags()&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
1885+
1886+
if (isProtected) {
1887+
Message msg = mService.mHandler.obtainMessage(
1888+
ActivityManagerService.POST_COMPONENT_PROTECTED_MSG);
1889+
//Store start flags, userid
1890+
intent.setFlags(startFlags);
1891+
intent.putExtra("com.android.settings.PROTECTED_APPS_USER_ID", r.userId);
1892+
msg.obj = intent;
1893+
mService.mHandler.sendMessage(msg);
1894+
return ActivityManager.START_NOT_CURRENT_USER_ACTIVITY;
1895+
}
1896+
} catch (RemoteException e) {
1897+
e.printStackTrace();
1898+
}
1899+
18761900
final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
18771901
final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
18781902
final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;

services/core/java/com/android/server/pm/PackageManagerService.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17265,10 +17265,12 @@ public void setComponentProtectedSetting(ComponentName componentName, boolean ne
1726517265
}
1726617266

1726717267
@Override
17268-
public boolean isComponentProtected(String callingPackage,
17268+
public boolean isComponentProtected(String callingPackage, int callingUid,
1726917269
ComponentName componentName, int userId) {
1727017270
if (DEBUG_PROTECTED) Log.d(TAG, "Checking if component is protected "
17271-
+ componentName.flattenToShortString() + " from calling package " + callingPackage);
17271+
+ componentName.flattenToShortString() + " from calling package " + callingPackage
17272+
+ " and callinguid " + callingUid);
17273+
1727217274
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "set protected");
1727317275

1727417276
//Allow managers full access
@@ -17289,8 +17291,24 @@ public boolean isComponentProtected(String callingPackage,
1728917291
return false;
1729017292
}
1729117293

17294+
//If this component is launched from a validation component, allow it.
1729217295
if (TextUtils.equals(PROTECTED_APPS_TARGET_VALIDATION_COMPONENT,
17293-
componentName.flattenToString())) {
17296+
componentName.flattenToString()) && callingUid == Process.SYSTEM_UID) {
17297+
return false;
17298+
}
17299+
17300+
//If this component is launched from the system or a uid of a protected component, allow it.
17301+
boolean fromProtectedComponentUid = false;
17302+
for (String protectedComponentManager : protectedComponentManagers) {
17303+
if (callingUid == getPackageUid(protectedComponentManager, userId)) {
17304+
fromProtectedComponentUid = true;
17305+
}
17306+
}
17307+
17308+
if (callingPackage == null && (callingUid == Process.SYSTEM_UID
17309+
|| fromProtectedComponentUid)) {
17310+
if (DEBUG_PROTECTED) Log.d(TAG, "Calling package is android and from system or " +
17311+
"protected manager, allow");
1729417312
return false;
1729517313
}
1729617314

test-runner/src/android/test/mock/MockPackageManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,8 @@ public void setComponentProtectedSetting(ComponentName componentName, boolean ne
904904
* @hide
905905
*/
906906
@Override
907-
public boolean isComponentProtected(String callingPackage, ComponentName componentName) {
907+
public boolean isComponentProtected(String callingPackage, int callingUid,
908+
ComponentName componentName) {
908909
throw new UnsupportedOperationException();
909910
}
910911

0 commit comments

Comments
 (0)