Merge tag 'AUDIO.LA.8.0.r1-09300-KAILUA.0' into staging/lineage-20.0_merge-AUDIO.LA.8.0.r1-09300-KAILUA.0

AUDIO.LA.8.0.r1-09300-KAILUA.0

# By Ganapathiraju Sarath Varma (2) and others
# Via Linux Build Service Account (4) and others
* tag 'AUDIO.LA.8.0.r1-09300-KAILUA.0':
  ipc: HwBinders: Fix potential out of bound access
  ipc: Hwbinders: Add checks to avoid OOB read.
  agm: ipc: SWBinders: protect handle by clbk_data_list_lock
  AGM: protect graph_read/graph_write with mutex
  service: metadata: Add check to avoid null pointer dereference
  AGM: Add suppot to pick default acdb path
  AGM: Add suppot to pick default acdb path
  plugins: tinyalsa: make correct direction distinction of RX and TX
  Revert "agm: service: implement agm crash notificaiton to kernel"

Change-Id: I0f1c53d66586efac241b74b053145131f0bb382d
diff --git a/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp b/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
index 9b2d1d0..9fde121 100644
--- a/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
+++ b/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -28,38 +27,10 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted (subject to the limitations in the
- * disclaimer below) provided that the following conditions are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
- * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
- * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
  */
+
 #define LOG_TAG "agm_client_wrapper"
 
 #include <cutils/list.h>
@@ -106,8 +77,6 @@
     agm_server_died = true;
     if (cb_ != NULL)
         cb_(cookie_);
