OSDN Git Service

soc: msm: add size check to fix out of bounds on ANC
authorTimothy Sham <tsham@codeaurora.org>
Mon, 28 May 2018 21:17:41 +0000 (17:17 -0400)
committerTimothy Sham <tsham@codeaurora.org>
Fri, 1 Jun 2018 17:35:21 +0000 (13:35 -0400)
Before calling audio ANC ioctl functions, compare the
allocated buffer size to the size of the header and ANC cmd header
to ensure the buffer is big enough.

Change-Id: I8fcd0a830853d802bbb11fc243a4d392fbe384f3
Signed-off-by: Timothy Sham <tsham@codeaurora.org>
drivers/soc/qcom/qdsp6v2/audio_anc.c
include/uapi/linux/msm_audio_anc.h

index e0abd2b..65c5858 100644 (file)
@@ -53,6 +53,9 @@ static size_t get_user_anc_cmd_size(int32_t anc_cmd)
        case ANC_CMD_ALGO_MODULE:
                size = sizeof(struct audio_anc_algo_module_info);
                break;
+       case ANC_CMD_ALGO_CALIBRATION:
+               size = sizeof(struct audio_anc_algo_calibration_info);
+               break;
        default:
                pr_err("%s:Invalid anc cmd %d!",
                        __func__, anc_cmd);
@@ -77,6 +80,7 @@ static int call_set_anc(int32_t anc_cmd,
        case ANC_CMD_RPM:
        case ANC_CMD_BYPASS_MODE:
        case ANC_CMD_ALGO_MODULE:
+       case ANC_CMD_ALGO_CALIBRATION:
                ret = msm_anc_dev_set_info(data, anc_cmd);
                break;
        default:
@@ -176,6 +180,12 @@ static long audio_anc_shared_ioctl(struct file *file, unsigned int cmd,
                        sizeof(union audio_anc_data));
                ret = -EINVAL;
                goto done;
+       } else if ((data->hdr.anc_cmd_size + sizeof(data->hdr)) > size) {
+               pr_err("%s: anc_cmd size %d + anc cmd hdr size %zd is is greater than user buffer siz %d!\n",
+                       __func__, data->hdr.anc_cmd_size, sizeof(data->hdr),
+                       size);
+               ret = -EFAULT;
+               goto done;
        }
 
        switch (cmd) {
@@ -194,15 +204,9 @@ static long audio_anc_shared_ioctl(struct file *file, unsigned int cmd,
                        goto done;
                if (data == NULL)
                        goto done;
-               if ((sizeof(data->hdr) + data->hdr.anc_cmd_size) > size) {
-                       pr_err("%s: header size %zd plus ype size %d larger than data buffer size %d\n",
-                               __func__, sizeof(data->hdr),
-                               data->hdr.anc_cmd_size, size);
-                       ret = -EFAULT;
-                       goto done;
-               } else if (copy_to_user((void *)arg, data,
+               if (copy_to_user(arg, data,
                        sizeof(data->hdr) + data->hdr.anc_cmd_size)) {
-                       pr_err("%s: Could not copy cal type to user\n",
+                       pr_err("%s: Could not copy anc data to user\n",
                                __func__);
                        ret = -EFAULT;
                        goto done;
index 028d381..d628f7c 100644 (file)
@@ -16,6 +16,7 @@
 #define ANC_CMD_RPM    2
 #define ANC_CMD_BYPASS_MODE    3
 #define ANC_CMD_ALGO_MODULE    4
+#define ANC_CMD_ALGO_CALIBRATION    5
 
 /* room for ANC_CMD define extend */
 #define ANC_CMD_MAX   0xFF
@@ -39,10 +40,16 @@ struct audio_anc_algo_module_info {
        int32_t module_id;
 };
 
+struct audio_anc_algo_calibration_info {
+       int32_t payload_size;
+       /* num bytes of payload specificed in payload_size followed */
+};
+
 union  audio_anc_data {
        struct audio_anc_rpm_info rpm_info;
        struct audio_anc_bypass_mode bypass_mode_info;
        struct audio_anc_algo_module_info algo_info;
+       struct audio_anc_algo_calibration_info algo_cali_info;
 };
 
 struct audio_anc_packet {