[lustre-devel] [bug report] staging: add Lustre file system client support

Oleg Drokin oleg.drokin at intel.com
Tue Dec 6 07:44:54 PST 2016


On Dec 6, 2016, at 6:02 AM, Dan Carpenter wrote:

> On Mon, Dec 05, 2016 at 06:43:37PM -0500, Oleg Drokin wrote:
>> 
>> On Nov 23, 2016, at 7:29 AM, Dan Carpenter wrote:
>> 
>>> Hi Lustre Devs,
>>> 
>>> The patch d7e09d0397e8: "staging: add Lustre file system client
>>> support" from May 2, 2013, leads to the following static checker
>>> warning:
>>> 
>>> 	drivers/staging/lustre/lnet/selftest/console.c:1336 lstcon_test_add()
>>> 	error: 'paramlen' from user is not capped properly
>>> 
>>> The story here, is that "paramlen" is capped but only if "param" is
>>> non-NULL.  This causes a problem.
>>> 
>>> drivers/staging/lustre/lnet/selftest/console.c
>>> 1311  
>>> 1312          LIBCFS_ALLOC(test, offsetof(struct lstcon_test, tes_param[paramlen]));
>>> 
>>> We don't know that paramlen is non-NULL here.  Because of integer
>>> overflows we could end up allocating less than intended.
>> 
>> I think this must be a false positive in this case?
>> 
>> Before calling this function we do:
>>                LIBCFS_ALLOC(param, args->lstio_tes_param_len);
>> 
>> in lst_test_add_ioctl(), so it's not any bigger than 128k (or kmalloc will fail).
>> Even if kmalloc would allow more than 128k allocations,
>> offsetof(struct lstcon_test, tes_param[0]) is bound to be a lot smaller than
>> the baseline allocation address for kmalloc, and therefore integer overflow
>> cannot happen at all.
>> 
> 
> I explained badly, and I typed the wrong variable names by mistake...
> Here is the relevant code from the caller:
> 
> drivers/staging/lustre/lnet/selftest/conctl.c
>   710  static int lst_test_add_ioctl(lstio_test_args_t *args)
>   711  {
>   712          char *batch_name;
>   713          char *src_name = NULL;
>   714          char *dst_name = NULL;
>   715          void *param = NULL;
>   716          int ret = 0;
>   717          int rc = -ENOMEM;
>   718  
>   719          if (!args->lstio_tes_resultp ||
>   720              !args->lstio_tes_retp ||
>   721              !args->lstio_tes_bat_name ||        /* no specified batch */
>   722              args->lstio_tes_bat_nmlen <= 0 ||
>   723              args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
>   724              !args->lstio_tes_sgrp_name ||       /* no source group */
>   725              args->lstio_tes_sgrp_nmlen <= 0 ||
>   726              args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
>   727              !args->lstio_tes_dgrp_name ||       /* no target group */
>   728              args->lstio_tes_dgrp_nmlen <= 0 ||
>   729              args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
>   730                  return -EINVAL;
>   731  
>   732          if (!args->lstio_tes_loop ||            /* negative is infinite */
>   733              args->lstio_tes_concur <= 0 ||
>   734              args->lstio_tes_dist <= 0 ||
>   735              args->lstio_tes_span <= 0)
>   736                  return -EINVAL;
>   737  
>   738          /* have parameter, check if parameter length is valid */
>   739          if (args->lstio_tes_param &&
>   740              (args->lstio_tes_param_len <= 0 ||
>   741               args->lstio_tes_param_len >
>   742               PAGE_SIZE - sizeof(struct lstcon_test)))
>   743                  return -EINVAL;
> 
> If we don't have a parameter then we don't check ->lstio_tes_param_len.

I see, indeed, it all makes sense now.
So basically if we unconditionally check for the size to be > 0, we should be
fine then, I imagine.
On the other hand there's probably no se for no param and nonzero param len,
so it's probably even better to enforce size as zero when no param.

Thank you.



More information about the lustre-devel mailing list