-    // We exit the client process here, so that it also can restart
-    // leading to a fresh start on both the sides.
 }
 
 android::sp<IAGM> get_agm_server() {
diff --git a/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp b/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
index 78b83f0..1f24851 100644
--- a/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
+++ b/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
@@ -883,6 +883,11 @@
     void * payload_local = NULL;
     int32_t ret = 0;
 
+    if (payload.size() < size) {
+        ALOGE("%s: Invalid payload.size[%d] less than size %d\n", __func__, payload.size(), size);
+        return -EINVAL;
+    }
+
     payload_local = (void*) calloc(1, size);
     if (payload_local == NULL) {
         ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -901,6 +906,18 @@
     ALOGV("%s : session_id = %d\n", __func__, session_id);
     struct agm_event_reg_cfg *evt_reg_cfg_local;
     int32_t ret = 0;
+
+    if (evt_reg_cfg.size() != 1) {
+        ALOGE("%s evt_reg_cfg needs to be of size 1\n", __func__);
+        return -EINVAL;
+    }
+
+    if (evt_reg_cfg.data()->event_config_payload.size() !=
+        evt_reg_cfg.data()->event_config_payload_size) {
+        ALOGE("%s: event_config_payload_size value mismatch\n", __func__);
+        return -EINVAL;
+    }
+
     evt_reg_cfg_local = (struct agm_event_reg_cfg*)
               calloc(1,(sizeof(struct agm_event_reg_cfg) +
               (evt_reg_cfg.data()->event_config_payload_size)*sizeof(uint8_t)));
diff --git a/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp b/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp
index 82cd647..0f875ea 100644
--- a/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp
+++ b/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp
@@ -27,7 +27,7 @@
 ** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted (subject to the limitations in the
@@ -777,21 +777,21 @@
         if (handle != NULL && handle->session_id == session_id &&
                               handle->client_data == client_data) {
             AGM_LOGV("%s: Found handle %p\n", __func__, handle);
-            pthread_mutex_unlock(&clbk_data_list_lock);
             break;
         }
     }
-    pthread_mutex_unlock(&clbk_data_list_lock);
 
     if (handle!= NULL) {
         sp<ICallback> cb_binder = handle->cb_binder;
         if (cb_binder == NULL) {
             AGM_LOGE("%s Invalid binder handle\n", __func__);
+            pthread_mutex_unlock(&clbk_data_list_lock);
             return;
         }
         cb_binder->event_cb(session_id, event_params,
                handle->client_data, handle->cb_func);
     }
+    pthread_mutex_unlock(&clbk_data_list_lock);
 }
 
 
diff --git a/plugins/tinyalsa/src/agm_pcm_plugin.c b/plugins/tinyalsa/src/agm_pcm_plugin.c
index 2099b60..8eb6587 100644
--- a/plugins/tinyalsa/src/agm_pcm_plugin.c
+++ b/plugins/tinyalsa/src/agm_pcm_plugin.c
@@ -710,8 +710,11 @@
 {
     struct agm_pcm_priv *priv = plugin->priv;
     snd_pcm_sframes_t avail = 0;
+    enum direction dir;
 
-    if (plugin->mode & PCM_OUT) {
+    dir = (plugin->mode & PCM_IN) ? TX : RX;
+
+    if (dir == RX) {
         avail = priv->pos_buf->hw_ptr +
             priv->total_size_frames -
             priv->pos_buf->appl_ptr;
@@ -720,7 +723,7 @@
             avail += priv->pos_buf->boundary;
         else if ((snd_pcm_uframes_t)avail >= priv->pos_buf->boundary)
             avail -= priv->pos_buf->boundary;
-    } else if (plugin->mode & PCM_IN) {
+    } else if (dir == TX) {
         __builtin_sub_overflow(priv->pos_buf->hw_ptr, priv->pos_buf->appl_ptr, &avail);
         if (avail < 0)
             avail += priv->pos_buf->boundary;
diff --git a/service/src/device.c b/service/src/device.c
index 78a3679..c498ed8 100644
--- a/service/src/device.c
+++ b/service/src/device.c
@@ -1,6 +1,5 @@
 /*
 ** Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
-** Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without
 ** modification, are permitted provided that the following conditions are
@@ -26,6 +25,10 @@
 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 ** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 ** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+** Changes from Qualcomm Innovation Center are provided under the following license:
+** Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+** SPDX-License-Identifier: BSD-3-Clause-Clear
 **/
 
 #define LOG_TAG "AGM: device"
@@ -34,7 +37,6 @@
 #include <pthread.h>
 #include <sched.h>
 #include <stdio.h>
-#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -63,9 +65,6 @@
 #define TRUE 1
 #define FALSE 0
 
-#define DEVICE_ENABLE 1
-#define DEVICE_DISABLE 0
-
 #define BUF_SIZE 1024
 #define FILE_PATH_EXTN_MAX_SIZE 80
 #define MAX_RETRY_CNT 20
@@ -83,9 +82,6 @@
 static struct mixer *mixer = NULL;
 #endif
 
-#define SYSFS_FD_PATH "/sys/kernel/aud_dev/state"
-static int sysfs_fd = -1;
-
 #define MAX_BUF_SIZE                 2048
 /**
   * The maximum period bytes for dummy dai is 8192 bytes.
@@ -150,36 +146,6 @@
      return bits_per_sample;
 }
 
-static void update_sysfs_fd (int8_t pcm_id, int8_t state)
-{
-    char buf[MAX_USR_INPUT]={0};
-    snprintf(buf, MAX_USR_INPUT,"%d %d", pcm_id, state);
-    if (sysfs_fd >= 0)
-        write(sysfs_fd, buf, MAX_USR_INPUT);
-    else {
-        /*AGM service and sysfs file creation are async events.
-         *Also when the syfs node is first created the default
-         *user attribute for the sysfs file is root.
-         *To change the same we need to execute a command from
-         *init scripts, which again are async and there is no
-         *deterministic way of scheduling this command only after
-         *the sysfs node is created. And all this should happen before
-         *we try to open the file from agm context, otherwise the open
-         *call would fail with permission denied error.
-         *Hence we try to open the file first time when we access it instead
-         *of doing it from agm_init.
-         *This gives the system enough time for the file attributes to
-         *be changed.
-         */
-        sysfs_fd = open(SYSFS_FD_PATH, O_WRONLY);
-        if (sysfs_fd >= 0) {
-            write(sysfs_fd, buf, MAX_USR_INPUT);
-        } else {
-            AGM_LOGE("invalid file handle\n");
-        }
-    }
-}
-
 int device_get_snd_card_id()
 {
     struct device_obj *dev_obj = node_to_item(list_head(&device_list),
@@ -297,8 +263,6 @@
                  __func__, pcm_name, rate, channels, format);
         goto done;
     }
-
-    update_sysfs_fd(obj->pcm_id, DEVICE_ENABLE);
     obj->pcm = pcm;
     obj->state = DEV_OPENED;
     obj->refcnt.open++;
@@ -413,7 +377,6 @@
         ret = -EIO;
         goto done;
     }
-    update_sysfs_fd(obj->pcm_id, DEVICE_ENABLE);
     obj->pcm = pcm;
     obj->state = DEV_OPENED;
     obj->refcnt.open++;
@@ -587,7 +550,6 @@
     }
 
     if (--obj->refcnt.open == 0) {
-        update_sysfs_fd(obj->pcm_id, DEVICE_DISABLE);
 #ifdef DEVICE_USES_ALSALIB
         ret = snd_pcm_close(obj->pcm);
 #else
@@ -1174,9 +1136,6 @@
 
     list_remove(&device_group_data_list);
     list_remove(&device_list);
-    if (sysfs_fd >= 0)
-        close(sysfs_fd);
-    sysfs_fd = -1;
 
 #ifdef DEVICE_USES_ALSALIB
     if (mixer)
@@ -1196,6 +1155,7 @@
     char *snd_card_name = NULL;
     char *tmp = NULL;
     char *card_sub_str = NULL;
+    int token_count = 0;
 
     snd_card_name = strdup(in_snd_card_name);
     if (snd_card_name == NULL) {
@@ -1211,12 +1171,14 @@
 
     while ((card_sub_str = strtok_r(NULL, "-", &tmp))) {
         if (strncmp(card_sub_str, "snd", strlen("snd"))) {
-            strlcpy(file_path_extn_wo_variant, file_path_extn, FILE_PATH_EXTN_MAX_SIZE);
+            if(token_count == 1)
+               strlcpy(file_path_extn_wo_variant, file_path_extn, FILE_PATH_EXTN_MAX_SIZE);
             strlcat(file_path_extn, "_", FILE_PATH_EXTN_MAX_SIZE);
             strlcat(file_path_extn, card_sub_str, FILE_PATH_EXTN_MAX_SIZE);
         }
         else
             break;
+        token_count++;
     }
 
 done:
diff --git a/service/src/metadata.c b/service/src/metadata.c
index bcf0d51..d49ab18 100644
--- a/service/src/metadata.c
+++ b/service/src/metadata.c
@@ -165,6 +165,22 @@
 {
     int i, j;
 
+    if (!meta_data || !ckv) {
+        AGM_LOGE("Invalid params\n");
+        return;
+    }
+
+    if (!(meta_data->ckv.kv)) {
+        AGM_LOGE("metadata->ckv.kv is NULL, num_kvs=%d\n",
+                                    meta_data->ckv.num_kvs);
+        return;
+    }
+    if (!(ckv->kv)) {
+        AGM_LOGE("ckv->kv is NULL, num_kvs=%d\n",
+                                    ckv->num_kvs);
+        return;
+    }
+
     for (i = 0; i < meta_data->ckv.num_kvs; i++) {
         for (j = 0; j < ckv->num_kvs; j++) {
             if (meta_data->ckv.kv[i].key == ckv->kv[j].key) {
diff --git a/service/src/session_obj.c b/service/src/session_obj.c
index 1ae4057..1319543 100644
--- a/service/src/session_obj.c
+++ b/service/src/session_obj.c
@@ -2362,10 +2362,8 @@
         AGM_LOGE("Cannot issue read in state:%d\n",
                            sess_obj->state);
         ret = -EINVAL;
-        pthread_mutex_unlock(&sess_obj->lock);
         goto done;
     }
-    pthread_mutex_unlock(&sess_obj->lock);
 
     buffer.timestamp = 0x0;
     buffer.flags = 0;
@@ -2378,6 +2376,7 @@
     }
 
 done:
+    pthread_mutex_unlock(&sess_obj->lock);
     return ret;
 }
 
@@ -2391,10 +2390,8 @@
         AGM_LOGE("Cannot issue write in state:%d\n",
                             sess_obj->state);
         ret = -EINVAL;
-        pthread_mutex_unlock(&sess_obj->lock);
         goto done;
     }
-    pthread_mutex_unlock(&sess_obj->lock);
 
     buffer.timestamp = 0x0;
     buffer.flags = 0;
@@ -2407,6 +2404,7 @@
     }
 
 done:
+    pthread_mutex_unlock(&sess_obj->lock);
     return ret;
 }
 
@@ -2652,16 +2650,16 @@
         AGM_LOGE("Cannot issue write in state:%d\n",
                             sess_obj->state);
         ret = -EINVAL;
-        pthread_mutex_unlock(&sess_obj->lock);
         goto done;
     }
-    pthread_mutex_unlock(&sess_obj->lock);
+
     ret = graph_write(sess_obj->graph, buffer, consumed_size);
     if (ret) {
         AGM_LOGE("Error:%d writing to graph\n", ret);
     }
 
 done:
+    pthread_mutex_unlock(&sess_obj->lock);
     return ret;
 }
 
@@ -2675,10 +2673,8 @@
         AGM_LOGE("Cannot issue read in state:%d\n",
                            sess_obj->state);
         ret = -EINVAL;
-        pthread_mutex_unlock(&sess_obj->lock);
         goto done;
     }
-    pthread_mutex_unlock(&sess_obj->lock);
 
     size_t read_size;
     ret = graph_read(sess_obj->graph, buffer, &read_size);
@@ -2689,6 +2685,7 @@
     *captured_size = (uint32_t)read_size;
 
 done:
+    pthread_mutex_unlock(&sess_obj->lock);
     return ret;
 }