Merge "Update audio permission checking"

gugelfrei
Andy Hung 6 years ago committed by Android (Google) Code Review
commit 298e1b3db0

@ -49,6 +49,7 @@ cc_library_shared {
"libaudiomanager", "libaudiomanager",
"libmedia_helper", "libmedia_helper",
"libmediametrics", "libmediametrics",
"libmediautils",
], ],
export_shared_lib_headers: ["libbinder"], export_shared_lib_headers: ["libbinder"],

@ -24,10 +24,8 @@
#include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h>
#include <binder/Parcel.h> #include <binder/Parcel.h>
#include <cutils/multiuser.h>
#include <media/TimeCheck.h> #include <media/TimeCheck.h>
#include <private/android_filesystem_config.h> #include <mediautils/ServiceUtilities.h>
#include "IAudioFlinger.h" #include "IAudioFlinger.h"
namespace android { namespace android {
@ -912,7 +910,7 @@ status_t BnAudioFlinger::onTransact(
case SET_MIC_MUTE: case SET_MIC_MUTE:
case SET_LOW_RAM_DEVICE: case SET_LOW_RAM_DEVICE:
case SYSTEM_READY: { case SYSTEM_READY: {
if (multiuser_get_app_id(IPCThreadState::self()->getCallingUid()) >= AID_APP_START) { if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d", ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(), __func__, code, IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid()); IPCThreadState::self()->getCallingUid());

@ -24,11 +24,10 @@
#include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h>
#include <binder/Parcel.h> #include <binder/Parcel.h>
#include <cutils/multiuser.h>
#include <media/AudioEffect.h> #include <media/AudioEffect.h>
#include <media/IAudioPolicyService.h> #include <media/IAudioPolicyService.h>
#include <media/TimeCheck.h> #include <media/TimeCheck.h>
#include <private/android_filesystem_config.h> #include <mediautils/ServiceUtilities.h>
#include <system/audio.h> #include <system/audio.h>
namespace android { namespace android {
@ -936,7 +935,7 @@ status_t BnAudioPolicyService::onTransact(
case STOP_AUDIO_SOURCE: case STOP_AUDIO_SOURCE:
case GET_SURROUND_FORMATS: case GET_SURROUND_FORMATS:
case SET_SURROUND_FORMAT_ENABLED: { case SET_SURROUND_FORMAT_ENABLED: {
if (multiuser_get_app_id(IPCThreadState::self()->getCallingUid()) >= AID_APP_START) { if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d", ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(), __func__, code, IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid()); IPCThreadState::self()->getCallingUid());

@ -25,6 +25,7 @@ cc_library {
], ],
shared_libs: [ shared_libs: [
"libbinder", "libbinder",
"libcutils",
"liblog", "liblog",
"libutils", "libutils",
"libmemunreachable", "libmemunreachable",

@ -18,7 +18,6 @@
#include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h> #include <binder/IServiceManager.h>
#include <binder/PermissionCache.h> #include <binder/PermissionCache.h>
#include <private/android_filesystem_config.h>
#include "mediautils/ServiceUtilities.h" #include "mediautils/ServiceUtilities.h"
/* When performing permission checks we do not use permission cache for /* When performing permission checks we do not use permission cache for
@ -32,24 +31,6 @@ namespace android {
static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO"); static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO");
// Not valid until initialized by AudioFlinger constructor. It would have to be
// re-initialized if the process containing AudioFlinger service forks (which it doesn't).
// This is often used to validate binder interface calls within audioserver
// (e.g. AudioPolicyManager to AudioFlinger).
pid_t getpid_cached;
// A trusted calling UID may specify the client UID as part of a binder interface call.
// otherwise the calling UID must be equal to the client UID.
bool isTrustedCallingUid(uid_t uid) {
switch (uid) {
case AID_MEDIA:
case AID_AUDIOSERVER:
return true;
default:
return false;
}
}
static String16 resolveCallingPackage(PermissionController& permissionController, static String16 resolveCallingPackage(PermissionController& permissionController,
const String16& opPackageName, uid_t uid) { const String16& opPackageName, uid_t uid) {
if (opPackageName.size() > 0) { if (opPackageName.size() > 0) {
@ -71,16 +52,11 @@ static String16 resolveCallingPackage(PermissionController& permissionController
return packages[0]; return packages[0];
} }
static inline bool isAudioServerOrRoot(uid_t uid) {
// AID_ROOT is OK for command-line tests. Native unforked audioserver always OK.
return uid == AID_ROOT || uid == AID_AUDIOSERVER ;
}
static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
uid_t uid, bool start) { uid_t uid, bool start) {
// Okay to not track in app ops as audio server is us and if // Okay to not track in app ops as audio server is us and if
// device is rooted security model is considered compromised. // device is rooted security model is considered compromised.
if (isAudioServerOrRoot(uid)) return true; if (isAudioServerOrRootUid(uid)) return true;
// We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder) // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
// may open a record track on behalf of a client. Note that pid may be a tid. // may open a record track on behalf of a client. Note that pid may be a tid.
@ -127,7 +103,7 @@ bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid) {
void finishRecording(const String16& opPackageName, uid_t uid) { void finishRecording(const String16& opPackageName, uid_t uid) {
// Okay to not track in app ops as audio server is us and if // Okay to not track in app ops as audio server is us and if
// device is rooted security model is considered compromised. // device is rooted security model is considered compromised.
if (isAudioServerOrRoot(uid)) return; if (isAudioServerOrRootUid(uid)) return;
PermissionController permissionController; PermissionController permissionController;
String16 resolvedOpPackageName = resolveCallingPackage( String16 resolvedOpPackageName = resolveCallingPackage(
@ -142,7 +118,7 @@ void finishRecording(const String16& opPackageName, uid_t uid) {
} }
bool captureAudioOutputAllowed(pid_t pid, uid_t uid) { bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; if (isAudioServerOrRootUid(uid)) return true;
static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT"); static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid); bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT"); if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
@ -163,7 +139,8 @@ bool captureHotwordAllowed(pid_t pid, uid_t uid) {
} }
bool settingsAllowed() { bool settingsAllowed() {
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; // given this is a permission check, could this be isAudioServerOrRootUid()?
if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS"); static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
// IMPORTANT: Use PermissionCache - not a runtime permission and may not change. // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
bool ok = PermissionCache::checkCallingPermission(sAudioSettings); bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
@ -180,7 +157,6 @@ bool modifyAudioRoutingAllowed() {
} }
bool dumpAllowed() { bool dumpAllowed() {
// don't optimize for same pid, since mediaserver never dumps itself
static const String16 sDump("android.permission.DUMP"); static const String16 sDump("android.permission.DUMP");
// IMPORTANT: Use PermissionCache - not a runtime permission and may not change. // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
bool ok = PermissionCache::checkCallingPermission(sDump); bool ok = PermissionCache::checkCallingPermission(sDump);

@ -17,13 +17,49 @@
#include <unistd.h> #include <unistd.h>
#include <binder/PermissionController.h> #include <binder/PermissionController.h>
#include <cutils/multiuser.h>
#include <private/android_filesystem_config.h>
namespace android { namespace android {
// Audio permission utilities // Audio permission utilities
extern pid_t getpid_cached; // Used for calls that should originate from system services.
bool isTrustedCallingUid(uid_t uid); // We allow that some services might have separate processes to
// handle multiple users, e.g. u10_system, u10_bluetooth, u10_radio.
static inline bool isServiceUid(uid_t uid) {
return multiuser_get_app_id(uid) < AID_APP_START;
}
// Used for calls that should originate from audioserver.
static inline bool isAudioServerUid(uid_t uid) {
return uid == AID_AUDIOSERVER;
}
// Used for some permission checks.
// AID_ROOT is OK for command-line tests. Native audioserver always OK.
static inline bool isAudioServerOrRootUid(uid_t uid) {
return uid == AID_AUDIOSERVER || uid == AID_ROOT;
}
// Used for calls that should come from system server or internal.
// Note: system server is multiprocess for multiple users. audioserver is not.
static inline bool isAudioServerOrSystemServerUid(uid_t uid) {
return multiuser_get_app_id(uid) == AID_SYSTEM || uid == AID_AUDIOSERVER;
}
// Mediaserver may forward the client PID and UID as part of a binder interface call;
// otherwise the calling UID must be equal to the client UID.
static inline bool isAudioServerOrMediaServerUid(uid_t uid) {
switch (uid) {
case AID_MEDIA:
case AID_AUDIOSERVER:
return true;
default:
return false;
}
}
bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid); bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid); bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid);
void finishRecording(const String16& opPackageName, uid_t uid); void finishRecording(const String16& opPackageName, uid_t uid);

@ -28,7 +28,6 @@
#include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h> #include <binder/IServiceManager.h>
#include <cutils/multiuser.h>
#include <utils/Log.h> #include <utils/Log.h>
#include <utils/Trace.h> #include <utils/Trace.h>
#include <binder/Parcel.h> #include <binder/Parcel.h>
@ -158,7 +157,6 @@ AudioFlinger::AudioFlinger()
mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX; mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
} }
getpid_cached = getpid();
const bool doLog = property_get_bool("ro.test_harness", false); const bool doLog = property_get_bool("ro.test_harness", false);
if (doLog) { if (doLog) {
mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters", mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
@ -632,7 +630,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input,
bool updatePid = (input.clientInfo.clientPid == -1); bool updatePid = (input.clientInfo.clientPid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t callingUid = IPCThreadState::self()->getCallingUid();
uid_t clientUid = input.clientInfo.clientUid; uid_t clientUid = input.clientInfo.clientUid;
if (!isTrustedCallingUid(callingUid)) { if (!isAudioServerOrMediaServerUid(callingUid)) {
ALOGW_IF(clientUid != callingUid, ALOGW_IF(clientUid != callingUid,
"%s uid %d tried to pass itself off as %d", "%s uid %d tried to pass itself off as %d",
__FUNCTION__, callingUid, clientUid); __FUNCTION__, callingUid, clientUid);
@ -1044,9 +1042,9 @@ status_t AudioFlinger::checkStreamType(audio_stream_type_t stream) const
ALOGW("checkStreamType() invalid stream %d", stream); ALOGW("checkStreamType() invalid stream %d", stream);
return BAD_VALUE; return BAD_VALUE;
} }
pid_t caller = IPCThreadState::self()->getCallingPid(); const uid_t callerUid = IPCThreadState::self()->getCallingUid();
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT && caller != getpid_cached) { if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT && !isAudioServerUid(callerUid)) {
ALOGW("checkStreamType() pid %d cannot use internal stream type %d", caller, stream); ALOGW("checkStreamType() uid %d cannot use internal stream type %d", callerUid, stream);
return PERMISSION_DENIED; return PERMISSION_DENIED;
} }
@ -1166,9 +1164,8 @@ void AudioFlinger::filterReservedParameters(String8& keyValuePairs, uid_t callin
String8(AudioParameter::keyStreamSupportedSamplingRates), String8(AudioParameter::keyStreamSupportedSamplingRates),
}; };
// multiuser friendly app ID check for requests coming from audioserver if (isAudioServerUid(callingUid)) {
if (multiuser_get_app_id(callingUid) == AID_AUDIOSERVER) { return; // no need to filter if audioserver.
return;
} }
AudioParameter param = AudioParameter(keyValuePairs); AudioParameter param = AudioParameter(keyValuePairs);
@ -1602,7 +1599,7 @@ sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& inpu
bool updatePid = (input.clientInfo.clientPid == -1); bool updatePid = (input.clientInfo.clientPid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t callingUid = IPCThreadState::self()->getCallingUid();
uid_t clientUid = input.clientInfo.clientUid; uid_t clientUid = input.clientInfo.clientUid;
if (!isTrustedCallingUid(callingUid)) { if (!isAudioServerOrMediaServerUid(callingUid)) {
ALOGW_IF(clientUid != callingUid, ALOGW_IF(clientUid != callingUid,
"%s uid %d tried to pass itself off as %d", "%s uid %d tried to pass itself off as %d",
__FUNCTION__, callingUid, clientUid); __FUNCTION__, callingUid, clientUid);
@ -1851,7 +1848,7 @@ size_t AudioFlinger::getPrimaryOutputFrameCount()
status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory)
{ {
uid_t uid = IPCThreadState::self()->getCallingUid(); uid_t uid = IPCThreadState::self()->getCallingUid();
if (uid != AID_SYSTEM) { if (!isAudioServerOrSystemServerUid(uid)) {
return PERMISSION_DENIED; return PERMISSION_DENIED;
} }
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
@ -2541,7 +2538,8 @@ void AudioFlinger::acquireAudioSessionId(audio_session_t audioSession, pid_t pid
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
pid_t caller = IPCThreadState::self()->getCallingPid(); pid_t caller = IPCThreadState::self()->getCallingPid();
ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid); ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid);
if (pid != -1 && (caller == getpid_cached)) { const uid_t callerUid = IPCThreadState::self()->getCallingUid();
if (pid != -1 && isAudioServerUid(callerUid)) { // check must match releaseAudioSessionId()
caller = pid; caller = pid;
} }
@ -2575,7 +2573,8 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
pid_t caller = IPCThreadState::self()->getCallingPid(); pid_t caller = IPCThreadState::self()->getCallingPid();
ALOGV("releasing %d from %d for %d", audioSession, caller, pid); ALOGV("releasing %d from %d for %d", audioSession, caller, pid);
if (pid != -1 && (caller == getpid_cached)) { const uid_t callerUid = IPCThreadState::self()->getCallingUid();
if (pid != -1 && isAudioServerUid(callerUid)) { // check must match acquireAudioSessionId()
caller = pid; caller = pid;
} }
size_t num = mAudioSessionRefs.size(); size_t num = mAudioSessionRefs.size();
@ -2592,9 +2591,10 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid
return; return;
} }
} }
// If the caller is mediaserver it is likely that the session being released was acquired // If the caller is audioserver it is likely that the session being released was acquired
// on behalf of a process not in notification clients and we ignore the warning. // on behalf of a process not in notification clients and we ignore the warning.
ALOGW_IF(caller != getpid_cached, "session id %d not found for pid %d", audioSession, caller); ALOGW_IF(!isAudioServerUid(callerUid),
"session id %d not found for pid %d", audioSession, caller);
} }
bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession) bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession)
@ -2902,7 +2902,7 @@ sp<IEffect> AudioFlinger::createEffect(
effect_descriptor_t desc; effect_descriptor_t desc;
const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (pid == -1 || !isTrustedCallingUid(callingUid)) { if (pid == -1 || !isAudioServerOrMediaServerUid(callingUid)) {
const pid_t callingPid = IPCThreadState::self()->getCallingPid(); const pid_t callingPid = IPCThreadState::self()->getCallingPid();
ALOGW_IF(pid != -1 && pid != callingPid, ALOGW_IF(pid != -1 && pid != callingPid,
"%s uid %d pid %d tried to pass itself off as pid %d", "%s uid %d pid %d tried to pass itself off as pid %d",
@ -2925,8 +2925,8 @@ sp<IEffect> AudioFlinger::createEffect(
} }
// Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
// that can only be created by audio policy manager (running in same process) // that can only be created by audio policy manager
if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && getpid_cached != pid) { if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && !isAudioServerUid(callingUid)) {
lStatus = PERMISSION_DENIED; lStatus = PERMISSION_DENIED;
goto Exit; goto Exit;
} }

@ -1815,7 +1815,7 @@ void AudioFlinger::EffectHandle::dumpToBuffer(char* buffer, size_t size)
bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock); bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
snprintf(buffer, size, "\t\t\t%5d %5d %3s %3s %5u %5u\n", snprintf(buffer, size, "\t\t\t%5d %5d %3s %3s %5u %5u\n",
(mClient == 0) ? getpid_cached : mClient->pid(), (mClient == 0) ? getpid() : mClient->pid(),
mPriority, mPriority,
mHasControl ? "yes" : "no", mHasControl ? "yes" : "no",
locked ? "yes" : "no", locked ? "yes" : "no",

@ -3930,7 +3930,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
// start the fast mixer // start the fast mixer
mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO); mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
pid_t tid = mFastMixer->getTid(); pid_t tid = mFastMixer->getTid();
sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer, false /*forApp*/); sendPrioConfigEvent(getpid(), tid, kPriorityFastMixer, false /*forApp*/);
stream()->setHalThreadPriority(kPriorityFastMixer); stream()->setHalThreadPriority(kPriorityFastMixer);
#ifdef AUDIO_WATCHDOG #ifdef AUDIO_WATCHDOG
@ -3939,7 +3939,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
mAudioWatchdog->setDump(&mAudioWatchdogDump); mAudioWatchdog->setDump(&mAudioWatchdogDump);
mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO); mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO);
tid = mAudioWatchdog->getTid(); tid = mAudioWatchdog->getTid();
sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer, false /*forApp*/); sendPrioConfigEvent(getpid(), tid, kPriorityFastMixer, false /*forApp*/);
#endif #endif
} else { } else {
#ifdef TEE_SINK #ifdef TEE_SINK
@ -6339,7 +6339,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
// start the fast capture // start the fast capture
mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO); mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO);
pid_t tid = mFastCapture->getTid(); pid_t tid = mFastCapture->getTid();
sendPrioConfigEvent(getpid_cached, tid, kPriorityFastCapture, false /*forApp*/); sendPrioConfigEvent(getpid(), tid, kPriorityFastCapture, false /*forApp*/);
stream()->setHalThreadPriority(kPriorityFastCapture); stream()->setHalThreadPriority(kPriorityFastCapture);
#ifdef AUDIO_WATCHDOG #ifdef AUDIO_WATCHDOG
// FIXME // FIXME

@ -102,7 +102,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
mIsInvalid(false) mIsInvalid(false)
{ {
const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!isTrustedCallingUid(callingUid) || clientUid == AUDIO_UID_INVALID) { if (!isAudioServerOrMediaServerUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
ALOGW_IF(clientUid != AUDIO_UID_INVALID && clientUid != callingUid, ALOGW_IF(clientUid != AUDIO_UID_INVALID && clientUid != callingUid,
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid); "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
clientUid = callingUid; clientUid = callingUid;
@ -585,7 +585,7 @@ void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool activ
"%08X %6zu%c %6zu %c %9u%c %7u " "%08X %6zu%c %6zu %c %9u%c %7u "
"%08zX %08zX\n", "%08zX %08zX\n",
active ? "yes" : "no", active ? "yes" : "no",
(mClient == 0) ? getpid_cached : mClient->pid(), (mClient == 0) ? getpid() : mClient->pid(),
mSessionId, mSessionId,
getTrackStateString(), getTrackStateString(),
mCblk->mFlags, mCblk->mFlags,
@ -1495,7 +1495,7 @@ AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThr
audio_attributes_t{} /* currently unused for patch track */, audio_attributes_t{} /* currently unused for patch track */,
sampleRate, format, channelMask, frameCount, sampleRate, format, channelMask, frameCount,
buffer, bufferSize, nullptr /* sharedBuffer */, buffer, bufferSize, nullptr /* sharedBuffer */,
AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH), AUDIO_SESSION_NONE, AID_AUDIOSERVER, flags, TYPE_PATCH),
mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true)) mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
{ {
uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) / uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
@ -1786,7 +1786,7 @@ void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool a
"%08X %6zu %3c\n", "%08X %6zu %3c\n",
isFastTrack() ? 'F' : ' ', isFastTrack() ? 'F' : ' ',
active ? "yes" : "no", active ? "yes" : "no",
(mClient == 0) ? getpid_cached : mClient->pid(), (mClient == 0) ? getpid() : mClient->pid(),
mSessionId, mSessionId,
getTrackStateString(), getTrackStateString(),
mCblk->mFlags, mCblk->mFlags,
@ -1866,7 +1866,8 @@ AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
: RecordTrack(recordThread, NULL, : RecordTrack(recordThread, NULL,
audio_attributes_t{} /* currently unused for patch track */, audio_attributes_t{} /* currently unused for patch track */,
sampleRate, format, channelMask, frameCount, sampleRate, format, channelMask, frameCount,
buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH), buffer, bufferSize, AUDIO_SESSION_NONE, AID_AUDIOSERVER,
flags, TYPE_PATCH),
mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true)) mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
{ {
uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) / uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /

@ -39,6 +39,7 @@
#include <media/AudioParameter.h> #include <media/AudioParameter.h>
#include <media/AudioPolicyHelper.h> #include <media/AudioPolicyHelper.h>
#include <media/PatchBuilder.h> #include <media/PatchBuilder.h>
#include <private/android_filesystem_config.h>
#include <soundtrigger/SoundTrigger.h> #include <soundtrigger/SoundTrigger.h>
#include <system/audio.h> #include <system/audio.h>
#include <audio_policy_conf.h> #include <audio_policy_conf.h>
@ -3865,7 +3866,7 @@ static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface, AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
bool /*forTesting*/) bool /*forTesting*/)
: :
mUidCached(getuid()), mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
mpClientInterface(clientInterface), mpClientInterface(clientInterface),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false), mA2dpSuspended(false),

@ -540,7 +540,7 @@ protected:
static bool streamsMatchForvolume(audio_stream_type_t stream1, static bool streamsMatchForvolume(audio_stream_type_t stream1,
audio_stream_type_t stream2); audio_stream_type_t stream2);
uid_t mUidCached; const uid_t mUidCached; // AID_AUDIOSERVER
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor
// list of descriptors for outputs currently opened // list of descriptors for outputs currently opened

@ -183,7 +183,7 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) { if (!isAudioServerOrMediaServerUid(callingUid) || uid == (uid_t)-1) {
ALOGW_IF(uid != (uid_t)-1 && uid != callingUid, ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid); "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
uid = callingUid; uid = callingUid;
@ -320,7 +320,7 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
bool updatePid = (pid == -1); bool updatePid = (pid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!isTrustedCallingUid(callingUid)) { if (!isAudioServerOrMediaServerUid(callingUid)) {
ALOGW_IF(uid != (uid_t)-1 && uid != callingUid, ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid); "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
uid = callingUid; uid = callingUid;

@ -26,7 +26,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <binder/IServiceManager.h> #include <binder/IServiceManager.h>
#include <utils/Log.h> #include <utils/Log.h>
#include <cutils/multiuser.h>
#include <cutils/properties.h> #include <cutils/properties.h>
#include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h>
#include <binder/ActivityManager.h> #include <binder/ActivityManager.h>
@ -43,8 +42,6 @@
#include <system/audio.h> #include <system/audio.h>
#include <system/audio_policy.h> #include <system/audio_policy.h>
#include <private/android_filesystem_config.h>
namespace android { namespace android {
static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n"; static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
@ -275,7 +272,7 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
const String8& regId, int32_t state) const String8& regId, int32_t state)
{ {
if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) { if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
} }
} }
@ -285,7 +282,7 @@ void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig, const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle) audio_patch_handle_t patchHandle)
{ {
if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) { if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo, mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
clientConfig, deviceConfig, patchHandle); clientConfig, deviceConfig, patchHandle);
} }
@ -577,10 +574,6 @@ void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled)
updateUidCache(uid, false, true); updateUidCache(uid, false, true);
} }
bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const {
return multiuser_get_app_id(uid) < AID_APP_START;
}
void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) { void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
sp<AudioPolicyService> service = mService.promote(); sp<AudioPolicyService> service = mService.promote();
if (service != nullptr) { if (service != nullptr) {

@ -293,7 +293,6 @@ private:
void removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); } void removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); }
private: private:
bool isServiceUid(uid_t uid) const;
void notifyService(uid_t uid, bool active); void notifyService(uid_t uid, bool active);
void updateOverrideUid(uid_t uid, bool active, bool insert); void updateOverrideUid(uid_t uid, bool active, bool insert);
void updateUidCache(uid_t uid, bool active, bool insert); void updateUidCache(uid_t uid, bool active, bool insert);

