On Sat, Apr 27, 2024 at 05:05:56PM +0200, Erick Archer wrote: > This is an effort to get rid of all multiplications from allocation > functions in order to prevent integer overflows [1][2]. > > As the "ff" variable is a pointer to "struct ff_device" and this > structure ends in a flexible array: > > struct ff_device { > [...] > struct file *effect_owners[] __counted_by(max_effects); > }; > > the preferred way in the kernel is to use the struct_size() helper to > do the arithmetic instead of the calculation "size + count * size" in > the kzalloc() function. > > The struct_size() helper returns SIZE_MAX on overflow. So, refactor > the comparison to take advantage of this. > > This way, the code is more readable and safer. > > This code was detected with the help of Coccinelle, and audited and > modified manually. > > Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1] > Link: https://github.com/KSPP/linux/issues/160 [2] > Signed-off-by: Erick Archer <erick.archer@xxxxxxxxxxx> > --- > Hi, > > The Coccinelle script used to detect this code pattern is the following: > > virtual report > > @rule1@ > type t1; > type t2; > identifier i0; > identifier i1; > identifier i2; > identifier ALLOC =~ "kmalloc|kzalloc|kmalloc_node|kzalloc_node|vmalloc|vzalloc|kvmalloc|kvzalloc"; > position p1; > @@ > > i0 = sizeof(t1) + sizeof(t2) * i1; > ... > i2 = ALLOC@p1(..., i0, ...); > > @script:python depends on report@ > p1 << rule1.p1; > @@ > > msg = "WARNING: verify allocation on line %s" % (p1[0].line) > coccilib.report.print_report(p1[0],msg) > > Regards, > Erick > --- > drivers/input/ff-core.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c > index 16231fe080b0..609a5f01761b 100644 > --- a/drivers/input/ff-core.c > +++ b/drivers/input/ff-core.c > @@ -9,8 +9,10 @@ > /* #define DEBUG */ > > #include <linux/input.h> > +#include <linux/limits.h> > #include <linux/module.h> > #include <linux/mutex.h> > +#include <linux/overflow.h> > #include <linux/sched.h> > #include <linux/slab.h> > > @@ -315,9 +317,8 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) > return -EINVAL; > } > > - ff_dev_size = sizeof(struct ff_device) + > - max_effects * sizeof(struct file *); > - if (ff_dev_size < max_effects) /* overflow */ > + ff_dev_size = struct_size(ff, effect_owners, max_effects); > + if (ff_dev_size == SIZE_MAX) /* overflow */ > return -EINVAL; > > ff = kzalloc(ff_dev_size, GFP_KERNEL); > -- > 2.25.1 > Yup, thanks. This looks right to me. Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> -- Kees Cook