From 854060af30f928c0a65591e9c8314ae17056e6b8 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 9 Jul 2009 18:14:31 -0700 Subject: Fix bug #1873249i: Apps can DoS/brick device This is the problem where various things are listening for broadcasts (such as battery status, PIN/PUK/Network) that an application can send to cause harm to the system. Solving this is tricky because many of these broadcasts are sticky, and I have never figured out how to do permissions with sticky broadcasts in a sane way. So instead, I am going to punt on the general problem and just brute force it: There is new a way for system components to declare specific broadcast actions to be protected, which means that only the system and the phone can send them. This is good enough for now. None of it is exposed in the public API so we can make something a little less stupid in the future if we ever need to. --- .../android/server/am/ActivityManagerService.java | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'services/java/com/android/server/am') diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index aad542a..134ab80 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -10832,6 +10832,29 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); } + /* + * Prevent non-system code (defined here to be non-persistent + * processes) from sending protected broadcasts. + */ + if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID + || callingUid == Process.SHELL_UID || callingUid == 0) { + // Always okay. + } else if (callerApp == null || !callerApp.persistent) { + try { + if (ActivityThread.getPackageManager().isProtectedBroadcast( + intent.getAction())) { + String msg = "Permission Denial: not allowed to send broadcast " + + intent.getAction() + " from pid=" + + callingPid + ", uid=" + callingUid; + Log.w(TAG, msg); + throw new SecurityException(msg); + } + } catch (RemoteException e) { + Log.w(TAG, "Remote exception", e); + return BROADCAST_SUCCESS; + } + } + // Add to the sticky list if requested. if (sticky) { if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, -- cgit v1.1