From 5df725a9834ae0a5d313f070543736923afa8f8c Mon Sep 17 00:00:00 2001 From: Da Xing Date: Sun, 18 Nov 2018 20:10:17 +0800 Subject: [PATCH] DO NOT MERGE Crash app on foreground service notification error. Resolved issue 118612296. On any notification error, the NMS silently cancels the notification, including foreground service notifications. Thus, an app could pass in a garbage notification deliberately and start a foreground service silently. This patch resolved this issue by judging the notification's flag, and if it is a foreground notification, still crash the app as previous platforms, and if it is a normal notification, don't crash the app. Background: In 3ad4cdd1, which was merged into Android 9 release, the crash behaviour is removed. But it is an important rule that foreground services guaranteed to show an ongoing notification. Test: Run the sample apk provided in the issue, it's main thread received a RemoteServiceException: Bad notification posted from package... as intended behaviour. Change-Id: I36ea0137ca6978ff401f64dccacb6f2edcadd7db Merged-In: I36ea0137ca6978ff401f64dccacb6f2edcadd7db Signed-off-by: Da Xing --- .../NotificationManagerService.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 0188f7c8bfaa4..b241a67a6b2da 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -795,8 +795,22 @@ public class NotificationManagerService extends SystemService { @Override public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id, int uid, int initialPid, String message, int userId) { - cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId, - REASON_ERROR, null); + final boolean fgService; + synchronized (mNotificationLock) { + NotificationRecord r = findNotificationLocked(pkg, tag, id, userId); + fgService = r != null && (r.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0; + } + cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, + false, userId, REASON_ERROR, null); + if (fgService) { + // Still crash for foreground services, preventing the not-crash behaviour abused + // by apps to give us a garbage notification and silently start a fg service. + Binder.withCleanCallingIdentity( + () -> mAm.crashApplication(uid, initialPid, pkg, -1, + "Bad notification(tag=" + tag + ", id=" + id + ") posted from package " + + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): " + + message)); + } } @Override