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?