Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/mremap: refactor initial parameter sanity checks

We are currently checking some things later, and some things immediately.
Aggregate the checks and avoid ones that need not be made.

Simplify things by aligning lengths immediately. Defer setting the delta
parameter until later, which removes some duplicate code in the hugetlb
case.

We can safely perform the checks moved from mremap_to() to
check_mremap_params() because:

* If we set a new address via vrm_set_new_addr(), then this is guaranteed
to not overlap nor to position the new VMA past TASK_SIZE, so there's no
need to check these later.

* We can simply page align lengths immediately. We do not need to check for
overlap nor TASK_SIZE sanity after hugetlb alignment as this asserts
addresses are huge-aligned, then huge-aligns lengths, rounding down. This
means any existing overlap would have already been caught.

Moving things around like this lays the groundwork for subsequent changes
to permit operations on batches of VMAs.

No functional change intended.

Link: https://lkml.kernel.org/r/c862d625c98b1abd861c406f2bfad8baf3287f83.1752770784.git.lorenzo.stoakes@oracle.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Jann Horn <jannh@google.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Rik van Riel <riel@surriel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Lorenzo Stoakes and committed by
Andrew Morton
3215eace 000c0691

+14 -15
+14 -15
mm/mremap.c
··· 1413 1413 struct mm_struct *mm = current->mm; 1414 1414 unsigned long err; 1415 1415 1416 - /* Is the new length or address silly? */ 1417 - if (vrm->new_len > TASK_SIZE || 1418 - vrm->new_addr > TASK_SIZE - vrm->new_len) 1419 - return -EINVAL; 1420 - 1421 - if (vrm_overlaps(vrm)) 1422 - return -EINVAL; 1423 - 1424 1416 if (vrm->flags & MREMAP_FIXED) { 1425 1417 /* 1426 1418 * In mremap_to(). ··· 1517 1525 * for DOS-emu "duplicate shm area" thing. But 1518 1526 * a zero new-len is nonsensical. 1519 1527 */ 1520 - if (!PAGE_ALIGN(vrm->new_len)) 1528 + if (!vrm->new_len) 1529 + return -EINVAL; 1530 + 1531 + /* Is the new length or address silly? */ 1532 + if (vrm->new_len > TASK_SIZE || 1533 + vrm->new_addr > TASK_SIZE - vrm->new_len) 1521 1534 return -EINVAL; 1522 1535 1523 1536 /* Remainder of checks are for cases with specific new_addr. */ ··· 1539 1542 1540 1543 /* MREMAP_DONTUNMAP does not allow resizing in the process. */ 1541 1544 if (flags & MREMAP_DONTUNMAP && vrm->old_len != vrm->new_len) 1545 + return -EINVAL; 1546 + 1547 + /* Target VMA must not overlap source VMA. */ 1548 + if (vrm_overlaps(vrm)) 1542 1549 return -EINVAL; 1543 1550 1544 1551 /* ··· 1620 1619 */ 1621 1620 if (vrm->new_len > vrm->old_len) 1622 1621 return false; 1623 - 1624 - vrm_set_delta(vrm); 1625 1622 1626 1623 return true; 1627 1624 } ··· 1720 1721 struct vm_area_struct *vma; 1721 1722 unsigned long res; 1722 1723 1724 + vrm->old_len = PAGE_ALIGN(vrm->old_len); 1725 + vrm->new_len = PAGE_ALIGN(vrm->new_len); 1726 + 1723 1727 res = check_mremap_params(vrm); 1724 1728 if (res) 1725 1729 return res; 1726 - 1727 - vrm->old_len = PAGE_ALIGN(vrm->old_len); 1728 - vrm->new_len = PAGE_ALIGN(vrm->new_len); 1729 - vrm_set_delta(vrm); 1730 1730 1731 1731 if (mmap_write_lock_killable(mm)) 1732 1732 return -EINTR; ··· 1749 1751 goto out; 1750 1752 } 1751 1753 1754 + vrm_set_delta(vrm); 1752 1755 vrm->remap_type = vrm_remap_type(vrm); 1753 1756 1754 1757 /* Actually execute mremap. */