* [PATCH 0/3] mm/mseal: further cleanups
@ 2026-07-16 13:43 Lorenzo Stoakes (ARM)
2026-07-16 13:43 ` [PATCH 1/3] mm/mseal: remove superfluous comments, fix confusion around mm Lorenzo Stoakes (ARM)
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-16 13:43 UTC (permalink / raw)
To: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko
Cc: linux-mm, linux-kernel, linux-fsdevel, Lorenzo Stoakes (ARM)
The mseal implementation is still rather confusing, so tighten things up a
little.
The only user of do_mseal() outside of the system call is the MMAP_PAGE_ZERO
process personality - retain better control over how mseal is utilised by
providing mseal_mmap_page_zero() for this instead.
The comments are overly long and confusion, so cut them down so they're a lot
clearer.
Remove confusing mm_struct params (mseal can not be used on remote mm's) and
wrap the actual system call logic into the system call declaration.
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
---
Lorenzo Stoakes (ARM) (3):
mm/mseal: remove superfluous comments, fix confusion around mm
mm/mseal: limit scope of mseal address zero to address zero
mm/mseal: remove further superfluous comments, do_mseal()
fs/binfmt_elf.c | 7 +--
include/linux/mm.h | 8 +--
mm/mseal.c | 156 ++++++++++++++++++-----------------------------------
3 files changed, 56 insertions(+), 115 deletions(-)
---
base-commit: 59c684a9908d2e6f7a791f7f033eae57ec2b3a61
change-id: 20260716-mseal-fixups-131ad0939de2
Cheers,
--
Lorenzo Stoakes (ARM) <ljs@kernel.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] mm/mseal: remove superfluous comments, fix confusion around mm
2026-07-16 13:43 [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
@ 2026-07-16 13:43 ` Lorenzo Stoakes (ARM)
2026-07-16 15:00 ` Pedro Falcato
2026-07-16 13:43 ` [PATCH 2/3] mm/mseal: limit scope of mseal address zero to address zero Lorenzo Stoakes (ARM)
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-16 13:43 UTC (permalink / raw)
To: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko
Cc: linux-mm, linux-kernel, linux-fsdevel, Lorenzo Stoakes (ARM)
Remove comment blocks that don't add value and eliminate any confusion
about whether or not we permit mseal()'ing of remote mm's by explicitly
referencing current->mm consistently.
Also avoid ugly goto by using an else branch.
No functional change intended.
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
---
mm/mseal.c | 48 ++++++++----------------------------------------
1 file changed, 8 insertions(+), 40 deletions(-)
diff --git a/mm/mseal.c b/mm/mseal.c
index 9781647483d1..207fea89c61e 100644
--- a/mm/mseal.c
+++ b/mm/mseal.c
@@ -16,28 +16,7 @@
#include <linux/sched.h>
#include "internal.h"
-/*
- * mseal() disallows an input range which contain unmapped ranges (VMA holes).
- *
- * It disallows unmapped regions from start to end whether they exist at the
- * start, in the middle, or at the end of the range, or any combination thereof.
- *
- * This is because after sealing a range, there's nothing to stop memory mapping
- * of ranges in the remaining gaps later, meaning that the user might then
- * wrongly consider the entirety of the mseal()'d range to be sealed when it
- * in fact isn't.
- */
-
-/*
- * Does the [start, end) range contain any unmapped memory?
- *
- * We ensure that:
- * - start is part of a valid VMA.
- * - end is part of a valid VMA.
- * - no gap (unallocated memory) exists between start and end.
- */
-static bool range_contains_unmapped(struct mm_struct *mm,
- unsigned long start, unsigned long end)
+static bool range_contains_unmapped(unsigned long start, unsigned long end)
{
struct vm_area_struct *vma;
unsigned long prev_end = start;
@@ -53,11 +32,10 @@ static bool range_contains_unmapped(struct mm_struct *mm,
return prev_end < end;
}
-static int mseal_apply(struct mm_struct *mm,
- unsigned long start, unsigned long end)
+static int mseal_apply(unsigned long start, unsigned long end)
{
struct vm_area_struct *vma, *prev;
- VMA_ITERATOR(vmi, mm, start);
+ VMA_ITERATOR(vmi, current->mm, start);
/* We know there are no gaps so this will be non-NULL. */
vma = vma_iter_load(&vmi);
@@ -145,7 +123,6 @@ int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
size_t len;
int ret = 0;
unsigned long end;
- struct mm_struct *mm = current->mm;
/* Verify flags not set. */
if (flags)
@@ -167,24 +144,15 @@ int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
if (end == start)
return 0;
- if (mmap_write_lock_killable(mm))
+ if (mmap_write_lock_killable(current->mm))
return -EINTR;
- if (range_contains_unmapped(mm, start, end)) {
+ if (range_contains_unmapped(start, end))
ret = -ENOMEM;
- goto out;
- }
-
- /*
- * Second pass, this should success, unless there are errors
- * from vma_modify_flags, e.g. merge/split error, or process
- * reaching the max supported VMAs, however, those cases shall
- * be rare.
- */
- ret = mseal_apply(mm, start, end);
+ else
+ ret = mseal_apply(start, end);
-out:
- mmap_write_unlock(mm);
+ mmap_write_unlock(current->mm);
return ret;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] mm/mseal: limit scope of mseal address zero to address zero
2026-07-16 13:43 [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
2026-07-16 13:43 ` [PATCH 1/3] mm/mseal: remove superfluous comments, fix confusion around mm Lorenzo Stoakes (ARM)
@ 2026-07-16 13:43 ` Lorenzo Stoakes (ARM)
2026-07-16 15:06 ` Pedro Falcato
2026-07-16 13:43 ` [PATCH 3/3] mm/mseal: remove further superfluous comments, do_mseal() Lorenzo Stoakes (ARM)
2026-07-16 13:48 ` [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
3 siblings, 1 reply; 10+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-16 13:43 UTC (permalink / raw)
To: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko
Cc: linux-mm, linux-kernel, linux-fsdevel, Lorenzo Stoakes (ARM)
Commit 44f65d900698 ("binfmt_elf: mseal address zero") unconditionally
provided do_mseal() to any internal kernel caller in order to address a
corner case slated for possible removal.
It also incorrectly attempts to mseal() without checking to see whether the
mapping even succeeded.
Restrict the scope to the corner case by providing mseal_mmap_page_zero()
which asserts the MMAP_PAGE_ZERO personality.
Avoid unnecessary checks in the start, end range by abstracting the actual
mseal()'ing to mseal() and have mseal_mmap_page_zero() call that instead.
Only try to seal the VMA if we mapped the VMA.
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
---
fs/binfmt_elf.c | 7 ++-----
include/linux/mm.h | 8 ++------
mm/mseal.c | 48 +++++++++++++++++++++++++++++++++++-------------
3 files changed, 39 insertions(+), 24 deletions(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 16a56b6b3f6c..e3131a311995 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1353,11 +1353,8 @@ static int load_elf_binary(struct linux_binprm *bprm)
emulate the SVr4 behavior. Sigh. */
error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, 0);
-
- retval = do_mseal(0, PAGE_SIZE, 0);
- if (retval)
- pr_warn_ratelimited("pid=%d, couldn't seal address 0, ret=%d.\n",
- task_pid_nr(current), retval);
+ if (!error)
+ mseal_mmap_page_zero();
}
regs = current_pt_regs();
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 550fb92957d1..87feaa5a2b78 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -5291,13 +5291,9 @@ int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *
int reserve_mem_release_by_name(const char *name);
#ifdef CONFIG_64BIT
-int do_mseal(unsigned long start, size_t len_in, unsigned long flags);
+void mseal_mmap_page_zero(void);
#else
-static inline int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
-{
- /* noop on 32 bit */
- return 0;
-}
+static inline void mseal_mmap_page_zero(void) {}
#endif
/*
diff --git a/mm/mseal.c b/mm/mseal.c
index 207fea89c61e..5930551d84f2 100644
--- a/mm/mseal.c
+++ b/mm/mseal.c
@@ -32,7 +32,7 @@ static bool range_contains_unmapped(unsigned long start, unsigned long end)
return prev_end < end;
}
-static int mseal_apply(unsigned long start, unsigned long end)
+static int __mseal(unsigned long start, unsigned long end)
{
struct vm_area_struct *vma, *prev;
VMA_ITERATOR(vmi, current->mm, start);
@@ -66,6 +66,38 @@ static int mseal_apply(unsigned long start, unsigned long end)
return 0;
}
+static int mseal(unsigned long start, unsigned long end)
+{
+ int err;
+
+ err = mmap_write_lock_killable(current->mm);
+ if (err)
+ return err;
+ if (range_contains_unmapped(start, end))
+ err = -ENOMEM;
+ else
+ err = __mseal(start, end);
+ mmap_write_unlock(current->mm);
+ return err;
+}
+
+/**
+ * mseal_mmap_page_zero() - If the MMAP_PAGE_ZERO personality is set, mseal()
+ * the page mapped at address zero.
+ */
+void mseal_mmap_page_zero(void)
+{
+ int err;
+
+ if (WARN_ON_ONCE(!(current->personality & MMAP_PAGE_ZERO)))
+ return;
+
+ err = mseal(0, PAGE_SIZE);
+ if (err)
+ pr_warn_ratelimited("pid=%d, couldn't seal address 0, ret=%d.\n",
+ task_pid_nr(current), err);
+}
+
/*
* mseal(2) seals the VM's meta data from
* selected syscalls.
@@ -118,10 +150,9 @@ static int mseal_apply(unsigned long start, unsigned long end)
*
* unseal() is not supported.
*/
-int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
+static int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
{
size_t len;
- int ret = 0;
unsigned long end;
/* Verify flags not set. */
@@ -144,16 +175,7 @@ int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
if (end == start)
return 0;
- if (mmap_write_lock_killable(current->mm))
- return -EINTR;
-
- if (range_contains_unmapped(start, end))
- ret = -ENOMEM;
- else
- ret = mseal_apply(start, end);
-
- mmap_write_unlock(current->mm);
- return ret;
+ return mseal(start, end);
}
SYSCALL_DEFINE3(mseal, unsigned long, start, size_t, len, unsigned long,
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] mm/mseal: remove further superfluous comments, do_mseal()
2026-07-16 13:43 [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
2026-07-16 13:43 ` [PATCH 1/3] mm/mseal: remove superfluous comments, fix confusion around mm Lorenzo Stoakes (ARM)
2026-07-16 13:43 ` [PATCH 2/3] mm/mseal: limit scope of mseal address zero to address zero Lorenzo Stoakes (ARM)
@ 2026-07-16 13:43 ` Lorenzo Stoakes (ARM)
2026-07-16 15:09 ` Pedro Falcato
2026-07-16 13:48 ` [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
3 siblings, 1 reply; 10+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-16 13:43 UTC (permalink / raw)
To: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko
Cc: linux-mm, linux-kernel, linux-fsdevel, Lorenzo Stoakes (ARM)
There's no need to abstract do_mseal() any longer so put the system call
implementation in the system call declaration.
The comment around do_mseal() is strangely formatted, overly long and adds
a lot of superfluous information that the code already provides, so boil it
down to the essentials.
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
---
mm/mseal.c | 74 ++++++++++++++------------------------------------------------
1 file changed, 16 insertions(+), 58 deletions(-)
diff --git a/mm/mseal.c b/mm/mseal.c
index 5930551d84f2..d01ab35d3f0f 100644
--- a/mm/mseal.c
+++ b/mm/mseal.c
@@ -99,60 +99,24 @@ void mseal_mmap_page_zero(void)
}
/*
- * mseal(2) seals the VM's meta data from
- * selected syscalls.
+ * Seal VMAs in the specified input range to prevent an attacker replacing what
+ * is mapped in the range with something else.
*
- * addr/len: VM address range.
+ * Disallows:
+ * - VMA unmapping, remapping or shrinking.
+ * - Overwriting the VMA with another one via mmap(), mremap() or similar.
+ * - Alteration of properties via mprotect()/pkey_mprotect().
+ * - Destructive madvise() behaviours (like MADV_DONTNEED) on anonymous read-only
+ * ranges.
*
- * The address range by addr/len must meet:
- * start (addr) must be in a valid VMA.
- * end (addr + len) must be in a valid VMA.
- * no gap (unallocated memory) between start and end.
- * start (addr) must be page aligned.
+ * Since unmapped ranges can be mapped at any time, the input range must span
+ * mapped ranges only.
*
- * len: len will be page aligned implicitly.
- *
- * Below VMA operations are blocked after sealing.
- * 1> Unmapping, moving to another location, and shrinking
- * the size, via munmap() and mremap(), can leave an empty
- * space, therefore can be replaced with a VMA with a new
- * set of attributes.
- * 2> Moving or expanding a different vma into the current location,
- * via mremap().
- * 3> Modifying a VMA via mmap(MAP_FIXED).
- * 4> Size expansion, via mremap(), does not appear to pose any
- * specific risks to sealed VMAs. It is included anyway because
- * the use case is unclear. In any case, users can rely on
- * merging to expand a sealed VMA.
- * 5> mprotect and pkey_mprotect.
- * 6> Some destructive madvice() behavior (e.g. MADV_DONTNEED)
- * for anonymous memory, when users don't have write permission to the
- * memory. Those behaviors can alter region contents by discarding pages,
- * effectively a memset(0) for anonymous memory.
- *
- * flags: reserved.
- *
- * return values:
- * zero: success.
- * -EINVAL:
- * invalid input flags.
- * start address is not page aligned.
- * Address range (start + len) overflow.
- * -ENOMEM:
- * addr is not a valid address (not allocated).
- * end (start + len) is not a valid address.
- * a gap (unallocated memory) between start and end.
- * -EPERM:
- * - In 32 bit architecture, sealing is not supported.
- * Note:
- * user can call mseal(2) multiple times, adding a seal on an
- * already sealed memory is a no-action (no error).
- *
- * unseal() is not supported.
+ * The flags parameter is currently reserved.
*/
-static int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
+SYSCALL_DEFINE3(mseal, unsigned long, start, size_t, len, unsigned long, flags)
{
- size_t len;
+ size_t len_aligned;
unsigned long end;
/* Verify flags not set. */
@@ -163,12 +127,12 @@ static int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
if (!PAGE_ALIGNED(start))
return -EINVAL;
- len = PAGE_ALIGN(len_in);
+ len_aligned = PAGE_ALIGN(len);
/* Check to see whether len was rounded up from small -ve to zero. */
- if (len_in && !len)
+ if (len && !len_aligned)
return -EINVAL;
- end = start + len;
+ end = start + len_aligned;
if (end < start)
return -EINVAL;
@@ -177,9 +141,3 @@ static int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
return mseal(start, end);
}
-
-SYSCALL_DEFINE3(mseal, unsigned long, start, size_t, len, unsigned long,
- flags)
-{
- return do_mseal(start, len, flags);
-}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] mm/mseal: further cleanups
2026-07-16 13:43 [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
` (2 preceding siblings ...)
2026-07-16 13:43 ` [PATCH 3/3] mm/mseal: remove further superfluous comments, do_mseal() Lorenzo Stoakes (ARM)
@ 2026-07-16 13:48 ` Lorenzo Stoakes (ARM)
3 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-16 13:48 UTC (permalink / raw)
To: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko
Cc: linux-mm, linux-kernel, linux-fsdevel
On Thu, Jul 16, 2026 at 02:43:08PM +0100, Lorenzo Stoakes (ARM) wrote:
> The mseal implementation is still rather confusing, so tighten things up a
> little.
>
> The only user of do_mseal() outside of the system call is the MMAP_PAGE_ZERO
> process personality - retain better control over how mseal is utilised by
> providing mseal_mmap_page_zero() for this instead.
>
> The comments are overly long and confusion, so cut them down so they're a lot
> clearer.
s/confusion/confusing/ :)
>
> Remove confusing mm_struct params (mseal can not be used on remote mm's) and
> wrap the actual system call logic into the system call declaration.
>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> Lorenzo Stoakes (ARM) (3):
> mm/mseal: remove superfluous comments, fix confusion around mm
> mm/mseal: limit scope of mseal address zero to address zero
> mm/mseal: remove further superfluous comments, do_mseal()
>
> fs/binfmt_elf.c | 7 +--
> include/linux/mm.h | 8 +--
> mm/mseal.c | 156 ++++++++++++++++++-----------------------------------
> 3 files changed, 56 insertions(+), 115 deletions(-)
> ---
> base-commit: 59c684a9908d2e6f7a791f7f033eae57ec2b3a61
> change-id: 20260716-mseal-fixups-131ad0939de2
>
> Cheers,
> --
> Lorenzo Stoakes (ARM) <ljs@kernel.org>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] mm/mseal: remove superfluous comments, fix confusion around mm
2026-07-16 13:43 ` [PATCH 1/3] mm/mseal: remove superfluous comments, fix confusion around mm Lorenzo Stoakes (ARM)
@ 2026-07-16 15:00 ` Pedro Falcato
0 siblings, 0 replies; 10+ messages in thread
From: Pedro Falcato @ 2026-07-16 15:00 UTC (permalink / raw)
To: Lorenzo Stoakes (ARM)
Cc: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Alexander Viro, Christian Brauner, Jan Kara, Kees Cook,
David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko, linux-mm, linux-kernel, linux-fsdevel
On Thu, Jul 16, 2026 at 02:43:09PM +0100, Lorenzo Stoakes (ARM) wrote:
> Remove comment blocks that don't add value and eliminate any confusion
> about whether or not we permit mseal()'ing of remote mm's by explicitly
> referencing current->mm consistently.
>
> Also avoid ugly goto by using an else branch.
>
> No functional change intended.
>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
--
Pedro
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] mm/mseal: limit scope of mseal address zero to address zero
2026-07-16 13:43 ` [PATCH 2/3] mm/mseal: limit scope of mseal address zero to address zero Lorenzo Stoakes (ARM)
@ 2026-07-16 15:06 ` Pedro Falcato
2026-07-16 15:38 ` Lorenzo Stoakes (ARM)
0 siblings, 1 reply; 10+ messages in thread
From: Pedro Falcato @ 2026-07-16 15:06 UTC (permalink / raw)
To: Lorenzo Stoakes (ARM)
Cc: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Alexander Viro, Christian Brauner, Jan Kara, Kees Cook,
David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko, linux-mm, linux-kernel, linux-fsdevel
On Thu, Jul 16, 2026 at 02:43:10PM +0100, Lorenzo Stoakes (ARM) wrote:
> Commit 44f65d900698 ("binfmt_elf: mseal address zero") unconditionally
> provided do_mseal() to any internal kernel caller in order to address a
> corner case slated for possible removal.
>
> It also incorrectly attempts to mseal() without checking to see whether the
> mapping even succeeded.
>
> Restrict the scope to the corner case by providing mseal_mmap_page_zero()
> which asserts the MMAP_PAGE_ZERO personality.
>
> Avoid unnecessary checks in the start, end range by abstracting the actual
> mseal()'ing to mseal() and have mseal_mmap_page_zero() call that instead.
>
> Only try to seal the VMA if we mapped the VMA.
>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> fs/binfmt_elf.c | 7 ++-----
> include/linux/mm.h | 8 ++------
> mm/mseal.c | 48 +++++++++++++++++++++++++++++++++++-------------
> 3 files changed, 39 insertions(+), 24 deletions(-)
>
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index 16a56b6b3f6c..e3131a311995 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -1353,11 +1353,8 @@ static int load_elf_binary(struct linux_binprm *bprm)
> emulate the SVr4 behavior. Sigh. */
> error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
> MAP_FIXED | MAP_PRIVATE, 0);
I think pedantically load_elf_binary() should error out on mmap error, no?
Not that this personality is used in the big 2026 however...
> -
> - retval = do_mseal(0, PAGE_SIZE, 0);
> - if (retval)
> - pr_warn_ratelimited("pid=%d, couldn't seal address 0, ret=%d.\n",
> - task_pid_nr(current), retval);
> + if (!error)
> + mseal_mmap_page_zero();
> }
>
> regs = current_pt_regs();
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 550fb92957d1..87feaa5a2b78 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -5291,13 +5291,9 @@ int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *
> int reserve_mem_release_by_name(const char *name);
>
> #ifdef CONFIG_64BIT
> -int do_mseal(unsigned long start, size_t len_in, unsigned long flags);
> +void mseal_mmap_page_zero(void);
> #else
> -static inline int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
> -{
> - /* noop on 32 bit */
> - return 0;
> -}
> +static inline void mseal_mmap_page_zero(void) {}
> #endif
>
> /*
> diff --git a/mm/mseal.c b/mm/mseal.c
> index 207fea89c61e..5930551d84f2 100644
> --- a/mm/mseal.c
> +++ b/mm/mseal.c
> @@ -32,7 +32,7 @@ static bool range_contains_unmapped(unsigned long start, unsigned long end)
> return prev_end < end;
> }
>
> -static int mseal_apply(unsigned long start, unsigned long end)
> +static int __mseal(unsigned long start, unsigned long end)
Why? I think the previous name is perfectly cromulent.
> {
> struct vm_area_struct *vma, *prev;
> VMA_ITERATOR(vmi, current->mm, start);
> @@ -66,6 +66,38 @@ static int mseal_apply(unsigned long start, unsigned long end)
> return 0;
> }
>
> +static int mseal(unsigned long start, unsigned long end)
I don't like that you go start - end on a function called "mseal". The actual
system call goes start - len. It just looks confusing :) So either rename it
to mseal_range(), or make it take a start, length pair.
The overall spirit of the change LGTM however.
--
Pedro
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] mm/mseal: remove further superfluous comments, do_mseal()
2026-07-16 13:43 ` [PATCH 3/3] mm/mseal: remove further superfluous comments, do_mseal() Lorenzo Stoakes (ARM)
@ 2026-07-16 15:09 ` Pedro Falcato
2026-07-16 15:13 ` Lorenzo Stoakes (ARM)
0 siblings, 1 reply; 10+ messages in thread
From: Pedro Falcato @ 2026-07-16 15:09 UTC (permalink / raw)
To: Lorenzo Stoakes (ARM)
Cc: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Alexander Viro, Christian Brauner, Jan Kara, Kees Cook,
David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko, linux-mm, linux-kernel, linux-fsdevel
On Thu, Jul 16, 2026 at 02:43:11PM +0100, Lorenzo Stoakes (ARM) wrote:
> There's no need to abstract do_mseal() any longer so put the system call
> implementation in the system call declaration.
This looks great!
>
> The comment around do_mseal() is strangely formatted, overly long and adds
> a lot of superfluous information that the code already provides, so boil it
> down to the essentials.
But I would much rather we delete the whole comment (like Leon's patch did,
per my request). Do you disagree?
>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Anyway,
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
--
Pedro
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] mm/mseal: remove further superfluous comments, do_mseal()
2026-07-16 15:09 ` Pedro Falcato
@ 2026-07-16 15:13 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-16 15:13 UTC (permalink / raw)
To: Pedro Falcato
Cc: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Alexander Viro, Christian Brauner, Jan Kara, Kees Cook,
David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko, linux-mm, linux-kernel, linux-fsdevel
On Thu, Jul 16, 2026 at 04:09:14PM +0100, Pedro Falcato wrote:
> On Thu, Jul 16, 2026 at 02:43:11PM +0100, Lorenzo Stoakes (ARM) wrote:
> > There's no need to abstract do_mseal() any longer so put the system call
> > implementation in the system call declaration.
>
> This looks great!
>
> >
> > The comment around do_mseal() is strangely formatted, overly long and adds
> > a lot of superfluous information that the code already provides, so boil it
> > down to the essentials.
>
> But I would much rather we delete the whole comment (like Leon's patch did,
> per my request). Do you disagree?
I would like us to retain the information I added yes. Removing that is not
really helpful I don't think.
>
> >
> > Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
>
> Anyway,
>
> Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Thanks!
>
> --
> Pedro
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] mm/mseal: limit scope of mseal address zero to address zero
2026-07-16 15:06 ` Pedro Falcato
@ 2026-07-16 15:38 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-16 15:38 UTC (permalink / raw)
To: Pedro Falcato
Cc: Andrew Morton, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Alexander Viro, Christian Brauner, Jan Kara, Kees Cook,
David Hildenbrand, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko, linux-mm, linux-kernel, linux-fsdevel
On Thu, Jul 16, 2026 at 04:06:20PM +0100, Pedro Falcato wrote:
> On Thu, Jul 16, 2026 at 02:43:10PM +0100, Lorenzo Stoakes (ARM) wrote:
> > Commit 44f65d900698 ("binfmt_elf: mseal address zero") unconditionally
> > provided do_mseal() to any internal kernel caller in order to address a
> > corner case slated for possible removal.
> >
> > It also incorrectly attempts to mseal() without checking to see whether the
> > mapping even succeeded.
> >
> > Restrict the scope to the corner case by providing mseal_mmap_page_zero()
> > which asserts the MMAP_PAGE_ZERO personality.
> >
> > Avoid unnecessary checks in the start, end range by abstracting the actual
> > mseal()'ing to mseal() and have mseal_mmap_page_zero() call that instead.
> >
> > Only try to seal the VMA if we mapped the VMA.
> >
> > Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> > ---
> > fs/binfmt_elf.c | 7 ++-----
> > include/linux/mm.h | 8 ++------
> > mm/mseal.c | 48 +++++++++++++++++++++++++++++++++++-------------
> > 3 files changed, 39 insertions(+), 24 deletions(-)
> >
> > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> > index 16a56b6b3f6c..e3131a311995 100644
> > --- a/fs/binfmt_elf.c
> > +++ b/fs/binfmt_elf.c
> > @@ -1353,11 +1353,8 @@ static int load_elf_binary(struct linux_binprm *bprm)
> > emulate the SVr4 behavior. Sigh. */
> > error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
> > MAP_FIXED | MAP_PRIVATE, 0);
>
> I think pedantically load_elf_binary() should error out on mmap error, no?
> Not that this personality is used in the big 2026 however...
I'm not sure I implied otherwise?
But yes I'm aware, the point is to not try to mseal() an unmapped range knowingly.
The fact we 'get away with it' now is irrelevant.
I can update the commit message if a respin is necessary to spell this out (I
thought it was obvious).
>
> > -
> > - retval = do_mseal(0, PAGE_SIZE, 0);
> > - if (retval)
> > - pr_warn_ratelimited("pid=%d, couldn't seal address 0, ret=%d.\n",
> > - task_pid_nr(current), retval);
> > + if (!error)
> > + mseal_mmap_page_zero();
> > }
> >
> > regs = current_pt_regs();
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index 550fb92957d1..87feaa5a2b78 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -5291,13 +5291,9 @@ int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *
> > int reserve_mem_release_by_name(const char *name);
> >
> > #ifdef CONFIG_64BIT
> > -int do_mseal(unsigned long start, size_t len_in, unsigned long flags);
> > +void mseal_mmap_page_zero(void);
> > #else
> > -static inline int do_mseal(unsigned long start, size_t len_in, unsigned long flags)
> > -{
> > - /* noop on 32 bit */
> > - return 0;
> > -}
> > +static inline void mseal_mmap_page_zero(void) {}
> > #endif
> >
> > /*
> > diff --git a/mm/mseal.c b/mm/mseal.c
> > index 207fea89c61e..5930551d84f2 100644
> > --- a/mm/mseal.c
> > +++ b/mm/mseal.c
> > @@ -32,7 +32,7 @@ static bool range_contains_unmapped(unsigned long start, unsigned long end)
> > return prev_end < end;
> > }
> >
> > -static int mseal_apply(unsigned long start, unsigned long end)
> > +static int __mseal(unsigned long start, unsigned long end)
>
> Why? I think the previous name is perfectly cromulent.
Because this is what actually mseal()'s, the _apply is not really useful.
The __ is because it's unlocked.
The point here is to eliminate useless indirection, so calling the function that
mseals, 'mseal' seems sensible.
>
> > {
> > struct vm_area_struct *vma, *prev;
> > VMA_ITERATOR(vmi, current->mm, start);
> > @@ -66,6 +66,38 @@ static int mseal_apply(unsigned long start, unsigned long end)
> > return 0;
> > }
> >
> > +static int mseal(unsigned long start, unsigned long end)
>
> I don't like that you go start - end on a function called "mseal". The actual
> system call goes start - len. It just looks confusing :) So either rename it
> to mseal_range(), or make it take a start, length pair.
I'm not sure I really understand the confusion (I suppose you're equally
confused by the lack of flags parameter?),
I find it silly that we avoid function names because a system call of the same
name exists.
But I guess I can rename it to mseal_range() since I don't want the series
blocked on silly naming issues.
The reason for passing end (which was already the case) is that the syscall
already calculates it and we need it to do the actual mseal.
>
> The overall spirit of the change LGTM however.
OK.
>
> --
> Pedro
Thanks, Lorenzo
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-07-16 15:38 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 13:43 [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
2026-07-16 13:43 ` [PATCH 1/3] mm/mseal: remove superfluous comments, fix confusion around mm Lorenzo Stoakes (ARM)
2026-07-16 15:00 ` Pedro Falcato
2026-07-16 13:43 ` [PATCH 2/3] mm/mseal: limit scope of mseal address zero to address zero Lorenzo Stoakes (ARM)
2026-07-16 15:06 ` Pedro Falcato
2026-07-16 15:38 ` Lorenzo Stoakes (ARM)
2026-07-16 13:43 ` [PATCH 3/3] mm/mseal: remove further superfluous comments, do_mseal() Lorenzo Stoakes (ARM)
2026-07-16 15:09 ` Pedro Falcato
2026-07-16 15:13 ` Lorenzo Stoakes (ARM)
2026-07-16 13:48 ` [PATCH 0/3] mm/mseal: further cleanups Lorenzo Stoakes (ARM)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox