soundtrigger: add size check on sound model and recogntion data

Bug: 30148546

Change-Id: I082f535a853c96571887eeea37c6d41ecee7d8c0
(cherry picked from commit bb00d8f139ff51336ab3c810d35685003949bcf8)
(cherry picked from commit ef0c91518446e65533ca8bab6726a845f27c73fd)
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 9de6fe2..e428388 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -534,6 +534,22 @@
     struct sound_trigger_sound_model *sound_model =
             (struct sound_trigger_sound_model *)modelMemory->pointer();
 
+    size_t structSize;
+    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+        structSize = sizeof(struct sound_trigger_phrase_sound_model);
+    } else {
+        structSize = sizeof(struct sound_trigger_sound_model);
+    }
+
+    if (sound_model->data_offset < structSize ||
+           sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
+           modelMemory->size() < sound_model->data_offset ||
+           sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
+        android_errorWriteLog(0x534e4554, "30148546");
+        ALOGE("loadSoundModel() data_size is too big");
+        return BAD_VALUE;
+    }
+
     AutoMutex lock(mLock);
 
     if (mModels.size() >= mDescriptor.properties.max_sound_models) {
@@ -603,11 +619,23 @@
         return PERMISSION_DENIED;
     }
 
-    if (dataMemory != 0 && dataMemory->pointer() == NULL) {
-        ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()");
+    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();
+
+    if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
+            config->data_size > (UINT_MAX - config->data_offset) ||
+            dataMemory->size() < config->data_offset ||
+            config->data_size > (dataMemory->size() - config->data_offset)) {
+        ALOGE("startRecognition() data_size is too big");
+        return BAD_VALUE;
+    }
+
     AutoMutex lock(mLock);
     if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
         return INVALID_OPERATION;
@@ -616,17 +644,11 @@
     if (model == 0) {
         return BAD_VALUE;
     }
-    if ((dataMemory == 0) ||
-            (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) {
-        return BAD_VALUE;
-    }
 
     if (model->mState == Model::STATE_ACTIVE) {
         return INVALID_OPERATION;
     }
 
-    struct sound_trigger_recognition_config *config =
-            (struct sound_trigger_recognition_config *)dataMemory->pointer();
 
     //TODO: get capture handle and device from audio policy service
     config->capture_handle = model->mCaptureIOHandle;