drm/nouveau/secboot/acr: Remove VLA usage
authorKees Cook <keescook@chromium.org>
Thu, 24 May 2018 17:24:36 +0000 (10:24 -0700)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 16 Jul 2018 08:06:30 +0000 (18:06 +1000)
In the quest to remove all stack VLA usage from the kernel[1], this
allocates the working buffers before starting the writing so it won't
abort in the middle. This needs an initial walk of the lists to figure
out how large the buffer should be.

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

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c

index a721354249ce68420d467990e0963a206fa9d2d3..d02e183717dc4575bd667116ab90caaaa8289968 100644 (file)
@@ -414,6 +414,20 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
 {
        struct ls_ucode_img *_img;
        u32 pos = 0;
+       u32 max_desc_size = 0;
+       u8 *gdesc;
+
+       /* Figure out how large we need gdesc to be. */
+       list_for_each_entry(_img, imgs, node) {
+               const struct acr_r352_ls_func *ls_func =
+                                           acr->func->ls_func[_img->falcon_id];
+
+               max_desc_size = max(max_desc_size, ls_func->bl_desc_size);
+       }
+
+       gdesc = kmalloc(max_desc_size, GFP_KERNEL);
+       if (!gdesc)
+               return -ENOMEM;
 
        nvkm_kmap(wpr_blob);
 
@@ -421,7 +435,6 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
                struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img);
                const struct acr_r352_ls_func *ls_func =
                                            acr->func->ls_func[_img->falcon_id];
-               u8 gdesc[ls_func->bl_desc_size];
 
                nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header,
                                      sizeof(img->wpr_header));
@@ -447,6 +460,8 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
 
        nvkm_done(wpr_blob);
 
+       kfree(gdesc);
+
        return 0;
 }
 
@@ -771,7 +786,11 @@ acr_r352_load(struct nvkm_acr *_acr, struct nvkm_falcon *falcon,
        struct fw_bl_desc *hsbl_desc;
        void *bl, *blob_data, *hsbl_code, *hsbl_data;
        u32 code_size;
-       u8 bl_desc[bl_desc_size];
+       u8 *bl_desc;
+
+       bl_desc = kzalloc(bl_desc_size, GFP_KERNEL);
+       if (!bl_desc)
+               return -ENOMEM;
 
        /* Find the bootloader descriptor for our blob and copy it */
        if (blob == acr->load_blob) {
@@ -802,7 +821,6 @@ acr_r352_load(struct nvkm_acr *_acr, struct nvkm_falcon *falcon,
                              code_size, hsbl_desc->start_tag, 0, false);
 
        /* Generate the BL header */
-       memset(bl_desc, 0, bl_desc_size);
        acr->func->generate_hs_bl_desc(load_hdr, bl_desc, offset);
 
        /*
@@ -811,6 +829,7 @@ acr_r352_load(struct nvkm_acr *_acr, struct nvkm_falcon *falcon,
        nvkm_falcon_load_dmem(falcon, bl_desc, hsbl_desc->dmem_load_off,
                              bl_desc_size, 0);
 
+       kfree(bl_desc);
        return hsbl_desc->start_tag << 8;
 }
 
index 866877b88797b568f2d604f156ed2ad4118538f3..978ad079036705cbb10b2b87fafa9507dc79317c 100644 (file)
@@ -265,6 +265,19 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
 {
        struct ls_ucode_img *_img;
        u32 pos = 0;
+       u32 max_desc_size = 0;
+       u8 *gdesc;
+
+       list_for_each_entry(_img, imgs, node) {
+               const struct acr_r352_ls_func *ls_func =
+                                           acr->func->ls_func[_img->falcon_id];
+
+               max_desc_size = max(max_desc_size, ls_func->bl_desc_size);
+       }
+
+       gdesc = kmalloc(max_desc_size, GFP_KERNEL);
+       if (!gdesc)
+               return -ENOMEM;
 
        nvkm_kmap(wpr_blob);
 
@@ -272,7 +285,6 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
                struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img);
                const struct acr_r352_ls_func *ls_func =
                                            acr->func->ls_func[_img->falcon_id];
-               u8 gdesc[ls_func->bl_desc_size];
 
                nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header,
                                      sizeof(img->wpr_header));
@@ -298,6 +310,8 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
 
        nvkm_done(wpr_blob);
 
+       kfree(gdesc);
+
        return 0;
 }