Merge "audio policy: add permission check for privileged attributes flags" into qt-dev

gugelfrei
Eric Laurent 5 years ago committed by Android (Google) Code Review
commit 68f7b18e8e

@ -864,7 +864,7 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream)
return aps->getOutput(stream);
}
status_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
status_t AudioSystem::getOutputForAttr(audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,

@ -198,7 +198,7 @@ public:
return static_cast <audio_io_handle_t> (reply.readInt32());
}
status_t getOutputForAttr(const audio_attributes_t *attr,
status_t getOutputForAttr(audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
@ -212,38 +212,27 @@ public:
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
if (attr == NULL) {
if (stream == NULL) {
ALOGE("getOutputForAttr(): NULL audio attributes and stream type");
return BAD_VALUE;
}
if (*stream == AUDIO_STREAM_DEFAULT) {
ALOGE("getOutputForAttr unspecified stream type");
return BAD_VALUE;
}
}
if (output == NULL) {
ALOGE("getOutputForAttr NULL output - shouldn't happen");
if (attr == nullptr) {
ALOGE("%s NULL audio attributes", __func__);
return BAD_VALUE;
}
if (selectedDeviceId == NULL) {
ALOGE("getOutputForAttr NULL selectedDeviceId - shouldn't happen");
if (output == nullptr) {
ALOGE("%s NULL output - shouldn't happen", __func__);
return BAD_VALUE;
}
if (portId == NULL) {
ALOGE("getOutputForAttr NULL portId - shouldn't happen");
if (selectedDeviceId == nullptr) {
ALOGE("%s NULL selectedDeviceId - shouldn't happen", __func__);
return BAD_VALUE;
}
if (secondaryOutputs == NULL) {
ALOGE("getOutputForAttr NULL secondaryOutputs - shouldn't happen");
if (portId == nullptr) {
ALOGE("%s NULL portId - shouldn't happen", __func__);
return BAD_VALUE;
}
if (attr == NULL) {
data.writeInt32(0);
} else {
data.writeInt32(1);
data.write(attr, sizeof(audio_attributes_t));
if (secondaryOutputs == nullptr) {
ALOGE("%s NULL secondaryOutputs - shouldn't happen", __func__);
return BAD_VALUE;
}
data.write(attr, sizeof(audio_attributes_t));
data.writeInt32(session);
if (stream == NULL) {
data.writeInt32(0);
@ -265,6 +254,10 @@ public:
if (status != NO_ERROR) {
return status;
}
status = (status_t)reply.read(&attr, sizeof(audio_attributes_t));
if (status != NO_ERROR) {
return status;
}
*output = (audio_io_handle_t)reply.readInt32();
audio_stream_type_t lStream = (audio_stream_type_t)reply.readInt32();
if (stream != NULL) {
@ -1449,12 +1442,12 @@ status_t BnAudioPolicyService::onTransact(
case GET_OUTPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_attributes_t attr = {};
bool hasAttributes = data.readInt32() != 0;
if (hasAttributes) {
data.read(&attr, sizeof(audio_attributes_t));
sanetizeAudioAttributes(&attr);
audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
status_t status = data.read(&attr, sizeof(audio_attributes_t));
if (status != NO_ERROR) {
return status;
}
sanetizeAudioAttributes(&attr);
audio_session_t session = (audio_session_t)data.readInt32();
audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
bool hasStream = data.readInt32() != 0;
@ -1472,11 +1465,15 @@ status_t BnAudioPolicyService::onTransact(
audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
audio_io_handle_t output = 0;
std::vector<audio_io_handle_t> secondaryOutputs;
status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
status = getOutputForAttr(&attr,
&output, session, &stream, pid, uid,
&config,
flags, &selectedDeviceId, &portId, &secondaryOutputs);
reply->writeInt32(status);
status = reply->write(&attr, sizeof(audio_attributes_t));
if (status != NO_ERROR) {
return status;
}
reply->writeInt32(output);
reply->writeInt32(stream);
reply->writeInt32(selectedDeviceId);

@ -223,7 +223,7 @@ public:
static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
static status_t getOutputForAttr(const audio_attributes_t *attr,
static status_t getOutputForAttr(audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,

@ -57,7 +57,7 @@ public:
audio_policy_forced_cfg_t config) = 0;
virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) = 0;
virtual audio_io_handle_t getOutput(audio_stream_type_t stream) = 0;
virtual status_t getOutputForAttr(const audio_attributes_t *attr,
virtual status_t getOutputForAttr(audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,

@ -35,6 +35,8 @@
namespace android {
static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO");
static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
static const String16 sModifyAudioRouting("android.permission.MODIFY_AUDIO_ROUTING");
static String16 resolveCallingPackage(PermissionController& permissionController,
const String16& opPackageName, uid_t uid) {
@ -162,9 +164,8 @@ bool settingsAllowed() {
}
bool modifyAudioRoutingAllowed() {
static const String16 sModifyAudioRoutingAllowed("android.permission.MODIFY_AUDIO_ROUTING");
// IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
bool ok = PermissionCache::checkCallingPermission(sModifyAudioRoutingAllowed);
bool ok = PermissionCache::checkCallingPermission(sModifyAudioRouting);
if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING");
return ok;
}
@ -200,9 +201,19 @@ bool dumpAllowed() {
}
bool modifyPhoneStateAllowed(pid_t pid, uid_t uid) {
static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid);
if (!ok) ALOGE("Request requires android.permission.MODIFY_PHONE_STATE");
ALOGE_IF(!ok, "Request requires %s", String8(sModifyPhoneState).c_str());
return ok;
}
// privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) {
static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid)
|| PermissionCache::checkPermission(sWriteSecureSettings, pid, uid)
|| PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
ALOGE_IF(!ok, "Request requires %s or %s",
String8(sModifyPhoneState).c_str(), String8(sWriteSecureSettings).c_str());
return ok;
}

@ -81,6 +81,8 @@ bool modifyAudioRoutingAllowed();
bool modifyDefaultAudioEffectsAllowed();
bool dumpAllowed();
bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid);
status_t checkIMemory(const sp<IMemory>& iMemory);
class MediaPackageManager {

@ -296,13 +296,15 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
audio_attributes_t localAttr = *attr;
if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER;
fullConfig.sample_rate = config->sample_rate;
fullConfig.channel_mask = config->channel_mask;
fullConfig.format = config->format;
std::vector<audio_io_handle_t> secondaryOutputs;
ret = AudioSystem::getOutputForAttr(attr, &io,
ret = AudioSystem::getOutputForAttr(&localAttr, &io,
actualSessionId,
&streamType, client.clientPid, client.clientUid,
&fullConfig,
@ -312,7 +314,7 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
ALOGW_IF(!secondaryOutputs.empty(),
"%s does not support secondary outputs, ignoring them", __func__);
} else {
ret = AudioSystem::getInputForAttr(attr, &io,
ret = AudioSystem::getInputForAttr(&localAttr, &io,
RECORD_RIID_INVALID,
actualSessionId,
client.clientPid,
@ -330,7 +332,7 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
sp<MmapThread> thread = mMmapThreads.valueFor(io);
if (thread != 0) {
interface = new MmapThreadHandle(thread);
thread->configure(attr, streamType, actualSessionId, callback, *deviceId, portId);
thread->configure(&localAttr, streamType, actualSessionId, callback, *deviceId, portId);
*handle = portId;
*sessionId = actualSessionId;
} else {
@ -691,7 +693,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input,
uid_t clientUid = input.clientInfo.clientUid;
audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE;
std::vector<int> effectIds;
audio_attributes_t localAttr = input.attr;
if (!isAudioServerOrMediaServerUid(callingUid)) {
ALOGW_IF(clientUid != callingUid,
@ -720,8 +722,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input,
output.sessionId = sessionId;
output.outputId = AUDIO_IO_HANDLE_NONE;
output.selectedDeviceId = input.selectedDeviceId;
lStatus = AudioSystem::getOutputForAttr(&input.attr, &output.outputId, sessionId, &streamType,
lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType,
clientPid, clientUid, &input.config, input.flags,
&output.selectedDeviceId, &portId, &secondaryOutputs);
@ -782,7 +783,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input,
output.notificationFrameCount = input.notificationFrameCount;
output.flags = input.flags;
track = thread->createTrack_l(client, streamType, input.attr, &output.sampleRate,
track = thread->createTrack_l(client, streamType, localAttr, &output.sampleRate,
input.config.format, input.config.channel_mask,
&output.frameCount, &output.notificationFrameCount,
input.notificationsPerBuffer, input.speed,

@ -1019,7 +1019,7 @@ status_t AudioPolicyManager::getOutputForAttrInt(
}
if (*output == AUDIO_IO_HANDLE_NONE) {
*output = getOutputForDevices(outputDevices, session, *stream, config,
flags, attr->flags & AUDIO_FLAG_MUTE_HAPTIC);
flags, resultAttr->flags & AUDIO_FLAG_MUTE_HAPTIC);
}
if (*output == AUDIO_IO_HANDLE_NONE) {
return INVALID_OPERATION;

@ -166,7 +166,7 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream)
return mAudioPolicyManager->getOutput(stream);
}
status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *originalAttr,
status_t AudioPolicyService::getOutputForAttr(audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
@ -190,13 +190,15 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *original
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
uid = callingUid;
}
audio_attributes_t attr = *originalAttr;
if (!mPackageManager.allowPlaybackCapture(uid)) {
attr.flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
attr->flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
}
if (!bypassInterruptionPolicyAllowed(pid, uid)) {
attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
}
audio_output_flags_t originalFlags = flags;
AutoCallerClear acc;
status_t result = mAudioPolicyManager->getOutputForAttr(&attr, output, session, stream, uid,
status_t result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
config,
&flags, selectedDeviceId, portId,
secondaryOutputs);
@ -212,14 +214,14 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *original
*selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
*portId = AUDIO_PORT_HANDLE_NONE;
secondaryOutputs->clear();
result = mAudioPolicyManager->getOutputForAttr(&attr, output, session, stream, uid, config,
result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, config,
&flags, selectedDeviceId, portId,
secondaryOutputs);
}
if (result == NO_ERROR) {
sp <AudioPlaybackClient> client =
new AudioPlaybackClient(attr, *output, uid, pid, session, *selectedDeviceId, *stream);
new AudioPlaybackClient(*attr, *output, uid, pid, session, *selectedDeviceId, *stream);
mAudioPlaybackClients.add(*portId, client);
}
return result;

@ -75,7 +75,7 @@ public:
virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
virtual audio_io_handle_t getOutput(audio_stream_type_t stream);
status_t getOutputForAttr(const audio_attributes_t *attr,
status_t getOutputForAttr(audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,

Loading…
Cancel
Save