video: tegra: dsi: Set max limit for reading panel
Pavan Kunapuli [Thu, 16 Mar 2017 14:02:06 +0000 (19:02 +0530)]
In the debugfs support for reading panel registers, max payload
needs to be limited to the buff array size to avoid stack corruption.

Bug 1873360

Change-Id: Ibee7bd81027d2669297942c09b905f1dd3bb09ee
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Signed-off-by: sakets <sakets@nvidia.com>
Reviewed-on: https://git-master/r/1505449
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bibek Basu <bbasu@nvidia.com>

drivers/video/tegra/dc/dsi_debug.c

index 294180e..bdd7426 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/video/tegra/dc/dsi_debug.c
  *
- * Copyright (c) 2013-2014 NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2013-2017 NVIDIA CORPORATION, All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -31,6 +31,8 @@
 
 #ifdef CONFIG_DEBUG_FS
 
+#define MAX_PANEL_REG_READ_SIZE        300
+
 static int dbg_dsi_show(struct seq_file *s, void *unused)
 {
        struct tegra_dc_dsi_data *dsi;
@@ -160,35 +162,43 @@ static int read_panel_get(struct seq_file *s, void *unused)
        struct tegra_dc_dsi_data *dsi = s->private;
        struct tegra_dc *dc = dsi->dc;
        int err = 0;
-       u8 buf[300] = {0};
+       u8 buf[MAX_PANEL_REG_READ_SIZE] = {0};
        int j = 0 , b = 0 , k;
        u32 payload_size = 0;
 
        if (!dsi->enabled) {
                dev_info(&dc->ndev->dev, " controller suspended\n");
-       return -EINVAL;
-}
+               return -EINVAL;
+       }
 
        seq_printf(s, "max ret payload size:0x%x\npanel reg addr:0x%x\n",
                                        max_ret_payload_size, panel_reg_addr);
-       if (max_ret_payload_size == 0) {
-               seq_puts(s, "echo was not successful\n");
-       return err;
-}
+
+       if ((max_ret_payload_size > MAX_PANEL_REG_READ_SIZE) ||
+                       (max_ret_payload_size == 0)) {
+               seq_printf(s, "payload size should be positive value < 0x%x\n",
+                                       MAX_PANEL_REG_READ_SIZE);
+               return err;
+       }
+
+       if (panel_reg_addr >= MAX_PANEL_REG_READ_SIZE) {
+               seq_puts(s, "panel reg addr is outside the range\n");
+               return err;
+       }
+
+       if (max_ret_payload_size >
+                       (MAX_PANEL_REG_READ_SIZE - panel_reg_addr))
+               max_ret_payload_size =
+                       MAX_PANEL_REG_READ_SIZE - panel_reg_addr;
+
        err = tegra_dsi_read_data(dsi->dc, dsi,
                                max_ret_payload_size,
                                panel_reg_addr, buf);
 
-       seq_printf(s, " Read data[%d] ", b);
-
-       for (b = 1; b < (max_ret_payload_size+1); b++) {
-               j = (b*4)-1;
-               for (k = j; k > (j-4); k--)
-                       if ((k%4) == 0 && b != max_ret_payload_size) {
-                               seq_printf(s, " %x  ", buf[k]);
-                               seq_printf(s, "\n Read data[%d] ", b);
-                       } else
-                               seq_printf(s, " %x ", buf[k]);
+       for (b = 0; b < max_ret_payload_size; b += 4) {
+               seq_printf(s, "\n Read data[%d] ", j++);
+               for (k = b+4; k > b; k--)
+                       seq_printf(s, " %x ", buf[k-1]);
        }
        seq_puts(s, "\n");