On Wed, Mar 29, 2023 at 07:54:02PM -0600, Gustavo A. R. Silva wrote:
> GCC-13 (and Clang) does not like having a partially allocated object,
> since it cannot reason about it for bounds checking.
> 
> Notice that the compiler is legitimately complaining about accessing
> an object (params, in this case) for which not enough memory was
> allocated.
> 
> The object is of size 20 bytes:
> 
> struct ec_params_vbnvcontext {
>       uint32_t                   op;                   /*     0     4 */
>       uint8_t                    block[16];            /*     4    16 */
> 
>       /* size: 20, cachelines: 1, members: 2 */
>       /* last cacheline: 20 bytes */
> };
> 
> but only 16 bytes are allocated:
> 
> sizeof(struct ec_response_vbnvcontext) == 16
> 
> In this case, as only enough space for the op field is allocated,
> we can use an object of type uint32_t instead of a whole
> struct ec_params_vbnvcontext (for which not enough memory is
> allocated).
> 
> Fix the following warning seen under GCC 13:
> drivers/platform/chrome/cros_ec_vbc.c: In function ‘vboot_context_read’:
> drivers/platform/chrome/cros_ec_vbc.c:36:15: warning: array subscript ‘struct 
> ec_params_vbnvcontext[1]’ is partly outside array bounds of ‘unsigned 
> char[36]’ [-Warray-bounds=]
>    36 |         params->op = EC_VBNV_CONTEXT_OP_READ;
>       |               ^~
> In file included from drivers/platform/chrome/cros_ec_vbc.c:12:
> In function ‘kmalloc’,
>     inlined from ‘vboot_context_read’ at 
> drivers/platform/chrome/cros_ec_vbc.c:30:8:
> ./include/linux/slab.h:580:24: note: at offset 20 into object of size 36 
> allocated by ‘kmalloc_trace’
>   580 |                 return kmalloc_trace(
>       |                        ^~~~~~~~~~~~~~
>   581 |                                 
> kmalloc_caches[kmalloc_type(flags)][index],
>       |                                 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   582 |                                 flags, size);
>       |                                 ~~~~~~~~~~~~
> 
> Link: https://github.com/KSPP/linux/issues/278
> Signed-off-by: Gustavo A. R. Silva <[email protected]>

This patch seems to have gotten lost? Looking at the conversation, I
think it should land as-is rather than changing the allocation size.

I can pick this up via my tree if that helps...

-Kees

> ---
>  drivers/platform/chrome/cros_ec_vbc.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/platform/chrome/cros_ec_vbc.c 
> b/drivers/platform/chrome/cros_ec_vbc.c
> index c859c862d7ac..b5a584f5469a 100644
> --- a/drivers/platform/chrome/cros_ec_vbc.c
> +++ b/drivers/platform/chrome/cros_ec_vbc.c
> @@ -20,10 +20,14 @@ static ssize_t vboot_context_read(struct file *filp, 
> struct kobject *kobj,
>       struct device *dev = kobj_to_dev(kobj);
>       struct cros_ec_dev *ec = to_cros_ec_dev(dev);
>       struct cros_ec_device *ecdev = ec->ec_dev;
> -     struct ec_params_vbnvcontext *params;
>       struct cros_ec_command *msg;
> +     /*
> +      * This should be a pointer to the same type as op field in
> +      * struct ec_params_vbnvcontext.
> +      */
> +     uint32_t *params_op;
>       int err;
> -     const size_t para_sz = sizeof(params->op);
> +     const size_t para_sz = sizeof(*params_op);
>       const size_t resp_sz = sizeof(struct ec_response_vbnvcontext);
>       const size_t payload = max(para_sz, resp_sz);
>  
> @@ -32,8 +36,8 @@ static ssize_t vboot_context_read(struct file *filp, struct 
> kobject *kobj,
>               return -ENOMEM;
>  
>       /* NB: we only kmalloc()ated enough space for the op field */
> -     params = (struct ec_params_vbnvcontext *)msg->data;
> -     params->op = EC_VBNV_CONTEXT_OP_READ;
> +     params_op = (uint32_t *)msg->data;
> +     *params_op = EC_VBNV_CONTEXT_OP_READ;
>  
>       msg->version = EC_VER_VBNV_CONTEXT;
>       msg->command = EC_CMD_VBNV_CONTEXT;
> -- 
> 2.34.1
> 

-- 
Kees Cook

Reply via email to