Skip to content

Commit 97ec9c6

Browse files
Taran SinghMegh-Rana
authored andcommitted
DO NOT MERGE: Prevent non-system IME from becoming device admin
Currently selected IME can inject KeyEvent on DeviceAdminAdd screen to activate itself as device admin and cause various DoS attacks. This CL ensures KeyEvent on "Activate" button can only come from system apps. Bug: 280793427 Test: atest DeviceAdminActivationTest (cherry picked from commit 70a501d) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0ee3b96e59f3e5699c919af3642130fb33cd263b) Merged-In: I6470d1684d707f4b1e86f8b456be0b4e0af5f188 Change-Id: I6470d1684d707f4b1e86f8b456be0b4e0af5f188
1 parent a243701 commit 97ec9c6

File tree

1 file changed

+64
-56
lines changed

1 file changed

+64
-56
lines changed

src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import android.util.EventLog;
5151
import android.util.Log;
5252
import android.view.Display;
53+
import android.view.KeyEvent;
54+
import android.view.LayoutInflater;
5355
import android.view.View;
5456
import android.view.ViewGroup;
5557
import android.view.ViewTreeObserver;
@@ -138,7 +140,7 @@ protected void onCreate(Bundle icicle) {
138140
mAppOps = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
139141
PackageManager packageManager = getPackageManager();
140142

141-
if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
143+
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
142144
Log.w(TAG, "Cannot start ADD_DEVICE_ADMIN as a new task");
143145
finish();
144146
return;
@@ -148,7 +150,7 @@ protected void onCreate(Bundle icicle) {
148150
EXTRA_CALLED_FROM_SUPPORT_DIALOG, false);
149151

150152
String action = getIntent().getAction();
151-
ComponentName who = (ComponentName)getIntent().getParcelableExtra(
153+
ComponentName who = (ComponentName) getIntent().getParcelableExtra(
152154
DevicePolicyManager.EXTRA_DEVICE_ADMIN);
153155
if (who == null) {
154156
String packageName = getIntent().getStringExtra(EXTRA_DEVICE_ADMIN_PACKAGE_NAME);
@@ -206,7 +208,7 @@ protected void onCreate(Bundle icicle) {
206208
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
207209
int count = avail == null ? 0 : avail.size();
208210
boolean found = false;
209-
for (int i=0; i<count; i++) {
211+
for (int i = 0; i < count; i++) {
210212
ResolveInfo ri = avail.get(i);
211213
if (ai.packageName.equals(ri.activityInfo.packageName)
212214
&& ai.name.equals(ri.activityInfo.name)) {
@@ -337,12 +339,12 @@ public void onDismiss(DialogInterface dialogInterface) {
337339
}
338340
setContentView(R.layout.device_admin_add);
339341

340-
mAdminIcon = (ImageView)findViewById(R.id.admin_icon);
341-
mAdminName = (TextView)findViewById(R.id.admin_name);
342-
mAdminDescription = (TextView)findViewById(R.id.admin_description);
342+
mAdminIcon = (ImageView) findViewById(R.id.admin_icon);
343+
mAdminName = (TextView) findViewById(R.id.admin_name);
344+
mAdminDescription = (TextView) findViewById(R.id.admin_description);
343345
mProfileOwnerWarning = (TextView) findViewById(R.id.profile_owner_warning);
344346

345-
mAddMsg = (TextView)findViewById(R.id.add_msg);
347+
mAddMsg = (TextView) findViewById(R.id.add_msg);
346348
mAddMsgExpander = (ImageView) findViewById(R.id.add_msg_expander);
347349
final View.OnClickListener onClickListener = new View.OnClickListener() {
348350
@Override
@@ -363,7 +365,7 @@ public void onGlobalLayout() {
363365
boolean hideMsgExpander = mAddMsg.getLineCount() <= maxLines;
364366
mAddMsgExpander.setVisibility(hideMsgExpander ? View.GONE : View.VISIBLE);
365367
if (hideMsgExpander) {
366-
((View)mAddMsgExpander.getParent()).invalidate();
368+
((View) mAddMsgExpander.getParent()).invalidate();
367369
}
368370
mAddMsg.getViewTreeObserver().removeOnGlobalLayoutListener(this);
369371
}
@@ -381,7 +383,7 @@ public void onGlobalLayout() {
381383
mCancelButton.setOnClickListener(new View.OnClickListener() {
382384
public void onClick(View v) {
383385
EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_DECLINED_BY_USER,
384-
mDeviceAdmin.getActivityInfo().applicationInfo.uid);
386+
mDeviceAdmin.getActivityInfo().applicationInfo.uid);
385387
finish();
386388
}
387389
});
@@ -401,58 +403,64 @@ public void onClick(View v) {
401403

402404
final View restrictedAction = findViewById(R.id.restricted_action);
403405
restrictedAction.setFilterTouchesWhenObscured(true);
404-
restrictedAction.setOnClickListener(new View.OnClickListener() {
405-
public void onClick(View v) {
406-
if (!mActionButton.isEnabled()) {
407-
showPolicyTransparencyDialogIfRequired();
408-
return;
409-
}
410-
if (mAdding) {
411-
addAndFinish();
412-
} else if (isManagedProfile(mDeviceAdmin)
413-
&& mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner())) {
414-
final int userId = UserHandle.myUserId();
415-
UserDialogs.createRemoveDialog(DeviceAdminAdd.this, userId,
416-
new DialogInterface.OnClickListener() {
417-
@Override
418-
public void onClick(DialogInterface dialog, int which) {
419-
UserManager um = UserManager.get(DeviceAdminAdd.this);
420-
um.removeUser(userId);
421-
finish();
422-
}
406+
407+
final View.OnClickListener restrictedActionClickListener = v -> {
408+
if (!mActionButton.isEnabled()) {
409+
showPolicyTransparencyDialogIfRequired();
410+
return;
411+
}
412+
if (mAdding) {
413+
addAndFinish();
414+
} else if (isManagedProfile(mDeviceAdmin)
415+
&& mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner())) {
416+
final int userId = UserHandle.myUserId();
417+
UserDialogs.createRemoveDialog(DeviceAdminAdd.this, userId,
418+
new DialogInterface.OnClickListener() {
419+
@Override
420+
public void onClick(DialogInterface dialog, int which) {
421+
UserManager um = UserManager.get(DeviceAdminAdd.this);
422+
um.removeUser(userId);
423+
finish();
423424
}
424-
).show();
425-
} else if (mUninstalling) {
426-
mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName());
427-
finish();
428-
} else if (!mWaitingForRemoveMsg) {
429-
try {
430-
// Don't allow the admin to put a dialog up in front
431-
// of us while we interact with the user.
432-
ActivityManager.getService().stopAppSwitches();
433-
} catch (RemoteException e) {
434-
}
435-
mWaitingForRemoveMsg = true;
436-
mDPM.getRemoveWarning(mDeviceAdmin.getComponent(),
437-
new RemoteCallback(new RemoteCallback.OnResultListener() {
438-
@Override
439-
public void onResult(Bundle result) {
440-
CharSequence msg = result != null
441-
? result.getCharSequence(
442-
DeviceAdminReceiver.EXTRA_DISABLE_WARNING)
443-
: null;
444-
continueRemoveAction(msg);
445-
}
446-
}, mHandler));
447-
// Don't want to wait too long.
448-
getWindow().getDecorView().getHandler().postDelayed(new Runnable() {
449-
@Override public void run() {
450-
continueRemoveAction(null);
451425
}
452-
}, 2*1000);
426+
).show();
427+
} else if (mUninstalling) {
428+
mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName());
429+
finish();
430+
} else if (!mWaitingForRemoveMsg) {
431+
try {
432+
// Don't allow the admin to put a dialog up in front
433+
// of us while we interact with the user.
434+
ActivityManager.getService().stopAppSwitches();
435+
} catch (RemoteException e) {
453436
}
437+
mWaitingForRemoveMsg = true;
438+
mDPM.getRemoveWarning(mDeviceAdmin.getComponent(),
439+
new RemoteCallback(new RemoteCallback.OnResultListener() {
440+
@Override
441+
public void onResult(Bundle result) {
442+
CharSequence msg = result != null
443+
? result.getCharSequence(
444+
DeviceAdminReceiver.EXTRA_DISABLE_WARNING)
445+
: null;
446+
continueRemoveAction(msg);
447+
}
448+
}, mHandler));
449+
// Don't want to wait too long.
450+
getWindow().getDecorView().getHandler().postDelayed(
451+
() -> continueRemoveAction(null), 2 * 1000);
452+
}
453+
};
454+
restrictedAction.setOnKeyListener((view, keyCode, keyEvent) -> {
455+
if ((keyEvent.getFlags() & KeyEvent.FLAG_FROM_SYSTEM) == 0) {
456+
Log.e(TAG, "Can not activate device-admin with KeyEvent from non-system app.");
457+
// Consume event to suppress click.
458+
return true;
454459
}
460+
// Fallback to view click handler.
461+
return false;
455462
});
463+
restrictedAction.setOnClickListener(restrictedActionClickListener);
456464
}
457465

458466
/**

0 commit comments

Comments
 (0)