On Tue, Oct 25, 2022 at 03:12:18PM -0300, Jason Gunthorpe wrote: > +static int iopt_check_iova(struct io_pagetable *iopt, unsigned long iova, > + unsigned long length) > +{ > + unsigned long last; > + > + lockdep_assert_held(&iopt->iova_rwsem); > + > + if ((iova & (iopt->iova_alignment - 1)) || > + (length & (iopt->iova_alignment - 1)) || !length) > + return -EINVAL; syzkaller noticed this length check is too late, if userpsace supplies an invalid length and asks for automatic IOVA allocation it will trigger a WARN_ON. @@ -177,8 +177,7 @@ static int iopt_check_iova(struct io_pagetable *iopt, unsigned long iova, lockdep_assert_held(&iopt->iova_rwsem); - if ((iova & (iopt->iova_alignment - 1)) || - (length & (iopt->iova_alignment - 1)) || !length) + if ((iova & (iopt->iova_alignment - 1))) return -EINVAL; if (check_add_overflow(iova, length - 1, &last)) @@ -248,6 +247,11 @@ static int iopt_alloc_area_pages(struct io_pagetable *iopt, } down_write(&iopt->iova_rwsem); + if ((length & (iopt->iova_alignment - 1)) || !length) { + rc = -EINVAL; + goto out_unlock; + } + if (flags & IOPT_ALLOC_IOVA) { /* Use the first entry to guess the ideal IOVA alignment */ elm = list_first_entry(pages_list, struct iopt_pages_list, And a test to cover it Jason