All of lore.kernel.org
 help / color / mirror / Atom feed
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);
 

  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 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.