OSDN Git Service

fbdev: msm: Avoid UAF in mdss_dsi_cmd_write
authorNirmal Abraham <nabrah@codeaurora.org>
Fri, 16 Aug 2019 11:09:17 +0000 (16:39 +0530)
committerGerrit - the friendly Code Review server <code-review@localhost>
Wed, 16 Oct 2019 05:42:19 +0000 (22:42 -0700)
In mdss_dsi_cmd_write, a failure in copying the cmds to
'string_buf' can cause an early return. In this case,
the 'pcmds->string_buf' won't be pointing to a valid
buffer. This can lead to use-after-free and memory leak.
To avoid this, assign the newly allocated buffer to
'pcmds->string_buf' after returning from krealloc call.

Change-Id: I286f12c86078d1989cb09453c8a395a4ad94b324
Signed-off-by: Nirmal Abraham <nabrah@codeaurora.org>
drivers/video/fbdev/msm/mdss_dsi.c

index 419991a..c2cfc8e 100644 (file)
@@ -888,7 +888,7 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
 {
        struct buf_data *pcmds = file->private_data;
        ssize_t ret = 0;
-       int blen = 0;
+       unsigned int blen = 0;
        char *string_buf;
 
        mutex_lock(&pcmds->dbg_mutex);
@@ -900,6 +900,11 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
 
        /* Allocate memory for the received string */
        blen = count + (pcmds->sblen);
+       if (blen > U32_MAX - 1) {
+               mutex_unlock(&pcmds->dbg_mutex);
+               return -EINVAL;
+       }
+
        string_buf = krealloc(pcmds->string_buf, blen + 1, GFP_KERNEL);
        if (!string_buf) {
                pr_err("%s: Failed to allocate memory\n", __func__);
@@ -907,6 +912,7 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
                return -ENOMEM;
        }
 
+       pcmds->string_buf = string_buf;
        /* Writing in batches is possible */
        ret = simple_write_to_buffer(string_buf, blen, ppos, p, count);
        if (ret < 0) {
@@ -916,7 +922,6 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
        }
 
        string_buf[ret] = '\0';
-       pcmds->string_buf = string_buf;
        pcmds->sblen = count;
        mutex_unlock(&pcmds->dbg_mutex);
        return ret;