On Sat, Nov 19, 2022 at 05:40:04PM -0800, Eric Biggers wrote: > On Sun, Nov 20, 2022 at 12:59:07AM +0100, Jason A. Donenfeld wrote: > > Hi Eric, > > > > On Sat, Nov 19, 2022 at 12:39:26PM -0800, Eric Biggers wrote: > > > On Sat, Nov 19, 2022 at 01:09:27PM +0100, Jason A. Donenfeld wrote: > > > > +SYSCALL_DEFINE3(vgetrandom_alloc, unsigned long __user *, num, > > > > + unsigned long __user *, size_per_each, unsigned int, flags) > > > > +{ > > > > + unsigned long alloc_size; > > > > + unsigned long num_states; > > > > + unsigned long pages_addr; > > > > + int ret; > > > > + > > > > + if (flags) > > > > + return -EINVAL; > > > > + > > > > + if (get_user(num_states, num)) > > > > + return -EFAULT; > > > > + > > > > + alloc_size = size_mul(num_states, sizeof(struct vgetrandom_state)); > > > > + if (alloc_size == SIZE_MAX) > > > > + return -EOVERFLOW; > > > > + alloc_size = roundup(alloc_size, PAGE_SIZE); > > > > > > Small detail: the roundup to PAGE_SIZE can make alloc_size overflow to 0. > > > > > > Also, 'roundup(alloc_size, PAGE_SIZE)' could be 'PAGE_ALIGN(alloc_size)'. > > > > Good catch, thanks. So perhaps this? > > > > alloc_size = size_mul(num_states, sizeof(struct vgetrandom_state)); > > if (alloc_size > SIZE_MAX - PAGE_SIZE + 1) > > return -EOVERFLOW; > > alloc_size = PAGE_ALIGN(alloc_size); > > > > Does that look right? > > Yes. Maybe use 'SIZE_MAX & PAGE_MASK'? > > Another alternative is the following: > > if (num_states > > (SIZE_MAX & PAGE_MASK) / sizeof(struct vgetrandom_state)) > return -EOVERFLOW; > alloc_size = PAGE_ALIGN(num_states * sizeof(struct vgetrandom_state)); Thanks, that's much nicer. Jason