From: Catalin Marinas <catalin.marinas@arm.com>
To: David Hildenbrand <david@redhat.com>
Cc: "Joey Gouly" <joey.gouly@arm.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Lennart Poettering" <lennart@poettering.net>,
"Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>,
"Alexander Viro" <viro@zeniv.linux.org.uk>,
"Kees Cook" <keescook@chromium.org>,
"Szabolcs Nagy" <szabolcs.nagy@arm.com>,
"Mark Brown" <broonie@kernel.org>,
"Jeremy Linton" <jeremy.linton@arm.com>,
"Topi Miettinen" <toiwoton@gmail.com>,
linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
linux-abi-devel@lists.sourceforge.net, nd@arm.com,
shuah@kernel.org
Subject: Re: [PATCH v2 1/2] mm: Implement memory-deny-write-execute as a prctl
Date: Mon, 23 Jan 2023 12:19:30 +0000 [thread overview]
Message-ID: <Y857Uoq7fjO0lZ12@arm.com> (raw)
In-Reply-To: <4a1faf67-178e-c9ba-0db1-cf90408b0d7d@redhat.com>
On Mon, Jan 23, 2023 at 12:45:50PM +0100, David Hildenbrand wrote:
> On 19.01.23 17:03, Joey Gouly wrote:
> > The aim of such policy is to prevent a user task from creating an
> > executable mapping that is also writeable.
> >
> > An example of mmap() returning -EACCESS if the policy is enabled:
> >
> > mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, 0, 0);
> >
> > Similarly, mprotect() would return -EACCESS below:
> >
> > addr = mmap(0, size, PROT_READ | PROT_EXEC, flags, 0, 0);
> > mprotect(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
> >
> > The BPF filter that systemd MDWE uses is stateless, and disallows
> > mprotect() with PROT_EXEC completely. This new prctl allows PROT_EXEC to
> > be enabled if it was already PROT_EXEC, which allows the following case:
> >
> > addr = mmap(0, size, PROT_READ | PROT_EXEC, flags, 0, 0);
> > mprotect(addr, size, PROT_READ | PROT_EXEC | PROT_BTI);
> >
> > where PROT_BTI enables branch tracking identification on arm64.
> >
> > Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> > Co-developed-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > ---
> > include/linux/mman.h | 34 ++++++++++++++++++++++++++++++++++
> > include/linux/sched/coredump.h | 6 +++++-
> > include/uapi/linux/prctl.h | 6 ++++++
> > kernel/sys.c | 33 +++++++++++++++++++++++++++++++++
> > mm/mmap.c | 10 ++++++++++
> > mm/mprotect.c | 5 +++++
> > 6 files changed, 93 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/mman.h b/include/linux/mman.h
> > index 58b3abd457a3..cee1e4b566d8 100644
> > --- a/include/linux/mman.h
> > +++ b/include/linux/mman.h
> > @@ -156,4 +156,38 @@ calc_vm_flag_bits(unsigned long flags)
> > }
> > unsigned long vm_commit_limit(void);
> > +
> > +/*
> > + * Denies creating a writable executable mapping or gaining executable permissions.
> > + *
> > + * This denies the following:
> > + *
> > + * a) mmap(PROT_WRITE | PROT_EXEC)
> > + *
> > + * b) mmap(PROT_WRITE)
> > + * mprotect(PROT_EXEC)
> > + *
> > + * c) mmap(PROT_WRITE)
> > + * mprotect(PROT_READ)
> > + * mprotect(PROT_EXEC)
> > + *
> > + * But allows the following:
> > + *
> > + * d) mmap(PROT_READ | PROT_EXEC)
> > + * mmap(PROT_READ | PROT_EXEC | PROT_BTI)
> > + */
>
> Shouldn't we clear VM_MAYEXEC at mmap() time such that we cannot set VM_EXEC
> anymore? In an ideal world, there would be no further mprotect changes
> required.
I don't think it works for this scenario. We don't want to disable
PROT_EXEC entirely, only disallow it if the mapping is not already
executable. The below should be allowed:
addr = mmap(0, size, PROT_READ | PROT_EXEC, flags, 0, 0);
mprotect(addr, size, PROT_READ | PROT_EXEC | PROT_BTI);
but IIUC what you meant, it fails if we cleared VM_MAYEXEC at mmap()
time.
We could clear VM_MAYEXEC if the mapping was made VM_WRITE (either by
mmap() or mprotect()) but IIRC we concluded that this should be an
additional prctl() flag. This series aims to be pretty much a drop-in
replacement for the systemd's MDWE SECCOMP feature (but allowing
PROT_BTI).
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Catalin Marinas <catalin.marinas@arm.com>
To: David Hildenbrand <david@redhat.com>
Cc: "Joey Gouly" <joey.gouly@arm.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Lennart Poettering" <lennart@poettering.net>,
"Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>,
"Alexander Viro" <viro@zeniv.linux.org.uk>,
"Kees Cook" <keescook@chromium.org>,
"Szabolcs Nagy" <szabolcs.nagy@arm.com>,
"Mark Brown" <broonie@kernel.org>,
"Jeremy Linton" <jeremy.linton@arm.com>,
"Topi Miettinen" <toiwoton@gmail.com>,
linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
linux-abi-devel@lists.sourceforge.net, nd@arm.com,
shuah@kernel.org
Subject: Re: [PATCH v2 1/2] mm: Implement memory-deny-write-execute as a prctl
Date: Mon, 23 Jan 2023 12:19:30 +0000 [thread overview]
Message-ID: <Y857Uoq7fjO0lZ12@arm.com> (raw)
In-Reply-To: <4a1faf67-178e-c9ba-0db1-cf90408b0d7d@redhat.com>
On Mon, Jan 23, 2023 at 12:45:50PM +0100, David Hildenbrand wrote:
> On 19.01.23 17:03, Joey Gouly wrote:
> > The aim of such policy is to prevent a user task from creating an
> > executable mapping that is also writeable.
> >
> > An example of mmap() returning -EACCESS if the policy is enabled:
> >
> > mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, 0, 0);
> >
> > Similarly, mprotect() would return -EACCESS below:
> >
> > addr = mmap(0, size, PROT_READ | PROT_EXEC, flags, 0, 0);
> > mprotect(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
> >
> > The BPF filter that systemd MDWE uses is stateless, and disallows
> > mprotect() with PROT_EXEC completely. This new prctl allows PROT_EXEC to
> > be enabled if it was already PROT_EXEC, which allows the following case:
> >
> > addr = mmap(0, size, PROT_READ | PROT_EXEC, flags, 0, 0);
> > mprotect(addr, size, PROT_READ | PROT_EXEC | PROT_BTI);
> >
> > where PROT_BTI enables branch tracking identification on arm64.
> >
> > Signed-off-by: Joey Gouly <joey.gouly@arm.com>
> > Co-developed-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > ---
> > include/linux/mman.h | 34 ++++++++++++++++++++++++++++++++++
> > include/linux/sched/coredump.h | 6 +++++-
> > include/uapi/linux/prctl.h | 6 ++++++
> > kernel/sys.c | 33 +++++++++++++++++++++++++++++++++
> > mm/mmap.c | 10 ++++++++++
> > mm/mprotect.c | 5 +++++
> > 6 files changed, 93 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/mman.h b/include/linux/mman.h
> > index 58b3abd457a3..cee1e4b566d8 100644
> > --- a/include/linux/mman.h
> > +++ b/include/linux/mman.h
> > @@ -156,4 +156,38 @@ calc_vm_flag_bits(unsigned long flags)
> > }
> > unsigned long vm_commit_limit(void);
> > +
> > +/*
> > + * Denies creating a writable executable mapping or gaining executable permissions.
> > + *
> > + * This denies the following:
> > + *
> > + * a) mmap(PROT_WRITE | PROT_EXEC)
> > + *
> > + * b) mmap(PROT_WRITE)
> > + * mprotect(PROT_EXEC)
> > + *
> > + * c) mmap(PROT_WRITE)
> > + * mprotect(PROT_READ)
> > + * mprotect(PROT_EXEC)
> > + *
> > + * But allows the following:
> > + *
> > + * d) mmap(PROT_READ | PROT_EXEC)
> > + * mmap(PROT_READ | PROT_EXEC | PROT_BTI)
> > + */
>
> Shouldn't we clear VM_MAYEXEC at mmap() time such that we cannot set VM_EXEC
> anymore? In an ideal world, there would be no further mprotect changes
> required.
I don't think it works for this scenario. We don't want to disable
PROT_EXEC entirely, only disallow it if the mapping is not already
executable. The below should be allowed:
addr = mmap(0, size, PROT_READ | PROT_EXEC, flags, 0, 0);
mprotect(addr, size, PROT_READ | PROT_EXEC | PROT_BTI);
but IIUC what you meant, it fails if we cleared VM_MAYEXEC at mmap()
time.
We could clear VM_MAYEXEC if the mapping was made VM_WRITE (either by
mmap() or mprotect()) but IIRC we concluded that this should be an
additional prctl() flag. This series aims to be pretty much a drop-in
replacement for the systemd's MDWE SECCOMP feature (but allowing
PROT_BTI).
--
Catalin
next prev parent reply other threads:[~2023-01-23 12:20 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-19 16:03 [PATCH v2 0/2] mm: In-kernel support for memory-deny-write-execute (MDWE) Joey Gouly
2023-01-19 16:03 ` Joey Gouly
2023-01-19 16:03 ` [PATCH v2 1/2] mm: Implement memory-deny-write-execute as a prctl Joey Gouly
2023-01-19 16:03 ` Joey Gouly
2023-01-23 11:45 ` David Hildenbrand
2023-01-23 11:45 ` David Hildenbrand
2023-01-23 12:19 ` Catalin Marinas [this message]
2023-01-23 12:19 ` Catalin Marinas
2023-01-23 12:53 ` David Hildenbrand
2023-01-23 12:53 ` David Hildenbrand
2023-01-23 16:04 ` Catalin Marinas
2023-01-23 16:04 ` Catalin Marinas
2023-01-23 16:10 ` David Hildenbrand
2023-01-23 16:10 ` David Hildenbrand
2023-01-23 16:22 ` Catalin Marinas
2023-01-23 16:22 ` Catalin Marinas
2023-01-23 17:48 ` Topi Miettinen
2023-01-23 17:48 ` Topi Miettinen
2023-03-07 13:01 ` Alexey Izbyshev
2023-03-07 13:01 ` Alexey Izbyshev
2023-03-08 12:36 ` Catalin Marinas
2023-03-08 12:36 ` Catalin Marinas
2023-01-19 16:03 ` [PATCH v2 2/2] kselftest: vm: add tests for memory-deny-write-execute Joey Gouly
2023-01-19 16:03 ` Joey Gouly
2023-03-01 16:35 ` Peter Xu
2023-03-01 16:35 ` Peter Xu
2023-03-02 11:07 ` Joey Gouly
2023-03-02 11:07 ` Joey Gouly
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y857Uoq7fjO0lZ12@arm.com \
--to=catalin.marinas@arm.com \
--cc=akpm@linux-foundation.org \
--cc=broonie@kernel.org \
--cc=david@redhat.com \
--cc=jeremy.linton@arm.com \
--cc=joey.gouly@arm.com \
--cc=keescook@chromium.org \
--cc=lennart@poettering.net \
--cc=linux-abi-devel@lists.sourceforge.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nd@arm.com \
--cc=shuah@kernel.org \
--cc=szabolcs.nagy@arm.com \
--cc=toiwoton@gmail.com \
--cc=viro@zeniv.linux.org.uk \
--cc=zbyszek@in.waw.pl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.