From: Ingo Molnar <mingo@kernel.org>
To: Kees Cook <keescook@chromium.org>
Cc: Hector Marco-Gisbert <hecmargi@upv.es>,
Andy Lutomirski <luto@kernel.org>,
Andi Kleen <ak@linux.intel.com>,
LKML <linux-kernel@vger.kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
"x86@kernel.org" <x86@kernel.org>,
Brian Gerst <brgerst@gmail.com>, Borislav Petkov <bp@suse.de>,
Huaitong Han <huaitong.han@intel.com>,
Ismael Ripoll Ripoll <iripoll@upv.es>
Subject: Re: [PATCH] x86_64: Disabling read-implies-exec when the stack is executable
Date: Mon, 16 May 2016 12:58:04 +0200 [thread overview]
Message-ID: <20160516105804.GB20440@gmail.com> (raw)
In-Reply-To: <CAGXu5jJt1YPvR903ivFCmnwu1b++mEZhbfm8k8kLwPNwCqpnbQ@mail.gmail.com>
* Kees Cook <keescook@chromium.org> wrote:
> On Wed, May 11, 2016 at 3:45 AM, Hector Marco-Gisbert <hecmargi@upv.es> wrote:
> > The READ_IMPLIES_EXEC personality was removed in 2005 for 64-bit processes,
> > (commit a3cc2546a54361b86b73557df5b85c4fc3fc27c3 form history.git).
> >
> > But it's still possible to have all readable areas with EXEC permissions by
> > setting the stack as executable in 64-bit ELF executables (also in 32-bit).
>
> My memory is fuzzy here, but IIRC, RIE is needed for loading binaries
> that have no concept of no-exec permissions. In those cases, there's
> no way to tell if the process expected to need execute permissions in
> arbitrary memory regions.
>
> > This is because the macro elf_read_implies_exec() does not distinguish
> > between 32 and 64-bit executables: when the stack is executable then the
> > read-implies-exec personality is set (enabled) to the process.
>
> However, I would tend to agree: RIE should only be needed on 32-bit
> since 64-bit started its life knowing about no-exec permissions.
>
> set_personality_64bit()'s (which is confusingly just an initializer
> and not called during the personality() syscall) comment about this
> makes no sense to me:
>
> /* TBD: overwrites user setup. Should have two bits.
> But 64bit processes have always behaved this way,
> so it's not too bad. The main problem is just that
> 32bit childs are affected again. */
> current->personality &= ~READ_IMPLIES_EXEC;
JFYI, that obfuscated comment was added over a decade ago to the x86_64 tree, see
the commit from the historic git tree attached below.
Thanks,
Ingo
=================>
>From a3cc2546a54361b86b73557df5b85c4fc3fc27c3 Mon Sep 17 00:00:00 2001
From: Andi Kleen <ak@suse.de>
Date: Wed, 9 Feb 2005 22:40:57 -0800
Subject: [PATCH] [PATCH] Force read implies exec for all 32bit processes in x86-64
This effectively enables executable stack and executable heap for all 32bit
programs on x86-64, except if noexec32=on is specified.
This does not support changing this with personality right now, this would
need more intrusive changes. A 64bit process will always turn it off and a
32bit process turn it on.
Also readd the noexec32=on option to turn this off and fix a minor bug in
noexec=... (would be reported as unknown option)
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
arch/x86_64/ia32/ia32_binfmt.c | 4 ++++
arch/x86_64/kernel/process.c | 6 ++++++
arch/x86_64/kernel/setup64.c | 25 +++++++++++++++++++++++--
include/asm-x86_64/pgtable.h | 2 +-
4 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index 445717b9c66b..93d568dfa762 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -249,6 +249,8 @@ elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
#define elf_check_arch(x) \
((x)->e_machine == EM_386)
+extern int force_personality32;
+
#define ELF_EXEC_PAGESIZE PAGE_SIZE
#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
#define ELF_PLATFORM ("i686")
@@ -262,6 +264,8 @@ do { \
set_thread_flag(TIF_ABI_PENDING); \
else \
clear_thread_flag(TIF_ABI_PENDING); \
+ /* XXX This overwrites the user set personality */ \
+ current->personality |= force_personality32; \
} while (0)
/* Override some function names */
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index bbe26dda5e79..3a3522b9c885 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -577,6 +577,12 @@ void set_personality_64bit(void)
/* Make sure to be in 64bit mode */
clear_thread_flag(TIF_IA32);
+
+ /* TBD: overwrites user setup. Should have two bits.
+ But 64bit processes have always behaved this way,
+ so it's not too bad. The main problem is just that
+ 32bit childs are affected again. */
+ current->personality &= ~READ_IMPLIES_EXEC;
}
asmlinkage long sys_fork(struct pt_regs *regs)
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 248a86a80366..b5305b04bc40 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -50,7 +50,7 @@ Control non executable mappings for 64bit processes.
on Enable(default)
off Disable
*/
-void __init nonx_setup(const char *str)
+int __init nonx_setup(char *str)
{
if (!strncmp(str, "on", 2)) {
__supported_pte_mask |= _PAGE_NX;
@@ -58,8 +58,29 @@ void __init nonx_setup(const char *str)
} else if (!strncmp(str, "off", 3)) {
do_not_nx = 1;
__supported_pte_mask &= ~_PAGE_NX;
- }
+ }
+ return 0;
}
+__setup("noexec=", nonx_setup); /* parsed early actually */
+
+int force_personality32 = READ_IMPLIES_EXEC;
+
+/* noexec32=on|off
+Control non executable heap for 32bit processes.
+To control the stack too use noexec=off
+
+on PROT_READ does not imply PROT_EXEC for 32bit processes
+off PROT_READ implies PROT_EXEC (default)
+*/
+static int __init nonx32_setup(char *str)
+{
+ if (!strcmp(str, "on"))
+ force_personality32 &= ~READ_IMPLIES_EXEC;
+ else if (!strcmp(str, "off"))
+ force_personality32 |= READ_IMPLIES_EXEC;
+ return 0;
+}
+__setup("noexec32=", nonx32_setup);
/*
* Great future plan:
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index c5773fd9b3d4..1e2cc99aebd8 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -20,7 +20,7 @@ extern unsigned long __supported_pte_mask;
#define swapper_pg_dir init_level4_pgt
-extern void nonx_setup(const char *str);
+extern int nonx_setup(char *str);
extern void paging_init(void);
extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
next prev parent reply other threads:[~2016-05-16 10:58 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-11 10:45 [PATCH] x86_64: Disabling read-implies-exec when the stack is executable Hector Marco-Gisbert
2016-05-11 20:49 ` Kees Cook
2016-05-11 22:40 ` Andi Kleen
2016-05-12 2:11 ` Kees Cook
2016-05-16 10:58 ` Ingo Molnar [this message]
2019-04-18 7:45 ` Kees Cook
2019-04-18 8:17 ` Thomas Gleixner
2019-04-18 14:11 ` Kees Cook
2019-04-18 14:14 ` Andy Lutomirski
2019-04-18 14:29 ` Kees Cook
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=20160516105804.GB20440@gmail.com \
--to=mingo@kernel.org \
--cc=ak@linux.intel.com \
--cc=bp@suse.de \
--cc=brgerst@gmail.com \
--cc=hecmargi@upv.es \
--cc=hpa@zytor.com \
--cc=huaitong.han@intel.com \
--cc=iripoll@upv.es \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox