Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 825f019

Browse files
heatdTreehugger Robot
authored andcommitted
BACKPORT: mseal: replace can_modify_mm_madv with a vma variant
Replace can_modify_mm_madv() with a single vma variant, and associated checks in madvise. While we're at it, also invert the order of checks in: if (unlikely(is_ro_anon(vma) && !can_modify_vma(vma)) Checking if we can modify the vma itself (through vm_flags) is certainly cheaper than is_ro_anon() due to arch_vma_access_permitted() looking at e.g pkeys registers (with extra branches) in some architectures. This patch allows for partial madvise success when finding a sealed VMA, which historically has been allowed in Linux. Link: https://lkml.kernel.org/r/[email protected] Change-Id: I0808016433305eb5e663d1de1cc697cac2c12dd8 Signed-off-by: Pedro Falcato <[email protected]> Reviewed-by: Liam R. Howlett <[email protected]> Reviewed-by: Lorenzo Stoakes <[email protected]> Cc: Jeff Xu <[email protected]> Cc: Kees Cook <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Shuah Khan <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]> (cherry picked from commit 23c57d1)
1 parent d0653d6 commit 825f019

File tree

3 files changed

+14
-23
lines changed

3 files changed

+14
-23
lines changed

mm/internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,8 @@ static inline bool can_modify_vma(struct vm_area_struct *vma)
14861486
return true;
14871487
}
14881488

1489+
bool can_modify_vma_madv(struct vm_area_struct *vma, int behavior);
1490+
14891491
#else
14901492
static inline int can_do_mseal(unsigned long flags)
14911493
{
@@ -1509,5 +1511,10 @@ static inline bool can_modify_vma(struct vm_area_struct *vma)
15091511
return true;
15101512
}
15111513

1514+
static inline bool can_modify_vma_madv(struct vm_area_struct *vma, int behavior)
1515+
{
1516+
return true;
1517+
}
1518+
15121519
#endif
15131520
#endif /* __MM_INTERNAL_H */

mm/madvise.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,9 @@ static int madvise_vma_behavior(struct vm_area_struct *vma,
10901090
struct anon_vma_name *anon_name;
10911091
unsigned long new_flags = vma->vm_flags;
10921092

1093+
if (unlikely(!can_modify_vma_madv(vma, behavior)))
1094+
return -EPERM;
1095+
10931096
switch (behavior) {
10941097
case MADV_REMOVE:
10951098
return madvise_remove(vma, prev, start, end);
@@ -1508,21 +1511,11 @@ int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int beh
15081511
start = untagged_addr_remote(mm, start);
15091512
end = start + len;
15101513

1511-
/*
1512-
* Check if the address range is sealed for do_madvise().
1513-
* can_modify_mm_madv assumes we have acquired the lock on MM.
1514-
*/
1515-
if (unlikely(!can_modify_mm_madv(mm, start, end, behavior))) {
1516-
error = -EPERM;
1517-
goto out;
1518-
}
1519-
15201514
blk_start_plug(&plug);
15211515
error = madvise_walk_vmas(mm, start, end, behavior,
15221516
madvise_vma_behavior);
15231517
blk_finish_plug(&plug);
15241518

1525-
out:
15261519
if (write)
15271520
mmap_write_unlock(mm);
15281521
else

mm/mseal.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,15 @@ bool can_modify_mm(struct mm_struct *mm, unsigned long start, unsigned long end)
7676
}
7777

7878
/*
79-
* Check if the vmas of a memory range are allowed to be modified by madvise.
80-
* the memory ranger can have a gap (unallocated memory).
81-
* return true, if it is allowed.
79+
* Check if a vma is allowed to be modified by madvise.
8280
*/
83-
bool can_modify_mm_madv(struct mm_struct *mm, unsigned long start, unsigned long end,
84-
int behavior)
81+
bool can_modify_vma_madv(struct vm_area_struct *vma, int behavior)
8582
{
86-
struct vm_area_struct *vma;
87-
88-
VMA_ITERATOR(vmi, mm, start);
89-
9083
if (!is_madv_discard(behavior))
9184
return true;
9285

93-
/* going through each vma to check. */
94-
for_each_vma_range(vmi, vma, end)
95-
if (unlikely(is_ro_anon(vma) && !can_modify_vma(vma)))
96-
return false;
86+
if (unlikely(!can_modify_vma(vma) && is_ro_anon(vma)))
87+
return false;
9788

9889
/* Allow by default. */
9990
return true;

0 commit comments

Comments
 (0)