Fix android.permission.CAPTURE_AUDIO_OUTPUT permission check
Make sure we use the correct PID and UID when checking
android.permission.CAPTURE_AUDIO_OUTPUT permission from audio
policy service.
Bug: 28772898
Change-Id: I8f0c45bf7a5728b4364a451eefb6c025892ae9a5
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 585ef59..2e6646a 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -238,6 +238,7 @@
static status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 80437dc..0e9e3bc 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -81,6 +81,7 @@
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 3074910..8fc410d 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -38,7 +38,9 @@
const String16 &opPackageName,
uint32_t sampleRate,
uint32_t channels,
- uint32_t outSampleRate = 0);
+ uint32_t outSampleRate = 0,
+ uid_t uid = -1,
+ pid_t pid = -1);
status_t initCheck() const;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 343bf1a..d9bb856 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -533,7 +533,8 @@
status = AudioSystem::getInputForAttr(&mAttributes, &input,
mSessionId,
// FIXME compare to AudioTrack
- IPCThreadState::self()->getCallingUid(),
+ mClientPid,
+ mClientUid,
mSampleRate, mFormat, mChannelMask,
mFlags, mSelectedDeviceId);
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index bbdf65e..808b3ab 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -836,6 +836,7 @@
status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
@@ -846,7 +847,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
return aps->getInputForAttr(
- attr, input, session, uid, samplingRate, format, channelMask, flags, selectedDeviceId);
+ attr, input, session, pid, uid,
+ samplingRate, format, channelMask, flags, selectedDeviceId);
}
status_t AudioSystem::startInput(audio_io_handle_t input,
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 4ea67da..6405d6d 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -280,6 +280,7 @@
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
@@ -299,6 +300,7 @@
}
data.write(attr, sizeof(audio_attributes_t));
data.writeInt32(session);
+ data.writeInt32(pid);
data.writeInt32(uid);
data.writeInt32(samplingRate);
data.writeInt32(static_cast <uint32_t>(format));
@@ -959,6 +961,7 @@
audio_attributes_t attr;
data.read(&attr, sizeof(audio_attributes_t));
audio_session_t session = (audio_session_t)data.readInt32();
+ pid_t pid = (pid_t)data.readInt32();
uid_t uid = (uid_t)data.readInt32();
uint32_t samplingRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
@@ -966,7 +969,7 @@
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
- status_t status = getInputForAttr(&attr, &input, session, uid,
+ status_t status = getInputForAttr(&attr, &input, session, pid, uid,
samplingRate, format, channelMask,
flags, selectedDeviceId);
reply->writeInt32(status);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6114af8..97ba76b 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -934,7 +934,9 @@
mOpPackageName,
sourceSampleRate,
mAudioChannels,
- mSampleRate);
+ mSampleRate,
+ mClientUid,
+ mClientPid);
status_t err = audioSource->initCheck();
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index c8b61ca..790c6da 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -51,7 +51,8 @@
AudioSource::AudioSource(
audio_source_t inputSource, const String16 &opPackageName,
- uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate)
+ uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
+ uid_t uid, pid_t pid)
: mStarted(false),
mSampleRate(sampleRate),
mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
@@ -91,7 +92,12 @@
(size_t) (bufCount * frameCount),
AudioRecordCallbackFunction,
this,
- frameCount /*notificationFrames*/);
+ frameCount /*notificationFrames*/,
+ AUDIO_SESSION_ALLOCATE,
+ AudioRecord::TRANSFER_DEFAULT,
+ AUDIO_INPUT_FLAG_NONE,
+ uid,
+ pid);
mInitCheck = mRecord->initCheck();
if (mInitCheck != OK) {
mRecord.clear();
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index afc2440..3c73543 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -105,11 +105,10 @@
return true;
}
-bool captureAudioOutputAllowed() {
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
- // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
- bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput);
+ bool ok = checkPermission(sCaptureAudioOutput, pid, uid);
if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
return ok;
}
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index 1e79553..8b1bc00 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -21,7 +21,7 @@
extern pid_t getpid_cached;
bool isTrustedCallingUid(uid_t uid);
bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
-bool captureAudioOutputAllowed();
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
bool captureHotwordAllowed();
bool settingsAllowed();
bool modifyAudioRoutingAllowed();
diff --git a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
index 09a931f..151d066 100644
--- a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
@@ -190,7 +190,8 @@
}
if (((*pDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) == AUDIO_DEVICE_IN_REMOTE_SUBMIX)
- && !captureAudioOutputAllowed()) {
+ && !captureAudioOutputAllowed(IPCThreadState::self()->getCallingPid(),
+ IPCThreadState::self()->getCallingUid())) {
ALOGE("open_input() permission denied: capture not allowed");
return AUDIO_IO_HANDLE_NONE;
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 92a1285..02603b8 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -260,6 +260,7 @@
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
@@ -282,11 +283,22 @@
sp<AudioPolicyEffects>audioPolicyEffects;
status_t status;
AudioPolicyInterface::input_type_t inputType;
+
+ bool updatePid = (pid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
- ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
+ if (!isTrustedCallingUid(callingUid)) {
+ ALOGW_IF(uid != -1 && uid != (int)callingUid,
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
uid = callingUid;
+ updatePid = true;
+ }
+
+ if (updatePid) {
+ const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW_IF(pid != -1 && pid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, pid);
+ pid = callingPid;
}
{
@@ -306,7 +318,7 @@
case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
// FIXME: use the same permission as for remote submix for now.
case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
- if (!captureAudioOutputAllowed()) {
+ if (!captureAudioOutputAllowed(pid, uid)) {
ALOGE("getInputForAttr() permission denied: capture not allowed");
status = PERMISSION_DENIED;
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index c830454..7c9315d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -234,6 +234,7 @@
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid __unused,
uid_t uid __unused,
uint32_t samplingRate,
audio_format_t format,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 2710ac7..0b2cb35 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -99,6 +99,7 @@
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,