sound trigger: more checks on IMemory received from client
Add a verification on actual size of the fd backing up the IMemory
recevied for sound model or recognition config.
Fix similar problem for AudioTrack shared buffer.
Bug: 78596657
Test: run POC. OK Google regression.
Change-Id: I7cb02785f8ba46c437c7fcaa5b821f4b7e3240a0
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 6a90bea..0d50be0 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "ServiceUtilities"
+
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -172,4 +174,29 @@
return ok;
}
+status_t checkIMemory(const sp<IMemory>& iMemory)
+{
+ if (iMemory == 0) {
+ ALOGE("%s check failed: NULL IMemory pointer", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ sp<IMemoryHeap> heap = iMemory->getMemory();
+ if (heap == 0) {
+ ALOGE("%s check failed: NULL heap pointer", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ off_t size = lseek(heap->getHeapID(), 0, SEEK_END);
+ lseek(heap->getHeapID(), 0, SEEK_SET);
+
+ if (iMemory->pointer() == NULL || size < (off_t)iMemory->size()) {
+ ALOGE("%s check failed: pointer %p size %zu fd size %u",
+ __FUNCTION__, iMemory->pointer(), iMemory->size(), (uint32_t)size);
+ return BAD_VALUE;
+ }
+
+ return NO_ERROR;
+}
+
} // namespace android
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 2bdba5e..0911744 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -16,6 +16,7 @@
#include <unistd.h>
+#include <binder/IMemory.h>
#include <binder/PermissionController.h>
#include <cutils/multiuser.h>
#include <private/android_filesystem_config.h>
@@ -69,4 +70,5 @@
bool modifyAudioRoutingAllowed();
bool dumpAllowed();
bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
+status_t checkIMemory(const sp<IMemory>& iMemory);
}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d61b1f0..509386e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1891,11 +1891,17 @@
status_t lStatus;
audio_output_flags_t outputFlags = mOutput->flags;
audio_output_flags_t requestedFlags = *flags;
+ uint32_t sampleRate;
+
+ if (sharedBuffer != 0 && checkIMemory(sharedBuffer) != NO_ERROR) {
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
if (*pSampleRate == 0) {
*pSampleRate = mSampleRate;
}
- uint32_t sampleRate = *pSampleRate;
+ sampleRate = *pSampleRate;
// special case for FAST flag considered OK if fast mixer is present
if (hasFastMixer()) {
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 6bf6e94..eb9cd1d 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -562,10 +562,7 @@
if (mHalInterface == 0) {
return NO_INIT;
}
- if (modelMemory == 0 || modelMemory->pointer() == NULL) {
- ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
- return BAD_VALUE;
- }
+
struct sound_trigger_sound_model *sound_model =
(struct sound_trigger_sound_model *)modelMemory->pointer();
@@ -659,11 +656,6 @@
if (mHalInterface == 0) {
return NO_INIT;
}
- if (dataMemory == 0 || dataMemory->pointer() == NULL) {
- ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
- return BAD_VALUE;
-
- }
struct sound_trigger_recognition_config *config =
(struct sound_trigger_recognition_config *)dataMemory->pointer();
@@ -966,6 +958,9 @@
IPCThreadState::self()->getCallingUid())) {
return PERMISSION_DENIED;
}
+ if (checkIMemory(modelMemory) != NO_ERROR) {
+ return BAD_VALUE;
+ }
sp<Module> module = mModule.promote();
if (module == 0) {
@@ -997,6 +992,9 @@
IPCThreadState::self()->getCallingUid())) {
return PERMISSION_DENIED;
}
+ if (checkIMemory(dataMemory) != NO_ERROR) {
+ return BAD_VALUE;
+ }
sp<Module> module = mModule.promote();
if (module == 0) {