@ -9,7 +9,9 @@ cc_library_shared {
shared_libs: [ shared_libs: [
"libaudioutils", "libaudioutils",
"libbinder", "libbinder",
"libcutils",
"liblog", "liblog",
"libmediautils",
"libnbaio", "libnbaio",
"libnblog", "libnblog",
"libutils", "libutils",

@ -21,7 +21,7 @@
#include <utils/Log.h> #include <utils/Log.h>
#include <binder/PermissionCache.h> #include <binder/PermissionCache.h>
#include <media/nblog/NBLog.h> #include <media/nblog/NBLog.h>
#include <private/android_filesystem_config.h> #include <mediautils/ServiceUtilities.h>
#include "MediaLogService.h" #include "MediaLogService.h"
namespace android { namespace android {
@ -53,7 +53,7 @@ MediaLogService::~MediaLogService()
void MediaLogService::registerWriter(const sp<IMemory>& shared, size_t size, const char *name) void MediaLogService::registerWriter(const sp<IMemory>& shared, size_t size, const char *name)
{ {
if (IPCThreadState::self()->getCallingUid() != AID_AUDIOSERVER || shared == 0 || if (!isAudioServerOrMediaServerUid(IPCThreadState::self()->getCallingUid()) || shared == 0 ||
size < kMinSize || size > kMaxSize || name == NULL || size < kMinSize || size > kMaxSize || name == NULL ||
shared->size() < NBLog::Timeline::sharedSize(size)) { shared->size() < NBLog::Timeline::sharedSize(size)) {
return; return;
@ -67,7 +67,7 @@ void MediaLogService::registerWriter(const sp<IMemory>& shared, size_t size, con
void MediaLogService::unregisterWriter(const sp<IMemory>& shared) void MediaLogService::unregisterWriter(const sp<IMemory>& shared)
{ {
if (IPCThreadState::self()->getCallingUid() != AID_AUDIOSERVER || shared == 0) { if (!isAudioServerOrMediaServerUid(IPCThreadState::self()->getCallingUid()) || shared == 0) {
return; return;
} }
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
@ -95,10 +95,8 @@ bool MediaLogService::dumpTryLock(Mutex& mutex)
status_t MediaLogService::dump(int fd, const Vector<String16>& args __unused) status_t MediaLogService::dump(int fd, const Vector<String16>& args __unused)
{ {
// FIXME merge with similar but not identical code at services/audioflinger/ServiceUtilities.cpp if (!(isAudioServerOrMediaServerUid(IPCThreadState::self()->getCallingUid())
static const String16 sDump("android.permission.DUMP"); || dumpAllowed())) {
if (!(IPCThreadState::self()->getCallingUid() == AID_AUDIOSERVER ||
PermissionCache::checkCallingPermission(sDump))) {
dprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n", dprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid()); IPCThreadState::self()->getCallingUid());

Loading…
Cancel
Save