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

2016-12-06 Thread Greg KH
On Tue, Dec 06, 2016 at 02:10:13PM -0500, Oleg Drokin wrote:
> 
> On Dec 6, 2016, at 1:37 PM, Dan Carpenter wrote:
> 
> > On Tue, Dec 06, 2016 at 10:44:54AM -0500, Oleg Drokin wrote:
> >> 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.
> > 
> > Checking for > 0 is not enough, because it could also have an integer
> > overflow on 32 bit systems.  We need to cap the upper bound as well.
> 
> How would it play out, though?
> offsetof(struct lstcon_test, tes_param[large_positive_int]) would result in
> some real "large" negative number.
> So trying to allocate this many negative bytes would fail, right?

Not always.  Please properly bound your allocations.

thanks,

greg k-h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


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

2016-12-06 Thread Dan Carpenter
On Tue, Dec 06, 2016 at 02:10:13PM -0500, Oleg Drokin wrote:
> 
> On Dec 6, 2016, at 1:37 PM, Dan Carpenter wrote:
> 
> > On Tue, Dec 06, 2016 at 10:44:54AM -0500, Oleg Drokin wrote:
> >> 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.
> > 
> > Checking for > 0 is not enough, because it could also have an integer
> > overflow on 32 bit systems.  We need to cap the upper bound as well.
> 
> How would it play out, though?
> offsetof(struct lstcon_test, tes_param[large_positive_int]) would result in
> some real "large" negative number.
> So trying to allocate this many negative bytes would fail, right?

Oh, yeah.  You're right.  Good point...

regards,
dan carpenter

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


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

2016-12-06 Thread Oleg Drokin

On Dec 6, 2016, at 1:37 PM, Dan Carpenter wrote:

> On Tue, Dec 06, 2016 at 10:44:54AM -0500, Oleg Drokin wrote:
>> 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.
> 
> Checking for > 0 is not enough, because it could also have an integer
> overflow on 32 bit systems.  We need to cap the upper bound as well.

How would it play out, though?
offsetof(struct lstcon_test, tes_param[large_positive_int]) would result in
some real "large" negative number.
So trying to allocate this many negative bytes would fail, right?


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


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

2016-12-06 Thread Dan Carpenter
On Tue, Dec 06, 2016 at 10:44:54AM -0500, Oleg Drokin wrote:
> 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.

Checking for > 0 is not enough, because it could also have an integer
overflow on 32 bit systems.  We need to cap the upper bound as well.

regards,
dan carpenter

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


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

2016-12-06 Thread Oleg Drokin

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.

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


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

2016-12-06 Thread Dan Carpenter
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.

   744  
   745  LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
   746  if (!batch_name)
   747  return rc;
   748  
   749  LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
   750  if (!src_name)
   751  goto out;
   752  
   753  LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
   754  if (!dst_name)
   755  goto out;
   756  
   757  if (args->lstio_tes_param) {
   758  LIBCFS_ALLOC(param, args->lstio_tes_param_len);
   759  if (!param)
   760  goto out;
   761  if (copy_from_user(param, args->lstio_tes_param,
   762 args->lstio_tes_param_len)) {
   763  rc = -EFAULT;
   764  goto out;
   765  }
   766  }

This is the code that you mentioned.  But we don't have a parameter so
it's not invoked.

   767  
   768  rc = -EFAULT;
   769  if (copy_from_user(batch_name, args->lstio_tes_bat_name,
   770 args->lstio_tes_bat_nmlen) ||
   771  copy_from_user(src_name, args->lstio_tes_sgrp_name,
   772 args->lstio_tes_sgrp_nmlen) ||
   773  copy_from_user(dst_name, args->lstio_tes_dgrp_name,
   774 args->lstio_tes_dgrp_nmlen))
   775  goto out;
   776  
   777  rc = lstcon_test_add(batch_name, args->lstio_tes_type,
   778   args->lstio_tes_loop, 
args->lstio_tes_concur,
   779   args->lstio_tes_dist, args->lstio_tes_span,
   780   

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

2016-12-05 Thread Oleg Drokin

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.

> 
>  1313  if (!test) {
>  1314  CERROR("Can't allocate test descriptor\n");
>  1315  rc = -ENOMEM;
>  1316  
>  1317  goto out;
>  1318  }
>  1319  
>  1320  test->tes_hdr.tsb_id = batch->bat_hdr.tsb_id;
> 
> Which will lead to memory corruption when we use "test".
> 
>  1321  test->tes_batch = batch;
>  1322  test->tes_type = type;
>  1323  test->tes_oneside = 0; /* TODO */
>  1324  test->tes_loop = loop;
>  1325  test->tes_concur = concur;
>  1326  test->tes_stop_onerr = 1; /* TODO */
>  1327  test->tes_span = span;
>  1328  test->tes_dist = dist;
>  1329  test->tes_cliidx = 0; /* just used for creating RPC */
>  1330  test->tes_src_grp = src_grp;
>  1331  test->tes_dst_grp = dst_grp;
>  1332  INIT_LIST_HEAD(>tes_trans_list);
>  1333  
>  1334  if (param) {
> 
> Smatch is not smart enough to trace the implication that "'param' is
> non-NULL, means that 'paramlen' has been verified" across a function
> boundary.  Storing that sort of information would really increase the
> hardware requirements for running Smatch so it's not something I have
> planned currently.
> 
>  1335  test->tes_paramlen = paramlen;
>  1336  memcpy(>tes_param[0], param, paramlen);
>  1337  }
>  1338  
> 
> regards,
> dan carpenter
> ___
> lustre-devel mailing list
> lustre-de...@lists.lustre.org
> http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel