On Wed, Nov 09, 2022 at 03:23:02PM +0500, Muhammad Usama Anjum wrote: ... > + > +static long do_pagemap_sd_cmd(struct mm_struct *mm, struct pagemap_scan_arg *arg) > +{ > + struct mmu_notifier_range range; > + unsigned long __user start, end; > + struct pagemap_scan_private p; > + int ret; > + > + start = (unsigned long)untagged_addr(arg->start); > + if ((!IS_ALIGNED(start, PAGE_SIZE)) || (!access_ok((void __user *)start, arg->len))) > + return -EINVAL; > + > + if (IS_GET_OP(arg) && > + ((arg->vec_len == 0) || (!access_ok((struct page_region *)arg->vec, arg->vec_len)))) > + return -ENOMEM; > + > + if (IS_SD_OP(arg) && ((arg->required_mask & PAGEMAP_NONSD_OP_MASK) || > + (arg->anyof_mask & PAGEMAP_NONSD_OP_MASK))) > + return -EINVAL; > + > + end = start + arg->len; > + p.max_pages = arg->max_pages; > + p.found_pages = 0; > + p.flags = arg->flags; > + p.required_mask = arg->required_mask; > + p.anyof_mask = arg->anyof_mask; > + p.excluded_mask = arg->excluded_mask; > + p.return_mask = arg->return_mask; > + p.vec_index = 0; > + p.vec_len = arg->vec_len; > + > + if (IS_GET_OP(arg)) { > + p.vec = vzalloc(arg->vec_len * sizeof(struct page_region)); > + if (!p.vec) > + return -ENOMEM; > + } else { > + p.vec = NULL; > + } Hi Muhammad! I'm really sorry for diving in such late (unfortunatelly too busy to step in yet). Anyway, while in general such interface looks reasonable here are few moments which really bothers me: as far as I undertstand you don't need vzalloc here, plain vmalloc should works as well since you copy only filled results back to userspace. Next -- there is no restriction on vec_len parameter, is not here a door for DoS from userspace? Say I could start a number of ioctl on same pagemap and try to allocate very big amount of vec_len in summay causing big pressure on kernel's memory. Or I miss something obvious here?