OSDN Git Service

drm/msm/adreno: Remove VLA usage
authorKees Cook <keescook@chromium.org>
Fri, 29 Jun 2018 18:48:18 +0000 (11:48 -0700)
committerRob Clark <robdclark@gmail.com>
Sun, 5 Aug 2018 14:07:09 +0000 (10:07 -0400)
In the quest to remove all stack VLA usage from the kernel[1], this
switches to using a kasprintf()ed buffer. Return paths are updated
to free the allocation.

[1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c

index bd84f71..ab1d930 100644 (file)
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/cpumask.h>
 #include <linux/qcom_scm.h>
@@ -20,6 +21,7 @@
 #include <linux/pm_opp.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/iopoll.h>
+#include <linux/slab.h>
 #include "msm_gem.h"
 #include "msm_mmu.h"
 #include "a5xx_gpu.h"
@@ -92,12 +94,13 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname)
                ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID,
                                mem_region, mem_phys, mem_size, NULL);
        } else {
-               char newname[strlen("qcom/") + strlen(fwname) + 1];
+               char *newname;
 
-               sprintf(newname, "qcom/%s", fwname);
+               newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
 
                ret = qcom_mdt_load(dev, fw, newname, GPU_PAS_ID,
                                mem_region, mem_phys, mem_size, NULL);
+               kfree(newname);
        }
        if (ret)
                goto out;
index 38ac50b..65c0ae7 100644 (file)
@@ -18,7 +18,9 @@
  */
 
 #include <linux/ascii85.h>
+#include <linux/kernel.h>
 #include <linux/pm_opp.h>
+#include <linux/slab.h>
 #include "adreno_gpu.h"
 #include "msm_gem.h"
 #include "msm_mmu.h"
@@ -71,10 +73,12 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
 {
        struct drm_device *drm = adreno_gpu->base.dev;
        const struct firmware *fw = NULL;
-       char newname[strlen("qcom/") + strlen(fwname) + 1];
+       char *newname;
        int ret;
 
-       sprintf(newname, "qcom/%s", fwname);
+       newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
+       if (!newname)
+               return ERR_PTR(-ENOMEM);
 
        /*
         * Try first to load from qcom/$fwfile using a direct load (to avoid
@@ -88,11 +92,12 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
                        dev_info(drm->dev, "loaded %s from new location\n",
                                newname);
                        adreno_gpu->fwloc = FW_LOCATION_NEW;
-                       return fw;
+                       goto out;
                } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
                        dev_err(drm->dev, "failed to load %s: %d\n",
                                newname, ret);
-                       return ERR_PTR(ret);
+                       fw = ERR_PTR(ret);
+                       goto out;
                }
        }
 
@@ -107,11 +112,12 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
                        dev_info(drm->dev, "loaded %s from legacy location\n",
                                newname);
                        adreno_gpu->fwloc = FW_LOCATION_LEGACY;
-                       return fw;
+                       goto out;
                } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
                        dev_err(drm->dev, "failed to load %s: %d\n",
                                fwname, ret);
-                       return ERR_PTR(ret);
+                       fw = ERR_PTR(ret);
+                       goto out;
                }
        }
 
@@ -127,16 +133,20 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
                        dev_info(drm->dev, "loaded %s with helper\n",
                                newname);
                        adreno_gpu->fwloc = FW_LOCATION_HELPER;
-                       return fw;
+                       goto out;
                } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
                        dev_err(drm->dev, "failed to load %s: %d\n",
                                newname, ret);
-                       return ERR_PTR(ret);
+                       fw = ERR_PTR(ret);
+                       goto out;
                }
        }
 
        dev_err(drm->dev, "failed to load %s\n", fwname);
-       return ERR_PTR(-ENOENT);
+       fw = ERR_PTR(-ENOENT);
+out:
+       kfree(newname);
+       return fw;
 }
 
 static int adreno_load_fw(struct adreno_gpu *adreno_gpu)