It turns out that, in apparent contradiction to the man page, and at odds with every other mremap() operation - we are allowed to specify an input addr, old_len range that spans any number of VMAs and any number of gaps, as long as we shrink that range to the point at which the new range spans only one. In order to accommodate this, adjust the remap validity check to account for this. Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@xxxxxxxxxx> Reported-by: kernel test robot <oliver.sang@xxxxxxxxx> Closes: https://lore.kernel.org/oe-lkp/202507201002.69144b74-lkp@xxxxxxxxx --- mm/mremap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm/mremap.c b/mm/mremap.c index 20844fb91755..11a8321a90b8 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -1339,11 +1339,18 @@ static int remap_is_valid(struct vma_remap_struct *vrm) (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP))) return -EINVAL; + /* + * We permit crossing of boundaries for the range being unmapped due to + * a shrink. + */ + if (vrm->remap_type == MREMAP_SHRINK) + old_len = new_len; + /* We can't remap across vm area boundaries */ if (old_len > vma->vm_end - addr) return -EFAULT; - if (new_len <= old_len) + if (new_len == old_len) return 0; /* Need to be careful about a growing mapping */ -- 2.50.1