Re: [PATCH v3 08/12] treewide: Use initializer for struct vm_unmapped_area_info

2024-03-12 Thread Kees Cook
On Tue, Mar 12, 2024 at 03:28:39PM -0700, Rick Edgecombe wrote:
> So to be reduce the chance of bugs via uninitialized fields, perform a
> tree wide change using the consensus for the best general way to do this
> change. Use C99 static initializing to zero the struct and remove and
> statements that simply set members to zero.
> 
> Signed-off-by: Rick Edgecombe 

Thanks! This looks to do exactly what it describes. :)

Reviewed-by: Kees Cook 

-- 
Kees Cook



Re: [PATCH v2 5/9] mm: Initialize struct vm_unmapped_area_info

2024-03-01 Thread Kees Cook
On Sat, Mar 02, 2024 at 12:47:08AM +, Edgecombe, Rick P wrote:
> On Wed, 2024-02-28 at 09:21 -0800, Kees Cook wrote:
> > I totally understand. If the "uninitialized" warnings were actually
> > reliable, I would agree. I look at it this way:
> > 
> > - initializations can be missed either in static initializers or via
> >   run time initializers. (So the risk of mistake here is matched --
> >   though I'd argue it's easier to *find* static initializers when
> > adding
> >   new struct members.)
> > - uninitialized warnings are inconsistent (this becomes an unknown
> > risk)
> > - when a run time initializer is missed, the contents are whatever
> > was
> >   on the stack (high risk)
> > - what a static initializer is missed, the content is 0 (low risk)
> > 
> > I think unambiguous state (always 0) is significantly more important
> > for
> > the safety of the system as a whole. Yes, individual cases maybe bad
> > ("what uid should this be? root?!") but from a general memory safety
> > perspective the value doesn't become potentially influenced by order
> > of
> > operations, leftover stack memory, etc.
> > 
> > I'd agree, lifting everything into a static initializer does seem
> > cleanest of all the choices.
> 
> Hi Kees,
> 
> Well, I just gave this a try. It is giving me flashbacks of when I last
> had to do a tree wide change that I couldn't fully test and the
> breakage was caught by Linus.

Yeah, testing isn't fun for these kinds of things. This is traditionally
why the "obviously correct" changes tend to have an easier time landing
(i.e. adding "= {}" to all of them).

> Could you let me know if you think this is additionally worthwhile
> cleanup outside of the guard gap improvements of this series? Because I
> was thinking a more cowardly approach could be a new vm_unmapped_area()
> variant that takes the new start gap member as a separate argument
> outside of struct vm_unmapped_area_info. It would be kind of strange to
> keep them separate, but it would be less likely to bump something.

I think you want a new member -- AIUI, that's what that struct is for.

Looking at this resulting set of patches, I do kinda think just adding
the "= {}" in a single patch is more sensible. Having to split things
that are know at the top of the function from the stuff known at the
existing initialization time is rather awkward.

Personally, I think a single patch that sets "= {}" for all of them and
drop the all the "= 0" or "= NULL" assignments would be the cleanest way
to go.

-Kees

-- 
Kees Cook



Re: [PATCH v2 5/9] mm: Initialize struct vm_unmapped_area_info

2024-02-28 Thread Kees Cook
On Wed, Feb 28, 2024 at 01:22:09PM +, Christophe Leroy wrote:
> [...]
> My worry with initialisation at declaration is it often hides missing 
> assignments. Let's take following simple exemple:
> 
> char *colour(int num)
> {
>   char *name;
> 
>   if (num == 0) {
>   name = "black";
>   } else if (num == 1) {
>   name = "white";
>   } else if (num == 2) {
>   } else {
>   name = "no colour";
>   }
> 
>   return name;
> }
> 
> Here, GCC warns about a missing initialisation of variable 'name'.

Sometimes. :( We build with -Wno-maybe-uninitialized because GCC gets
this wrong too often. Also, like with large structs like this, all
uninit warnings get suppressed if anything takes it by reference. So, if
before your "return name" statement above, you had something like:

do_something();

it won't warn with any option enabled.

> But if I declare it as
> 
>   char *name = "no colour";
> 
> Then GCC won't warn anymore that we are missing a value for when num is 2.
> 
> During my life I have so many times spent huge amount of time 
> investigating issues and bugs due to missing assignments that were going 
> undetected due to default initialisation at declaration.

I totally understand. If the "uninitialized" warnings were actually
reliable, I would agree. I look at it this way:

- initializations can be missed either in static initializers or via
  run time initializers. (So the risk of mistake here is matched --
  though I'd argue it's easier to *find* static initializers when adding
  new struct members.)
- uninitialized warnings are inconsistent (this becomes an unknown risk)
- when a run time initializer is missed, the contents are whatever was
  on the stack (high risk)
- what a static initializer is missed, the content is 0 (low risk)

I think unambiguous state (always 0) is significantly more important for
the safety of the system as a whole. Yes, individual cases maybe bad
("what uid should this be? root?!") but from a general memory safety
perspective the value doesn't become potentially influenced by order of
operations, leftover stack memory, etc.

I'd agree, lifting everything into a static initializer does seem
cleanest of all the choices.

-Kees

-- 
Kees Cook



Re: [PATCH v2 5/9] mm: Initialize struct vm_unmapped_area_info

2024-02-27 Thread Kees Cook
On Tue, Feb 27, 2024 at 07:02:59AM +, Christophe Leroy wrote:
> 
> 
> Le 26/02/2024 à 20:09, Rick Edgecombe a écrit :
> > Future changes will need to add a field to struct vm_unmapped_area_info.
> > This would cause trouble for any archs that don't initialize the
> > struct. Currently every user sets each field, so if new fields are
> > added, the core code parsing the struct will see garbage in the new
> > field.
> > 
> > It could be possible to initialize the new field for each arch to 0, but
> > instead simply inialize the field with a C99 struct inializing syntax.
> 
> Why doing a full init of the struct when all fields are re-written a few 
> lines after ?

It's a nice change for robustness and makes future changes easier. It's
not actually wasteful since the compiler will throw away all redundant
stores.

> If I take the exemple of powerpc function slice_find_area_bottomup():
> 
>   struct vm_unmapped_area_info info;
> 
>   info.flags = 0;
>   info.length = len;
>   info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
>   info.align_offset = 0;

But one cleanup that is possible from explicitly zero-initializing the
whole structure would be dropping all the individual "= 0" assignments.
:)

-- 
Kees Cook



Re: [PATCH v2 01/29] powerpc: Rename "notes" PT_NOTE to "note"

2019-10-15 Thread Kees Cook
On Tue, Oct 15, 2019 at 06:54:13PM +0200, Borislav Petkov wrote:
> On Fri, Oct 11, 2019 at 11:25:52AM -0500, Segher Boessenkool wrote:
> > Names *matter*, internal names doubly so.  So why replace a good name with
> > a worse name?  Because it is slightly less work for you?
> 
> So if we agree on the name "notes" and we decide to rename the other
> arches, this should all be done in a separate patchset anyway, and ontop
> of this one. And I believe Kees wouldn't mind doing it ontop since he's
> gotten his hands dirty already. :-P

Yeah, I'm fine with that. I would prefer to do it as a separate step,
just to minimize the logical steps each patch takes. Shall I spin a v3
with the Acks added and a final rename for this?

-- 
Kees Cook


Re: [PATCH v2 01/29] powerpc: Rename "notes" PT_NOTE to "note"

2019-10-11 Thread Kees Cook
On Fri, Oct 11, 2019 at 03:25:19AM -0500, Segher Boessenkool wrote:
> On Thu, Oct 10, 2019 at 05:05:41PM -0700, Kees Cook wrote:
> > The Program Header identifiers are internal to the linker scripts. In
> > preparation for moving the NOTES segment declaration into RO_DATA,
> > standardize the identifier for the PT_NOTE entry to "note" as used by
> > all other architectures that emit PT_NOTE.
> 
> All other archs are wrong, and "notes" is a much better name.  This
> segment does not contain a single "note", but multiple "notes".

True, but the naming appears to be based off the Program Header name of
"PT_NOTE". Regardless, it is an entirely internal-to-the-linker-script
identifier, so I am just consolidating on a common name with the least
number of collateral changes.

-- 
Kees Cook


[PATCH v2 23/29] parisc: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/parisc/kernel/vmlinux.lds.S | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 12b3d7d5e9e4..53e29d88f99c 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -19,6 +19,7 @@
*(.data..vm0.pte)
 
 #define CC_USING_PATCHABLE_FUNCTION_ENTRY
+#define RO_EXCEPTION_TABLE_ALIGN   8
 
 #include 
 
@@ -129,9 +130,6 @@ SECTIONS
 
RO_DATA(8)
 
-   /* RO because of BUILDTIME_EXTABLE_SORT */
-   EXCEPTION_TABLE(8)
-
/* unwind info */
.PARISC.unwind : {
__start___unwind = .;
-- 
2.17.1



[PATCH v2 19/29] c6x: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/c6x/kernel/vmlinux.lds.S | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S
index a3547f9d415b..ac99ba0864bf 100644
--- a/arch/c6x/kernel/vmlinux.lds.S
+++ b/arch/c6x/kernel/vmlinux.lds.S
@@ -5,6 +5,9 @@
  *  Copyright (C) 2010, 2011 Texas Instruments Incorporated
  *  Mark Salter 
  */
+
+#define RO_EXCEPTION_TABLE_ALIGN   16
+
 #include 
 #include 
 #include 
@@ -80,8 +83,6 @@ SECTIONS
*(.gnu.warning)
}
 
-   EXCEPTION_TABLE(16)
-
RO_DATA(PAGE_SIZE)
.const :
{
-- 
2.17.1



[PATCH v2 17/29] alpha: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index edc45f45523b..bc6f727278fd 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
 #define EMITS_PT_NOTE
+#define RO_EXCEPTION_TABLE_ALIGN   16
 
 #include 
 #include 
@@ -35,7 +36,6 @@ SECTIONS
_etext = .; /* End of text section */
 
RO_DATA(4096)
-   EXCEPTION_TABLE(16)
 
/* Will be freed after init */
__init_begin = ALIGN(PAGE_SIZE);
-- 
2.17.1



[PATCH v2 21/29] ia64: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/ia64/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 11d5115bc44d..1ec6b703c5b4 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
 #include 
 
 #define EMITS_PT_NOTE
+#define RO_EXCEPTION_TABLE_ALIGN   16
 
 #include 
 
@@ -70,7 +71,6 @@ SECTIONS {
/*
 * Read-only data
 */
-   EXCEPTION_TABLE(16)
 
/* MCA table */
. = ALIGN(16);
-- 
2.17.1



[PATCH v2 18/29] arm64: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA. Also
removes the redundant ALIGN, which is already present at the end of the
RO_DATA macro.

Signed-off-by: Kees Cook 
Acked-by: Will Deacon 
---
 arch/arm64/kernel/vmlinux.lds.S | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index a4b3e6c0680c..9128a26eb45b 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -5,6 +5,8 @@
  * Written by Martin Mares 
  */
 
+#define RO_EXCEPTION_TABLE_ALIGN   8
+
 #include 
 #include 
 #include 
@@ -135,10 +137,9 @@ SECTIONS
. = ALIGN(SEGMENT_ALIGN);
_etext = .; /* End of text section */
 
-   RO_DATA(PAGE_SIZE)  /* everything from this point to */
-   EXCEPTION_TABLE(8)  /* __init_begin will be marked RO NX */
+   /* everything from this point to __init_begin will be marked RO NX */
+   RO_DATA(PAGE_SIZE)
 
-   . = ALIGN(PAGE_SIZE);
idmap_pg_dir = .;
. += IDMAP_DIR_SIZE;
 
-- 
2.17.1



[PATCH v2 29/29] x86: Use INT3 instead of NOP for linker fill bytes

2019-10-10 Thread Kees Cook
Instead of using 0x90 (NOP) to fill bytes between functions, which makes
it easier to sloppily target functions in function pointer overwrite
attacks, fill with 0xCC (INT3) to force a trap. Also drop the space
between "=" and the value to better match the binutils documentation
https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html#Output-Section-Fill

Example "objdump -d" before:

...
810001e0 :
810001e0:   48 8b 25 e1 b1 51 01mov 0x151b1e1(%rip),%rsp
# 8251b3c8 
810001e7:   e9 d5 fe ff ff  jmpq   81c1 

810001ec:   90  nop
810001ed:   90  nop
810001ee:   90  nop
810001ef:   90  nop

810001f0 <__startup_64>:
...

After:

...
810001e0 :
810001e0:   48 8b 25 41 79 53 01mov 0x1537941(%rip),%rsp
# 82537b28 
810001e7:   e9 d5 fe ff ff  jmpq   81c1 

810001ec:   cc  int3
810001ed:   cc  int3
810001ee:   cc  int3
810001ef:   cc  int3

810001f0 <__startup_64>:
...

Signed-off-by: Kees Cook 
---
 arch/x86/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index b06d6e1188de..3a1a819da137 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -144,7 +144,7 @@ SECTIONS
*(.text.__x86.indirect_thunk)
__indirect_thunk_end = .;
 #endif
-   } :text = 0x9090
+   } :text =0x
 
/* End of text section, which should occupy whole number of pages */
_etext = .;
-- 
2.17.1



[PATCH v2 27/29] x86/mm: Report which part of kernel image is freed

2019-10-10 Thread Kees Cook
The memory freeing report wasn't very useful for figuring out which
parts of the kernel image were being freed. Add the details for clearer
reporting in dmesg.

Before:

[2.150450] Freeing unused kernel image memory: 1348K
[2.154574] Write protecting the kernel read-only data: 20480k
[2.157641] Freeing unused kernel image memory: 2040K
[2.158827] Freeing unused kernel image memory: 172K

After:

[2.329678] Freeing unused kernel image (initmem) memory: 1348K
[2.331953] Write protecting the kernel read-only data: 20480k
[2.335361] Freeing unused kernel image (text/rodata gap) memory: 2040K
[2.336927] Freeing unused kernel image (rodata/data gap) memory: 172K

Signed-off-by: Kees Cook 
---
 arch/x86/include/asm/processor.h | 2 +-
 arch/x86/mm/init.c   | 8 
 arch/x86/mm/init_64.c| 6 --
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 6e0a3b43d027..790f250d39a8 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -958,7 +958,7 @@ static inline uint32_t hypervisor_cpuid_base(const char 
*sig, uint32_t leaves)
 
 extern unsigned long arch_align_stack(unsigned long sp);
 void free_init_pages(const char *what, unsigned long begin, unsigned long end);
-extern void free_kernel_image_pages(void *begin, void *end);
+extern void free_kernel_image_pages(const char *what, void *begin, void *end);
 
 void default_idle(void);
 #ifdef CONFIG_XEN
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index fd10d91a6115..e7bb483557c9 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -829,14 +829,13 @@ void free_init_pages(const char *what, unsigned long 
begin, unsigned long end)
  * used for the kernel image only.  free_init_pages() will do the
  * right thing for either kind of address.
  */
-void free_kernel_image_pages(void *begin, void *end)
+void free_kernel_image_pages(const char *what, void *begin, void *end)
 {
unsigned long begin_ul = (unsigned long)begin;
unsigned long end_ul = (unsigned long)end;
unsigned long len_pages = (end_ul - begin_ul) >> PAGE_SHIFT;
 
-
-   free_init_pages("unused kernel image", begin_ul, end_ul);
+   free_init_pages(what, begin_ul, end_ul);
 
/*
 * PTI maps some of the kernel into userspace.  For performance,
@@ -865,7 +864,8 @@ void __ref free_initmem(void)
 
mem_encrypt_free_decrypted_mem();
 
-   free_kernel_image_pages(&__init_begin, &__init_end);
+   free_kernel_image_pages("unused kernel image (initmem)",
+   &__init_begin, &__init_end);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index e67ddca8b7a8..dcb9bc961b39 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1334,8 +1334,10 @@ void mark_rodata_ro(void)
set_memory_ro(start, (end-start) >> PAGE_SHIFT);
 #endif
 
-   free_kernel_image_pages((void *)text_end, (void *)rodata_start);
-   free_kernel_image_pages((void *)rodata_end, (void *)_sdata);
+   free_kernel_image_pages("unused kernel image (text/rodata gap)",
+   (void *)text_end, (void *)rodata_start);
+   free_kernel_image_pages("unused kernel image (rodata/data gap)",
+   (void *)rodata_end, (void *)_sdata);
 
debug_checkwx();
 }
-- 
2.17.1



[PATCH v2 24/29] powerpc: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 4e7cec088c8b..8834220036a5 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -7,6 +7,7 @@
 
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
 #define EMITS_PT_NOTE
+#define RO_EXCEPTION_TABLE_ALIGN   0
 
 #include 
 #include 
@@ -162,7 +163,6 @@ SECTIONS
__stop__btb_flush_fixup = .;
}
 #endif
-   EXCEPTION_TABLE(0)
 
 /*
  * Init sections discarded at runtime
-- 
2.17.1



[PATCH v2 14/29] vmlinux.lds.h: Allow EXCEPTION_TABLE to live in RO_DATA

2019-10-10 Thread Kees Cook
Many architectures have an EXCEPTION_TABLE that only needs to
be readable. As such, it should live in RO_DATA. Create a macro to
identify this case for the architectures that can move EXCEPTION_TABLE
into RO_DATA.

Signed-off-by: Kees Cook 
Acked-by: Will Deacon 
---
 include/asm-generic/vmlinux.lds.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 356078e50a5c..9867d8e41eed 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -69,6 +69,17 @@
 #define NOTES_HEADERS_RESTORE
 #endif
 
+/*
+ * Some architectures have non-executable read-only exception tables.
+ * They can be added to the RO_DATA segment by specifying their desired
+ * alignment.
+ */
+#ifdef RO_EXCEPTION_TABLE_ALIGN
+#define RO_EXCEPTION_TABLE EXCEPTION_TABLE(RO_EXCEPTION_TABLE_ALIGN)
+#else
+#define RO_EXCEPTION_TABLE
+#endif
+
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
@@ -513,6 +524,7 @@
__stop___modver = .;\
}   \
\
+   RO_EXCEPTION_TABLE  \
NOTES   \
\
. = ALIGN((align)); \
-- 
2.17.1



[PATCH v2 25/29] xtensa: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/xtensa/kernel/vmlinux.lds.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index bdbd7c4056c1..0043d5858f14 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -14,6 +14,8 @@
  * Joe Taylor 
  */
 
+#define RO_EXCEPTION_TABLE_ALIGN   16
+
 #include 
 #include 
 #include 
@@ -130,7 +132,6 @@ SECTIONS
 
   .fixup   : { *(.fixup) }
 
-  EXCEPTION_TABLE(16)
   /* Data section */
 
   _sdata = .;
-- 
2.17.1



[PATCH v2 22/29] microblaze: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/microblaze/kernel/vmlinux.lds.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/microblaze/kernel/vmlinux.lds.S 
b/arch/microblaze/kernel/vmlinux.lds.S
index b8efb08204a1..760cac41cbfe 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -11,6 +11,8 @@
 OUTPUT_ARCH(microblaze)
 ENTRY(microblaze_start)
 
+#define RO_EXCEPTION_TABLE_ALIGN   16
+
 #include 
 #include 
 #include 
@@ -52,7 +54,6 @@ SECTIONS {
 
. = ALIGN(16);
RO_DATA(4096)
-   EXCEPTION_TABLE(16)
 
/*
 * sdata2 section can go anywhere, but must be word aligned
-- 
2.17.1



[PATCH v2 26/29] x86/mm: Remove redundant on addresses

2019-10-10 Thread Kees Cook
The  on addresses are redundant. Remove them to match all the other
similar functions.

Signed-off-by: Kees Cook 
---
 arch/x86/mm/init_64.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 26299e9ce6da..e67ddca8b7a8 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1300,9 +1300,9 @@ void mark_rodata_ro(void)
 {
unsigned long start = PFN_ALIGN(_text);
unsigned long rodata_start = PFN_ALIGN(__start_rodata);
-   unsigned long end = (unsigned long) &__end_rodata_hpage_align;
-   unsigned long text_end = PFN_ALIGN(&_etext);
-   unsigned long rodata_end = PFN_ALIGN(&__end_rodata);
+   unsigned long end = (unsigned long)__end_rodata_hpage_align;
+   unsigned long text_end = PFN_ALIGN(_etext);
+   unsigned long rodata_end = PFN_ALIGN(__end_rodata);
unsigned long all_end;
 
printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
-- 
2.17.1



[PATCH v2 04/29] alpha: Rename PT_LOAD identifier "kernel" to "text"

2019-10-10 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, rename the linker script
internal identifier for the PT_LOAD Program Header from "kernel" to
"text" to match other architectures.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index c4b5ceceab52..781090cacc96 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -8,7 +8,7 @@
 OUTPUT_FORMAT("elf64-alpha")
 OUTPUT_ARCH(alpha)
 ENTRY(__start)
-PHDRS { kernel PT_LOAD; note PT_NOTE; }
+PHDRS { text PT_LOAD; note PT_NOTE; }
 jiffies = jiffies_64;
 SECTIONS
 {
@@ -27,14 +27,14 @@ SECTIONS
LOCK_TEXT
*(.fixup)
*(.gnu.warning)
-   } :kernel
+   } :text
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   NOTES :kernel :note
+   NOTES :text :note
.dummy : {
*(.dummy)
-   } :kernel
+   } :text
 
RODATA
EXCEPTION_TABLE(16)
-- 
2.17.1



[PATCH v2 02/29] powerpc: Remove PT_NOTE workaround

2019-10-10 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, remove the PT_NOTE
workaround since the kernel requires at least gcc 4.6 now.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 24 ++--
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 81e672654789..a3c8492b2b19 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -20,20 +20,6 @@ ENTRY(_stext)
 PHDRS {
kernel PT_LOAD FLAGS(7); /* RWX */
note PT_NOTE FLAGS(0);
-   dummy PT_NOTE FLAGS(0);
-
-   /* binutils < 2.18 has a bug that makes it misbehave when taking an
-  ELF file with all segments at load address 0 as input.  This
-  happens when running "strip" on vmlinux, because of the AT() magic
-  in this linker script.  People using GCC >= 4.2 won't run into
-  this problem, because the "build-id" support will put some data
-  into the "notes" segment (at a non-zero load address).
-
-  To work around this, we force some data into both the "dummy"
-  segment and the kernel segment, so the dummy segment will get a
-  non-zero load address.  It's not enough to always create the
-  "notes" segment, since if nothing gets assigned to it, its load
-  address will be zero.  */
 }
 
 #ifdef CONFIG_PPC64
@@ -178,14 +164,8 @@ SECTIONS
EXCEPTION_TABLE(0)
 
NOTES :kernel :note
-
-   /* The dummy segment contents for the bug workaround mentioned above
-  near PHDRS.  */
-   .dummy : AT(ADDR(.dummy) - LOAD_OFFSET) {
-   LONG(0)
-   LONG(0)
-   LONG(0)
-   } :kernel :dummy
+   /* Restore program header away from PT_NOTE. */
+   .dummy : { *(.dummy) } :kernel
 
 /*
  * Init sections discarded at runtime
-- 
2.17.1



[PATCH v2 05/29] ia64: Rename PT_LOAD identifier "code" to "text"

2019-10-10 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, rename the linker script
internal identifier for the PT_LOAD Program Header from "code" to "text"
to match other architectures.

Signed-off-by: Kees Cook 
---
 arch/ia64/kernel/vmlinux.lds.S | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index d9d4e21107cd..2c4f23c390ad 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -13,7 +13,7 @@ ENTRY(phys_start)
 jiffies = jiffies_64;
 
 PHDRS {
-   code   PT_LOAD;
+   text   PT_LOAD;
percpu PT_LOAD;
data   PT_LOAD;
note   PT_NOTE;
@@ -36,7 +36,7 @@ SECTIONS {
phys_start = _start - LOAD_OFFSET;
 
code : {
-   } :code
+   } :text
. = KERNEL_START;
 
_text = .;
@@ -68,9 +68,9 @@ SECTIONS {
/*
 * Read-only data
 */
-   NOTES :code :note   /* put .notes in text and mark in PT_NOTE  */
+   NOTES :text :note   /* put .notes in text and mark in PT_NOTE  */
code_continues : {
-   } : code   /* switch back to regular program...  */
+   } :text/* switch back to regular program...  */
 
EXCEPTION_TABLE(16)
 
@@ -102,9 +102,9 @@ SECTIONS {
__start_unwind = .;
*(.IA_64.unwind*)
__end_unwind = .;
-   } :code :unwind
+   } :text :unwind
code_continues2 : {
-   } : code
+   } :text
 
RODATA
 
@@ -214,7 +214,7 @@ SECTIONS {
_end = .;
 
code : {
-   } :code
+   } :text
 
STABS_DEBUG
DWARF_DEBUG
-- 
2.17.1



[PATCH v2 01/29] powerpc: Rename "notes" PT_NOTE to "note"

2019-10-10 Thread Kees Cook
The Program Header identifiers are internal to the linker scripts. In
preparation for moving the NOTES segment declaration into RO_DATA,
standardize the identifier for the PT_NOTE entry to "note" as used by
all other architectures that emit PT_NOTE.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 060a1acd7c6d..81e672654789 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -19,7 +19,7 @@ ENTRY(_stext)
 
 PHDRS {
kernel PT_LOAD FLAGS(7); /* RWX */
-   notes PT_NOTE FLAGS(0);
+   note PT_NOTE FLAGS(0);
dummy PT_NOTE FLAGS(0);
 
/* binutils < 2.18 has a bug that makes it misbehave when taking an
@@ -177,7 +177,7 @@ SECTIONS
 #endif
EXCEPTION_TABLE(0)
 
-   NOTES :kernel :notes
+   NOTES :kernel :note
 
/* The dummy segment contents for the bug workaround mentioned above
   near PHDRS.  */
-- 
2.17.1



[PATCH v2 13/29] vmlinux.lds.h: Replace RW_DATA_SECTION with RW_DATA

2019-10-10 Thread Kees Cook
Rename RW_DATA_SECTION to RW_DATA. (Calling this a "section" is a lie,
since it's multiple sections and section flags cannot be applied to
the macro.)

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S  | 2 +-
 arch/arc/kernel/vmlinux.lds.S| 2 +-
 arch/arm/kernel/vmlinux-xip.lds.S| 2 +-
 arch/arm/kernel/vmlinux.lds.S| 2 +-
 arch/arm64/kernel/vmlinux.lds.S  | 2 +-
 arch/csky/kernel/vmlinux.lds.S   | 2 +-
 arch/h8300/kernel/vmlinux.lds.S  | 2 +-
 arch/hexagon/kernel/vmlinux.lds.S| 2 +-
 arch/m68k/kernel/vmlinux-nommu.lds   | 2 +-
 arch/m68k/kernel/vmlinux-std.lds | 2 +-
 arch/m68k/kernel/vmlinux-sun3.lds| 2 +-
 arch/microblaze/kernel/vmlinux.lds.S | 2 +-
 arch/nds32/kernel/vmlinux.lds.S  | 2 +-
 arch/nios2/kernel/vmlinux.lds.S  | 2 +-
 arch/openrisc/kernel/vmlinux.lds.S   | 2 +-
 arch/parisc/kernel/vmlinux.lds.S | 2 +-
 arch/riscv/kernel/vmlinux.lds.S  | 2 +-
 arch/s390/kernel/vmlinux.lds.S   | 2 +-
 arch/sh/kernel/vmlinux.lds.S | 2 +-
 arch/sparc/kernel/vmlinux.lds.S  | 2 +-
 arch/unicore32/kernel/vmlinux.lds.S  | 2 +-
 arch/xtensa/kernel/vmlinux.lds.S | 2 +-
 include/asm-generic/vmlinux.lds.h| 4 ++--
 23 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index af411817dd7d..edc45f45523b 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
 
_sdata = .; /* Start of rw data section */
_data = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
.got : {
*(.got)
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 7d1d27066deb..54139a6f469b 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -101,7 +101,7 @@ SECTIONS
 * 1. this is .data essentially
 * 2. THREAD_SIZE for init.task, must be kernel-stk sz aligned
 */
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
_edata = .;
 
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S 
b/arch/arm/kernel/vmlinux-xip.lds.S
index d2a9651c24ad..21b8b271c80d 100644
--- a/arch/arm/kernel/vmlinux-xip.lds.S
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
@@ -112,7 +112,7 @@ SECTIONS
 
. = ALIGN(THREAD_SIZE);
_sdata = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
.data.ro_after_init : AT(ADDR(.data.ro_after_init) - LOAD_OFFSET) {
*(.data..ro_after_init)
}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 068db6860867..319ccb10846a 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -141,7 +141,7 @@ SECTIONS
__init_end = .;
 
_sdata = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
BSS_SECTION(0, 0, 0)
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index e7dafc29b1fa..a4b3e6c0680c 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -214,7 +214,7 @@ SECTIONS
 
_data = .;
_sdata = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
 
/*
 * Data written with the MMU off but read with the MMU on requires
diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S
index 8598bd7a7bcd..2ff37beaf2bf 100644
--- a/arch/csky/kernel/vmlinux.lds.S
+++ b/arch/csky/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
 
_sdata = .;
RO_DATA(PAGE_SIZE)
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
EXCEPTION_TABLE(L1_CACHE_BYTES)
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index d3247d33b115..2ac7bdcd2fe0 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -47,7 +47,7 @@ SECTIONS
 #endif
_sdata = . ;
__data_start = . ;
-   RW_DATA_SECTION(0, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(0, PAGE_SIZE, THREAD_SIZE)
 #if defined(CONFIG_ROMKERNEL)
 #undef ADDR
 #endif
diff --git a/arch/hexagon/kernel/vmlinux.lds.S 
b/arch/hexagon/kernel/vmlinux.lds.S
index 0145251fa317..0ca2471ddb9f 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -49,7 +49,7 @@ SECTIONS
INIT_DATA_SECTION(PAGE_SIZE)
 
_sdata = .;
-   RW_DATA_SECTION(32,PAGE_SIZE,_THREAD_SIZE)
+   RW_DATA(32,PAGE_SIZE,_THREAD_SIZE)
RO_DATA(PAGE_SIZE)
_edata = .;
 

[PATCH v2 08/29] vmlinux.lds.h: Provide EMIT_PT_NOTE to indicate export of .notes

2019-10-10 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, provide a mechanism for
architectures that want to emit a PT_NOTE Program Header to do so.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S   |  3 +++
 arch/ia64/kernel/vmlinux.lds.S|  2 ++
 arch/mips/kernel/vmlinux.lds.S| 12 ++--
 arch/powerpc/kernel/vmlinux.lds.S |  1 +
 arch/s390/kernel/vmlinux.lds.S|  2 ++
 arch/x86/kernel/vmlinux.lds.S |  2 ++
 include/asm-generic/vmlinux.lds.h |  8 
 7 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 781090cacc96..363a60ba7c31 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+
+#define EMITS_PT_NOTE
+
 #include 
 #include 
 #include 
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 2c4f23c390ad..7cf4958b732d 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -5,6 +5,8 @@
 #include 
 #include 
 
+#define EMITS_PT_NOTE
+
 #include 
 
 OUTPUT_FORMAT("elf64-ia64-little")
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 33ee0d18fb0a..1c95612eb800 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -10,6 +10,11 @@
  */
 #define BSS_FIRST_SECTIONS *(.bss..swapper_pg_dir)
 
+/* Cavium Octeon should not have a separate PT_NOTE Program Header. */
+#ifndef CONFIG_CAVIUM_OCTEON_SOC
+#define EMITS_PT_NOTE
+#endif
+
 #include 
 
 #undef mips
@@ -76,12 +81,7 @@ SECTIONS
__stop___dbe_table = .;
}
 
-#ifdef CONFIG_CAVIUM_OCTEON_SOC
-#define NOTES_HEADER
-#else /* CONFIG_CAVIUM_OCTEON_SOC */
-#define NOTES_HEADER :note
-#endif /* CONFIG_CAVIUM_OCTEON_SOC */
-   NOTES :text NOTES_HEADER
+   NOTES NOTES_HEADERS
.dummy : { *(.dummy) } :text
 
_sdata = .; /* Start of data section */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index e184a63aa5b0..7e26e20c8324 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
 #endif
 
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
+#define EMITS_PT_NOTE
 
 #include 
 #include 
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 13294fef473e..646d939346df 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -15,6 +15,8 @@
 /* Handle ro_after_init data on our own. */
 #define RO_AFTER_INIT_DATA
 
+#define EMITS_PT_NOTE
+
 #include 
 #include 
 
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 788e78978030..2e18bf5c1aed 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -21,6 +21,8 @@
 #define LOAD_OFFSET __START_KERNEL_map
 #endif
 
+#define EMITS_PT_NOTE
+
 #include 
 #include 
 #include 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index dae64600ccbf..f5dd45ce73f1 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -54,6 +54,14 @@
 #define LOAD_OFFSET 0
 #endif
 
+/*
+ * Only some architectures want to have the .notes segment visible in
+ * a separate PT_NOTE ELF Program Header.
+ */
+#ifdef EMITS_PT_NOTE
+#define NOTES_HEADERS  :text :note
+#endif
+
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
-- 
2.17.1



[PATCH v2 15/29] x86: Actually use _etext for end of text segment

2019-10-10 Thread Kees Cook
Various calculations are using the end of the exception table (which
does not need to be executable) as the end of the text segment. Instead,
in preparation for moving the exception table into RO_DATA, move _etext
after the exception table and update the calculations.

Signed-off-by: Kees Cook 
---
 arch/x86/include/asm/sections.h | 1 -
 arch/x86/kernel/vmlinux.lds.S   | 7 +++
 arch/x86/mm/init_64.c   | 6 +++---
 arch/x86/mm/pti.c   | 2 +-
 4 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
index 71b32f2570ab..036c360910c5 100644
--- a/arch/x86/include/asm/sections.h
+++ b/arch/x86/include/asm/sections.h
@@ -6,7 +6,6 @@
 #include 
 
 extern char __brk_base[], __brk_limit[];
-extern struct exception_table_entry __stop___ex_table[];
 extern char __end_rodata_aligned[];
 
 #if defined(CONFIG_X86_64)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 41362e90142d..a1a758e25b2b 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -143,15 +143,14 @@ SECTIONS
*(.text.__x86.indirect_thunk)
__indirect_thunk_end = .;
 #endif
-
-   /* End of text section */
-   _etext = .;
} :text = 0x9090
 
EXCEPTION_TABLE(16)
 
-   /* .text should occupy whole number of pages */
+   /* End of text section, which should occupy whole number of pages */
+   _etext = .;
. = ALIGN(PAGE_SIZE);
+
X86_ALIGN_RODATA_BEGIN
RO_DATA(PAGE_SIZE)
X86_ALIGN_RODATA_END
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a6b5c653727b..26299e9ce6da 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1263,7 +1263,7 @@ int kernel_set_to_readonly;
 void set_kernel_text_rw(void)
 {
unsigned long start = PFN_ALIGN(_text);
-   unsigned long end = PFN_ALIGN(__stop___ex_table);
+   unsigned long end = PFN_ALIGN(_etext);
 
if (!kernel_set_to_readonly)
return;
@@ -1282,7 +1282,7 @@ void set_kernel_text_rw(void)
 void set_kernel_text_ro(void)
 {
unsigned long start = PFN_ALIGN(_text);
-   unsigned long end = PFN_ALIGN(__stop___ex_table);
+   unsigned long end = PFN_ALIGN(_etext);
 
if (!kernel_set_to_readonly)
return;
@@ -1301,7 +1301,7 @@ void mark_rodata_ro(void)
unsigned long start = PFN_ALIGN(_text);
unsigned long rodata_start = PFN_ALIGN(__start_rodata);
unsigned long end = (unsigned long) &__end_rodata_hpage_align;
-   unsigned long text_end = PFN_ALIGN(&__stop___ex_table);
+   unsigned long text_end = PFN_ALIGN(&_etext);
unsigned long rodata_end = PFN_ALIGN(&__end_rodata);
unsigned long all_end;
 
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index 7f2140414440..44a9f068eee0 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -574,7 +574,7 @@ static void pti_clone_kernel_text(void)
 */
unsigned long start = PFN_ALIGN(_text);
unsigned long end_clone  = (unsigned long)__end_rodata_aligned;
-   unsigned long end_global = PFN_ALIGN((unsigned long)__stop___ex_table);
+   unsigned long end_global = PFN_ALIGN((unsigned long)_etext);
 
if (!pti_kernel_image_global_ok())
return;
-- 
2.17.1



[PATCH v2 00/29] vmlinux.lds.h: Refactor EXCEPTION_TABLE and NOTES

2019-10-10 Thread Kees Cook
Arch maintainers: please send Acks (if you haven't already) for your
respective linker script changes; the intention is for this series to
land via -tip.

v1: https://lore.kernel.org/lkml/20190926175602.33098-1-keesc...@chromium.org
v2: clean up commit messages, rename RO_EXCEPTION_TABLE (bp)


This series works to move the linker sections for NOTES and
EXCEPTION_TABLE into the RO_DATA area, where they belong on most
(all?) architectures. The problem being addressed was the discovery
by Rick Edgecombe that the exception table was accidentally marked
executable while he was developing his execute-only-memory series. When
permissions were flipped from readable-and-executable to only-executable,
the exception table became unreadable, causing things to explode rather
badly. :)

Roughly speaking, the steps are:

- regularize the linker names for PT_NOTE and PT_LOAD program headers
  (to "note" and "text" respectively)
- regularize restoration of linker section to program header assignment
  (when PT_NOTE exists)
- move NOTES into RO_DATA
- finish macro naming conversions for RO_DATA and RW_DATA
- move EXCEPTION_TABLE into RO_DATA on architectures where this is clear
- clean up some x86-specific reporting of kernel memory resources
- switch x86 linker fill byte from x90 (NOP) to 0xcc (INT3), just because
  I finally realized what that trailing ": 0x9090" meant -- and we should
  trap, not slide, if execution lands in section padding

Thanks!

-Kees

Kees Cook (29):
  powerpc: Rename "notes" PT_NOTE to "note"
  powerpc: Remove PT_NOTE workaround
  powerpc: Rename PT_LOAD identifier "kernel" to "text"
  alpha: Rename PT_LOAD identifier "kernel" to "text"
  ia64: Rename PT_LOAD identifier "code" to "text"
  s390: Move RO_DATA into "text" PT_LOAD Program Header
  x86: Restore "text" Program Header with dummy section
  vmlinux.lds.h: Provide EMIT_PT_NOTE to indicate export of .notes
  vmlinux.lds.h: Move Program Header restoration into NOTES macro
  vmlinux.lds.h: Move NOTES into RO_DATA
  vmlinux.lds.h: Replace RODATA with RO_DATA
  vmlinux.lds.h: Replace RO_DATA_SECTION with RO_DATA
  vmlinux.lds.h: Replace RW_DATA_SECTION with RW_DATA
  vmlinux.lds.h: Allow EXCEPTION_TABLE to live in RO_DATA
  x86: Actually use _etext for end of text segment
  x86: Move EXCEPTION_TABLE to RO_DATA segment
  alpha: Move EXCEPTION_TABLE to RO_DATA segment
  arm64: Move EXCEPTION_TABLE to RO_DATA segment
  c6x: Move EXCEPTION_TABLE to RO_DATA segment
  h8300: Move EXCEPTION_TABLE to RO_DATA segment
  ia64: Move EXCEPTION_TABLE to RO_DATA segment
  microblaze: Move EXCEPTION_TABLE to RO_DATA segment
  parisc: Move EXCEPTION_TABLE to RO_DATA segment
  powerpc: Move EXCEPTION_TABLE to RO_DATA segment
  xtensa: Move EXCEPTION_TABLE to RO_DATA segment
  x86/mm: Remove redundant  on addresses
  x86/mm: Report which part of kernel image is freed
  x86/mm: Report actual image regions in /proc/iomem
  x86: Use INT3 instead of NOP for linker fill bytes

 arch/alpha/kernel/vmlinux.lds.S  | 18 +-
 arch/arc/kernel/vmlinux.lds.S|  6 ++--
 arch/arm/kernel/vmlinux-xip.lds.S|  4 +--
 arch/arm/kernel/vmlinux.lds.S|  4 +--
 arch/arm64/kernel/vmlinux.lds.S  |  9 ++---
 arch/c6x/kernel/vmlinux.lds.S|  8 ++---
 arch/csky/kernel/vmlinux.lds.S   |  5 ++-
 arch/h8300/kernel/vmlinux.lds.S  |  9 ++---
 arch/hexagon/kernel/vmlinux.lds.S|  5 ++-
 arch/ia64/kernel/vmlinux.lds.S   | 20 +--
 arch/m68k/kernel/vmlinux-nommu.lds   |  4 +--
 arch/m68k/kernel/vmlinux-std.lds |  2 +-
 arch/m68k/kernel/vmlinux-sun3.lds|  2 +-
 arch/microblaze/kernel/vmlinux.lds.S |  8 ++---
 arch/mips/kernel/vmlinux.lds.S   | 15 
 arch/nds32/kernel/vmlinux.lds.S  |  5 ++-
 arch/nios2/kernel/vmlinux.lds.S  |  5 ++-
 arch/openrisc/kernel/vmlinux.lds.S   |  7 ++--
 arch/parisc/kernel/vmlinux.lds.S | 11 +++---
 arch/powerpc/kernel/vmlinux.lds.S| 37 ---
 arch/riscv/kernel/vmlinux.lds.S  |  5 ++-
 arch/s390/kernel/vmlinux.lds.S   | 12 +++
 arch/sh/kernel/vmlinux.lds.S |  3 +-
 arch/sparc/kernel/vmlinux.lds.S  |  3 +-
 arch/um/include/asm/common.lds.S |  3 +-
 arch/unicore32/kernel/vmlinux.lds.S  |  5 ++-
 arch/x86/include/asm/processor.h |  2 +-
 arch/x86/include/asm/sections.h  |  1 -
 arch/x86/kernel/setup.c  | 12 ++-
 arch/x86/kernel/vmlinux.lds.S| 16 -
 arch/x86/mm/init.c   |  8 ++---
 arch/x86/mm/init_64.c| 16 +
 arch/x86/mm/pti.c|  2 +-
 arch/xtensa/kernel/vmlinux.lds.S |  8 ++---
 include/asm-generic/vmlinux.lds.h| 53 
 35 files changed, 159 insertions(+), 174 deletions(-)

-- 
2.17.1


Kees Cook (29):
  powerpc: Rename "notes" PT_NOTE to "note"
  powerpc: 

[PATCH v2 09/29] vmlinux.lds.h: Move Program Header restoration into NOTES macro

2019-10-10 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, make the Program Header
assignment restoration be part of the NOTES macro itself.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S   |  5 +
 arch/ia64/kernel/vmlinux.lds.S|  4 +---
 arch/mips/kernel/vmlinux.lds.S|  3 +--
 arch/powerpc/kernel/vmlinux.lds.S |  4 +---
 arch/s390/kernel/vmlinux.lds.S|  4 +---
 arch/x86/kernel/vmlinux.lds.S |  3 +--
 include/asm-generic/vmlinux.lds.h | 13 +++--
 7 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 363a60ba7c31..cdfdc91ce64c 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -34,10 +34,7 @@ SECTIONS
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   NOTES :text :note
-   .dummy : {
-   *(.dummy)
-   } :text
+   NOTES
 
RODATA
EXCEPTION_TABLE(16)
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 7cf4958b732d..bfc937ec168c 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -70,9 +70,7 @@ SECTIONS {
/*
 * Read-only data
 */
-   NOTES :text :note   /* put .notes in text and mark in PT_NOTE  */
-   code_continues : {
-   } :text/* switch back to regular program...  */
+   NOTES
 
EXCEPTION_TABLE(16)
 
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 1c95612eb800..6a22f531d815 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -81,8 +81,7 @@ SECTIONS
__stop___dbe_table = .;
}
 
-   NOTES NOTES_HEADERS
-   .dummy : { *(.dummy) } :text
+   NOTES
 
_sdata = .; /* Start of data section */
RODATA
diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 7e26e20c8324..4f19d814d592 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -164,9 +164,7 @@ SECTIONS
 #endif
EXCEPTION_TABLE(0)
 
-   NOTES :text :note
-   /* Restore program header away from PT_NOTE. */
-   .dummy : { *(.dummy) } :text
+   NOTES
 
 /*
  * Init sections discarded at runtime
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 646d939346df..f88eedeb915a 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -52,9 +52,7 @@ SECTIONS
_etext = .; /* End of text section */
} :text = 0x0700
 
-   NOTES :text :note
-
-   .dummy : { *(.dummy) } :text
+   NOTES
 
RO_DATA_SECTION(PAGE_SIZE)
 
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 2e18bf5c1aed..8be25b09c2b7 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -148,8 +148,7 @@ SECTIONS
_etext = .;
} :text = 0x9090
 
-   NOTES :text :note
-   .dummy : { *(.dummy) } :text
+   NOTES
 
EXCEPTION_TABLE(16)
 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index f5dd45ce73f1..97d4299f14dc 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -56,10 +56,18 @@
 
 /*
  * Only some architectures want to have the .notes segment visible in
- * a separate PT_NOTE ELF Program Header.
+ * a separate PT_NOTE ELF Program Header. When this happens, it needs
+ * to be visible in both the kernel text's PT_LOAD and the PT_NOTE
+ * Program Headers. In this case, though, the PT_LOAD needs to be made
+ * the default again so that all the following sections don't also end
+ * up in the PT_NOTE Program Header.
  */
 #ifdef EMITS_PT_NOTE
 #define NOTES_HEADERS  :text :note
+#define NOTES_HEADERS_RESTORE  __restore_ph : { *(.__restore_ph) } :text
+#else
+#define NOTES_HEADERS
+#define NOTES_HEADERS_RESTORE
 #endif
 
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
@@ -798,7 +806,8 @@
__start_notes = .;  \
KEEP(*(.note.*))\
__stop_notes = .;   \
-   }
+   } NOTES_HEADERS \
+   NOTES_HEADERS_RESTORE
 
 #define INIT_SETUP(initsetup_align)\
. = ALIGN(initsetup_align); \
-- 
2.17.1



[PATCH v2 28/29] x86/mm: Report actual image regions in /proc/iomem

2019-10-10 Thread Kees Cook
The resource reservations in /proc/iomem made for the kernel image did
not reflect the gaps between text, rodata, and data. Add the "rodata"
resource and update the start/end calculations to match the respective
calls to free_kernel_image_pages().

Before (booted with "nokaslr" for easier comparison):

0010-bffd9fff : System RAM
  0100-01e011d0 : Kernel code
  01e011d1-025619bf : Kernel data
  02a95000-035f : Kernel bss

After:

0010-bffd9fff : System RAM
  0100-01e011d0 : Kernel code
  0200-023d4fff : Kernel rodata
  0240-025619ff : Kernel data
  02a95000-035f : Kernel bss

Signed-off-by: Kees Cook 
---
 arch/x86/kernel/setup.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 77ea96b794bd..591e885a852e 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -143,6 +143,13 @@ struct boot_params boot_params;
 /*
  * Machine setup..
  */
+static struct resource rodata_resource = {
+   .name   = "Kernel rodata",
+   .start  = 0,
+   .end= 0,
+   .flags  = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
+};
+
 static struct resource data_resource = {
.name   = "Kernel data",
.start  = 0,
@@ -951,7 +958,9 @@ void __init setup_arch(char **cmdline_p)
 
code_resource.start = __pa_symbol(_text);
code_resource.end = __pa_symbol(_etext)-1;
-   data_resource.start = __pa_symbol(_etext);
+   rodata_resource.start = __pa_symbol(__start_rodata);
+   rodata_resource.end = __pa_symbol(__end_rodata)-1;
+   data_resource.start = __pa_symbol(_sdata);
data_resource.end = __pa_symbol(_edata)-1;
bss_resource.start = __pa_symbol(__bss_start);
bss_resource.end = __pa_symbol(__bss_stop)-1;
@@ -1040,6 +1049,7 @@ void __init setup_arch(char **cmdline_p)
 
/* after parse_early_param, so could debug it */
insert_resource(_resource, _resource);
+   insert_resource(_resource, _resource);
insert_resource(_resource, _resource);
insert_resource(_resource, _resource);
 
-- 
2.17.1



[PATCH v2 03/29] powerpc: Rename PT_LOAD identifier "kernel" to "text"

2019-10-10 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, rename the linker script
internal identifier for the PT_LOAD Program Header from "kernel" to
"text" to match other architectures.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index a3c8492b2b19..e184a63aa5b0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -18,7 +18,7 @@
 ENTRY(_stext)
 
 PHDRS {
-   kernel PT_LOAD FLAGS(7); /* RWX */
+   text PT_LOAD FLAGS(7); /* RWX */
note PT_NOTE FLAGS(0);
 }
 
@@ -63,7 +63,7 @@ SECTIONS
 #else /* !CONFIG_PPC64 */
HEAD_TEXT
 #endif
-   } :kernel
+   } :text
 
__head_end = .;
 
@@ -112,7 +112,7 @@ SECTIONS
__got2_end = .;
 #endif /* CONFIG_PPC32 */
 
-   } :kernel
+   } :text
 
. = ALIGN(ETEXT_ALIGN_SIZE);
_etext = .;
@@ -163,9 +163,9 @@ SECTIONS
 #endif
EXCEPTION_TABLE(0)
 
-   NOTES :kernel :note
+   NOTES :text :note
/* Restore program header away from PT_NOTE. */
-   .dummy : { *(.dummy) } :kernel
+   .dummy : { *(.dummy) } :text
 
 /*
  * Init sections discarded at runtime
@@ -180,7 +180,7 @@ SECTIONS
 #ifdef CONFIG_PPC64
*(.tramp.ftrace.init);
 #endif
-   } :kernel
+   } :text
 
/* .exit.text is discarded at runtime, not link time,
 * to deal with references from __bug_table
-- 
2.17.1



[PATCH v2 11/29] vmlinux.lds.h: Replace RODATA with RO_DATA

2019-10-10 Thread Kees Cook
There's no reason to keep the RODATA macro: replace the callers with
the expected RO_DATA macro.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S  | 2 +-
 arch/ia64/kernel/vmlinux.lds.S   | 2 +-
 arch/microblaze/kernel/vmlinux.lds.S | 2 +-
 arch/mips/kernel/vmlinux.lds.S   | 2 +-
 arch/um/include/asm/common.lds.S | 2 +-
 arch/xtensa/kernel/vmlinux.lds.S | 2 +-
 include/asm-generic/vmlinux.lds.h| 4 +---
 7 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index bf28043485f6..af411817dd7d 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -34,7 +34,7 @@ SECTIONS
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   RODATA
+   RO_DATA(4096)
EXCEPTION_TABLE(16)
 
/* Will be freed after init */
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index fae077595756..11d5115bc44d 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -104,7 +104,7 @@ SECTIONS {
code_continues2 : {
} :text
 
-   RODATA
+   RO_DATA(4096)
 
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
__start_opd = .;
diff --git a/arch/microblaze/kernel/vmlinux.lds.S 
b/arch/microblaze/kernel/vmlinux.lds.S
index d008e50bb212..2299694748ea 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -51,7 +51,7 @@ SECTIONS {
}
 
. = ALIGN(16);
-   RODATA
+   RO_DATA(4096)
EXCEPTION_TABLE(16)
 
/*
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 91e566defc16..a5f00ec73ea6 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -82,7 +82,7 @@ SECTIONS
}
 
_sdata = .; /* Start of data section */
-   RODATA
+   RO_DATA(4096)
 
/* writeable */
.data : {   /* Data */
diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S
index 91aca356095f..7145ce699982 100644
--- a/arch/um/include/asm/common.lds.S
+++ b/arch/um/include/asm/common.lds.S
@@ -9,7 +9,7 @@
   _sdata = .;
   PROVIDE (sdata = .);
 
-  RODATA
+  RO_DATA(4096)
 
   .unprotected : { *(.unprotected) }
   . = ALIGN(4096);
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index a0a843745695..b97e5798b9cf 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -124,7 +124,7 @@ SECTIONS
 
   . = ALIGN(16);
 
-  RODATA
+  RO_DATA(4096)
 
   /*  Relocation table */
 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index dc3390ec6b60..a0a989fbe411 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -518,9 +518,7 @@
. = ALIGN((align)); \
__end_rodata = .;
 
-/* RODATA & RO_DATA provided for backward compatibility.
- * All archs are supposed to use RO_DATA() */
-#define RODATA  RO_DATA_SECTION(4096)
+/* All archs are supposed to use RO_DATA() */
 #define RO_DATA(align)  RO_DATA_SECTION(align)
 
 /*
-- 
2.17.1



[PATCH v2 12/29] vmlinux.lds.h: Replace RO_DATA_SECTION with RO_DATA

2019-10-10 Thread Kees Cook
Finish renaming RO_DATA_SECTION to RO_DATA. (Calling this a "section"
is a lie, since it's multiple sections and section flags cannot be
applied to the macro.)

Signed-off-by: Kees Cook 
---
 arch/arc/kernel/vmlinux.lds.S   | 2 +-
 arch/c6x/kernel/vmlinux.lds.S   | 2 +-
 arch/csky/kernel/vmlinux.lds.S  | 2 +-
 arch/h8300/kernel/vmlinux.lds.S | 2 +-
 arch/hexagon/kernel/vmlinux.lds.S   | 2 +-
 arch/m68k/kernel/vmlinux-nommu.lds  | 2 +-
 arch/nds32/kernel/vmlinux.lds.S | 2 +-
 arch/nios2/kernel/vmlinux.lds.S | 2 +-
 arch/openrisc/kernel/vmlinux.lds.S  | 4 ++--
 arch/parisc/kernel/vmlinux.lds.S| 4 ++--
 arch/riscv/kernel/vmlinux.lds.S | 2 +-
 arch/s390/kernel/vmlinux.lds.S  | 2 +-
 arch/unicore32/kernel/vmlinux.lds.S | 2 +-
 include/asm-generic/vmlinux.lds.h   | 7 ++-
 14 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 1d6eef4b6976..7d1d27066deb 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -95,7 +95,7 @@ SECTIONS
_etext = .;
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
 
/*
 * 1. this is .data essentially
diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S
index d6e3802536b3..a3547f9d415b 100644
--- a/arch/c6x/kernel/vmlinux.lds.S
+++ b/arch/c6x/kernel/vmlinux.lds.S
@@ -82,7 +82,7 @@ SECTIONS
 
EXCEPTION_TABLE(16)
 
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
.const :
{
*(.const .const.* .gnu.linkonce.r.*)
diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S
index 75dd31412242..8598bd7a7bcd 100644
--- a/arch/csky/kernel/vmlinux.lds.S
+++ b/arch/csky/kernel/vmlinux.lds.S
@@ -49,7 +49,7 @@ SECTIONS
 
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 88776e785245..d3247d33b115 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -38,7 +38,7 @@ SECTIONS
_etext = . ;
}
EXCEPTION_TABLE(16)
-   RO_DATA_SECTION(4)
+   RO_DATA(4)
ROMEND = .;
 #if defined(CONFIG_ROMKERNEL)
. = RAMTOP;
diff --git a/arch/hexagon/kernel/vmlinux.lds.S 
b/arch/hexagon/kernel/vmlinux.lds.S
index 6a6e8fc422ee..0145251fa317 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
 
_sdata = .;
RW_DATA_SECTION(32,PAGE_SIZE,_THREAD_SIZE)
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
_edata = .;
 
EXCEPTION_TABLE(16)
diff --git a/arch/m68k/kernel/vmlinux-nommu.lds 
b/arch/m68k/kernel/vmlinux-nommu.lds
index cf6edda38971..de80f8b8ae78 100644
--- a/arch/m68k/kernel/vmlinux-nommu.lds
+++ b/arch/m68k/kernel/vmlinux-nommu.lds
@@ -60,7 +60,7 @@ SECTIONS {
 #endif
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
diff --git a/arch/nds32/kernel/vmlinux.lds.S b/arch/nds32/kernel/vmlinux.lds.S
index c4f1c5a604c3..10ff570ba95b 100644
--- a/arch/nds32/kernel/vmlinux.lds.S
+++ b/arch/nds32/kernel/vmlinux.lds.S
@@ -53,7 +53,7 @@ SECTIONS
_etext = .; /* End of text and rodata section */
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata  =  .;
 
diff --git a/arch/nios2/kernel/vmlinux.lds.S b/arch/nios2/kernel/vmlinux.lds.S
index 20e4078b3477..318804a2c7a1 100644
--- a/arch/nios2/kernel/vmlinux.lds.S
+++ b/arch/nios2/kernel/vmlinux.lds.S
@@ -49,7 +49,7 @@ SECTIONS
__init_end = .;
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
diff --git a/arch/openrisc/kernel/vmlinux.lds.S 
b/arch/openrisc/kernel/vmlinux.lds.S
index 142c51c994f5..f73e0d3ea09f 100644
--- a/arch/openrisc/kernel/vmlinux.lds.S
+++ b/arch/openrisc/kernel/vmlinux.lds.S
@@ -67,8 +67,8 @@ SECTIONS
 
_sdata = .;
 
-   /* Page alignment required for RO_DATA_SECTION */
-   RO_DATA_SECTION(PAGE_SIZE)
+   /* Page alignment required for RO_DATA */
+   RO_DATA(PAGE_SIZE)
_e_kernel_ro = .;
 
/* Whatever comes after _e_kernel_ro had better be page-aligend, too */
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 168d12b2ebb8..e1c563c7dca1 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -109,7 +109,7 @@ SECTIONS
_sdata = .;
 
/* Architecturally we need to keep __gp below

[PATCH v2 20/29] h8300: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
Since the EXCEPTION_TABLE is read-only, collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/h8300/kernel/vmlinux.lds.S | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 2ac7bdcd2fe0..6b1afc2f9b68 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+
+#define RO_EXCEPTION_TABLE_ALIGN   16
+
 #include 
 #include 
 #include 
@@ -37,7 +40,6 @@ SECTIONS
 #endif
_etext = . ;
}
-   EXCEPTION_TABLE(16)
RO_DATA(4)
ROMEND = .;
 #if defined(CONFIG_ROMKERNEL)
-- 
2.17.1



[PATCH v2 16/29] x86: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-10 Thread Kees Cook
The exception table was needlessly marked executable. In preparation
for execute-only memory, move the table into the RO_DATA segment via
the new macro that can be used by any architectures that want to make
a similar consolidation.

Signed-off-by: Kees Cook 
---
 arch/x86/kernel/vmlinux.lds.S | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index a1a758e25b2b..b06d6e1188de 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -22,6 +22,7 @@
 #endif
 
 #define EMITS_PT_NOTE
+#define RO_EXCEPTION_TABLE_ALIGN   16
 
 #include 
 #include 
@@ -145,8 +146,6 @@ SECTIONS
 #endif
} :text = 0x9090
 
-   EXCEPTION_TABLE(16)
-
/* End of text section, which should occupy whole number of pages */
_etext = .;
. = ALIGN(PAGE_SIZE);
-- 
2.17.1



[PATCH v2 06/29] s390: Move RO_DATA into "text" PT_LOAD Program Header

2019-10-10 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, move RO_DATA back into the
"text" PT_LOAD Program Header, as done with other architectures. The
"data" PT_LOAD now starts with the writable data section.

Signed-off-by: Kees Cook 
---
 arch/s390/kernel/vmlinux.lds.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 7e0eb4020917..13294fef473e 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -52,7 +52,7 @@ SECTIONS
 
NOTES :text :note
 
-   .dummy : { *(.dummy) } :data
+   .dummy : { *(.dummy) } :text
 
RO_DATA_SECTION(PAGE_SIZE)
 
@@ -64,7 +64,7 @@ SECTIONS
.data..ro_after_init : {
 *(.data..ro_after_init)
JUMP_TABLE_DATA
-   }
+   } :data
EXCEPTION_TABLE(16)
. = ALIGN(PAGE_SIZE);
__end_ro_after_init = .;
-- 
2.17.1



[PATCH v2 10/29] vmlinux.lds.h: Move NOTES into RO_DATA

2019-10-10 Thread Kees Cook
The .notes section should be non-executable read-only data. As such,
move it to the RO_DATA macro instead of being per-architecture defined.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S  | 2 --
 arch/arc/kernel/vmlinux.lds.S| 2 --
 arch/arm/kernel/vmlinux-xip.lds.S| 2 --
 arch/arm/kernel/vmlinux.lds.S| 2 --
 arch/arm64/kernel/vmlinux.lds.S  | 1 -
 arch/c6x/kernel/vmlinux.lds.S| 1 -
 arch/csky/kernel/vmlinux.lds.S   | 1 -
 arch/h8300/kernel/vmlinux.lds.S  | 1 -
 arch/hexagon/kernel/vmlinux.lds.S| 1 -
 arch/ia64/kernel/vmlinux.lds.S   | 2 --
 arch/microblaze/kernel/vmlinux.lds.S | 1 -
 arch/mips/kernel/vmlinux.lds.S   | 2 --
 arch/nds32/kernel/vmlinux.lds.S  | 1 -
 arch/nios2/kernel/vmlinux.lds.S  | 1 -
 arch/openrisc/kernel/vmlinux.lds.S   | 1 -
 arch/parisc/kernel/vmlinux.lds.S | 1 -
 arch/powerpc/kernel/vmlinux.lds.S| 2 --
 arch/riscv/kernel/vmlinux.lds.S  | 1 -
 arch/s390/kernel/vmlinux.lds.S   | 2 --
 arch/sh/kernel/vmlinux.lds.S | 1 -
 arch/sparc/kernel/vmlinux.lds.S  | 1 -
 arch/um/include/asm/common.lds.S | 1 -
 arch/unicore32/kernel/vmlinux.lds.S  | 1 -
 arch/x86/kernel/vmlinux.lds.S| 2 --
 arch/xtensa/kernel/vmlinux.lds.S | 1 -
 include/asm-generic/vmlinux.lds.h| 9 +
 26 files changed, 5 insertions(+), 38 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index cdfdc91ce64c..bf28043485f6 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -34,8 +34,6 @@ SECTIONS
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   NOTES
-
RODATA
EXCEPTION_TABLE(16)
 
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 6c693a9d29b6..1d6eef4b6976 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -118,8 +118,6 @@ SECTIONS
/DISCARD/ : {   *(.eh_frame) }
 #endif
 
-   NOTES
-
. = ALIGN(PAGE_SIZE);
_end = . ;
 
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S 
b/arch/arm/kernel/vmlinux-xip.lds.S
index 8c74037ade22..d2a9651c24ad 100644
--- a/arch/arm/kernel/vmlinux-xip.lds.S
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
@@ -70,8 +70,6 @@ SECTIONS
ARM_UNWIND_SECTIONS
 #endif
 
-   NOTES
-
_etext = .; /* End of text and rodata section */
 
ARM_VECTORS
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 23150c0f0f4d..068db6860867 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -81,8 +81,6 @@ SECTIONS
ARM_UNWIND_SECTIONS
 #endif
 
-   NOTES
-
 #ifdef CONFIG_STRICT_KERNEL_RWX
. = ALIGN(1<

Re: [PATCH 00/29] vmlinux.lds.h: Refactor EXCEPTION_TABLE and NOTES

2019-10-10 Thread Kees Cook
On Thu, Oct 10, 2019 at 08:03:31PM +0200, Borislav Petkov wrote:
> On Thu, Sep 26, 2019 at 10:55:33AM -0700, Kees Cook wrote:
> > This series works to move the linker sections for NOTES and
> > EXCEPTION_TABLE into the RO_DATA area, where they belong on most
> > (all?) architectures. The problem being addressed was the discovery
> > by Rick Edgecombe that the exception table was accidentally marked
> > executable while he was developing his execute-only-memory series. When
> > permissions were flipped from readable-and-executable to only-executable,
> > the exception table became unreadable, causing things to explode rather
> > badly. :)
> > 
> > Roughly speaking, the steps are:
> > 
> > - regularize the linker names for PT_NOTE and PT_LOAD program headers
> >   (to "note" and "text" respectively)
> > - regularize restoration of linker section to program header assignment
> >   (when PT_NOTE exists)
> > - move NOTES into RO_DATA
> > - finish macro naming conversions for RO_DATA and RW_DATA
> > - move EXCEPTION_TABLE into RO_DATA on architectures where this is clear
> > - clean up some x86-specific reporting of kernel memory resources
> > - switch x86 linker fill byte from x90 (NOP) to 0xcc (INT3), just because
> >   I finally realized what that trailing ": 0x9090" meant -- and we should
> >   trap, not slide, if execution lands in section padding
> 
> Yap, nice patchset overall.

Thanks!

> > Since these changes are treewide, I'd love to get architecture-maintainer
> > Acks and either have this live in x86 -tip or in my own tree, however
> > people think it should go.
> 
> Sure, I don't mind taking v2 through tip once I get ACKs from the
> respective arch maintainers.

Okay, excellent. I've only had acks from arm64, but I'll call it out
again in v2. Thanks for the review!

-- 
Kees Cook


Re: [PATCH 18/29] arm64: Move EXCEPTION_TABLE to RO_DATA segment

2019-10-01 Thread Kees Cook
On Tue, Oct 01, 2019 at 10:03:56AM +0100, Will Deacon wrote:
> Hi Kees,
> 
> On Thu, Sep 26, 2019 at 10:55:51AM -0700, Kees Cook wrote:
> > The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.
> > 
> > Signed-off-by: Kees Cook 
> > ---
> >  arch/arm64/kernel/vmlinux.lds.S | 6 --
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/vmlinux.lds.S 
> > b/arch/arm64/kernel/vmlinux.lds.S
> > index 81d94e371c95..c6ba2eee0ee8 100644
> > --- a/arch/arm64/kernel/vmlinux.lds.S
> > +++ b/arch/arm64/kernel/vmlinux.lds.S
> > @@ -5,6 +5,8 @@
> >   * Written by Martin Mares 
> >   */
> >  
> > +#define RO_DATA_EXCEPTION_TABLE_ALIGN  8
> > +
> >  #include 
> >  #include 
> >  #include 
> > @@ -135,8 +137,8 @@ SECTIONS
> > . = ALIGN(SEGMENT_ALIGN);
> > _etext = .; /* End of text section */
> >  
> > -   RO_DATA(PAGE_SIZE)  /* everything from this point to */
> > -   EXCEPTION_TABLE(8)  /* __init_begin will be marked RO NX */
> > +   /* everything from this point to __init_begin will be marked RO NX */
> > +   RO_DATA(PAGE_SIZE)
> >  
> > . = ALIGN(PAGE_SIZE);
> 
> Do you reckon it would be worth merging this last ALIGN directive into the
> RO_DATA definition too? Given that we want to map the thing read-only, it
> really has to be aligned either side.

Actually, taking a closer look, this appears to be redundant: RO_DATA()
ends with:

. = ALIGN(align)

(where "align" is the "PAGE_SIZE" argument to RO_DATA())

> Anyway, that's only a nit, so:
> 
> Acked-by: Will Deacon 

Thanks!

> P.S. Please CC the arm64 maintainers on arm64 patches -- I nearly missed
> this one!

Okay, I can re-expand my list. I originally had done this but it was
getting to be a rather large set of people. :)

-- 
Kees Cook


[PATCH 23/29] parisc: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/parisc/kernel/vmlinux.lds.S | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 12b3d7d5e9e4..1dc2f71e62b1 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -19,6 +19,7 @@
*(.data..vm0.pte)
 
 #define CC_USING_PATCHABLE_FUNCTION_ENTRY
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  8
 
 #include 
 
@@ -129,9 +130,6 @@ SECTIONS
 
RO_DATA(8)
 
-   /* RO because of BUILDTIME_EXTABLE_SORT */
-   EXCEPTION_TABLE(8)
-
/* unwind info */
.PARISC.unwind : {
__start___unwind = .;
-- 
2.17.1



[PATCH 21/29] ia64: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/ia64/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 0d86fc8e88d5..18a732597112 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
 #include 
 
 #define EMITS_PT_NOTE
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  16
 
 #include 
 
@@ -70,7 +71,6 @@ SECTIONS {
/*
 * Read-only data
 */
-   EXCEPTION_TABLE(16)
 
/* MCA table */
. = ALIGN(16);
-- 
2.17.1



[PATCH 11/29] vmlinux.lds.h: Replace RODATA with RO_DATA

2019-09-26 Thread Kees Cook
There's no reason to keep the RODATA macro: just replace the callers
with the expected RO_DATA macro.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S  | 2 +-
 arch/ia64/kernel/vmlinux.lds.S   | 2 +-
 arch/microblaze/kernel/vmlinux.lds.S | 2 +-
 arch/mips/kernel/vmlinux.lds.S   | 2 +-
 arch/um/include/asm/common.lds.S | 2 +-
 arch/xtensa/kernel/vmlinux.lds.S | 2 +-
 include/asm-generic/vmlinux.lds.h| 4 +---
 7 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index bf28043485f6..af411817dd7d 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -34,7 +34,7 @@ SECTIONS
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   RODATA
+   RO_DATA(4096)
EXCEPTION_TABLE(16)
 
/* Will be freed after init */
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index ad3578924589..0d86fc8e88d5 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -104,7 +104,7 @@ SECTIONS {
code_continues2 : {
} :text
 
-   RODATA
+   RO_DATA(4096)
 
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
__start_opd = .;
diff --git a/arch/microblaze/kernel/vmlinux.lds.S 
b/arch/microblaze/kernel/vmlinux.lds.S
index d008e50bb212..2299694748ea 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -51,7 +51,7 @@ SECTIONS {
}
 
. = ALIGN(16);
-   RODATA
+   RO_DATA(4096)
EXCEPTION_TABLE(16)
 
/*
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 91e566defc16..a5f00ec73ea6 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -82,7 +82,7 @@ SECTIONS
}
 
_sdata = .; /* Start of data section */
-   RODATA
+   RO_DATA(4096)
 
/* writeable */
.data : {   /* Data */
diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S
index a24b284f5135..eca6c452a41b 100644
--- a/arch/um/include/asm/common.lds.S
+++ b/arch/um/include/asm/common.lds.S
@@ -9,7 +9,7 @@
   _sdata = .;
   PROVIDE (sdata = .);
 
-  RODATA
+  RO_DATA(4096)
 
   .unprotected : { *(.unprotected) }
   . = ALIGN(4096);
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index a0a843745695..b97e5798b9cf 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -124,7 +124,7 @@ SECTIONS
 
   . = ALIGN(16);
 
-  RODATA
+  RO_DATA(4096)
 
   /*  Relocation table */
 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 3a4c1cb971da..9520dede6c7a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -513,9 +513,7 @@
. = ALIGN((align)); \
__end_rodata = .;
 
-/* RODATA & RO_DATA provided for backward compatibility.
- * All archs are supposed to use RO_DATA() */
-#define RODATA  RO_DATA_SECTION(4096)
+/* All archs are supposed to use RO_DATA() */
 #define RO_DATA(align)  RO_DATA_SECTION(align)
 
 /*
-- 
2.17.1



[PATCH 15/29] x86: Actually use _etext for end of text segment

2019-09-26 Thread Kees Cook
Various calculations are using the end of the exception table (which
does not need to be executable) as the end of the text segment. Instead,
in preparation for moving the exception table into RO_DATA, move _etext
after the exception table and update the calculations.

Signed-off-by: Kees Cook 
---
 arch/x86/include/asm/sections.h | 1 -
 arch/x86/kernel/vmlinux.lds.S   | 7 +++
 arch/x86/mm/init_64.c   | 6 +++---
 arch/x86/mm/pti.c   | 2 +-
 4 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
index 71b32f2570ab..036c360910c5 100644
--- a/arch/x86/include/asm/sections.h
+++ b/arch/x86/include/asm/sections.h
@@ -6,7 +6,6 @@
 #include 
 
 extern char __brk_base[], __brk_limit[];
-extern struct exception_table_entry __stop___ex_table[];
 extern char __end_rodata_aligned[];
 
 #if defined(CONFIG_X86_64)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 41362e90142d..a1a758e25b2b 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -143,15 +143,14 @@ SECTIONS
*(.text.__x86.indirect_thunk)
__indirect_thunk_end = .;
 #endif
-
-   /* End of text section */
-   _etext = .;
} :text = 0x9090
 
EXCEPTION_TABLE(16)
 
-   /* .text should occupy whole number of pages */
+   /* End of text section, which should occupy whole number of pages */
+   _etext = .;
. = ALIGN(PAGE_SIZE);
+
X86_ALIGN_RODATA_BEGIN
RO_DATA(PAGE_SIZE)
X86_ALIGN_RODATA_END
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a6b5c653727b..26299e9ce6da 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1263,7 +1263,7 @@ int kernel_set_to_readonly;
 void set_kernel_text_rw(void)
 {
unsigned long start = PFN_ALIGN(_text);
-   unsigned long end = PFN_ALIGN(__stop___ex_table);
+   unsigned long end = PFN_ALIGN(_etext);
 
if (!kernel_set_to_readonly)
return;
@@ -1282,7 +1282,7 @@ void set_kernel_text_rw(void)
 void set_kernel_text_ro(void)
 {
unsigned long start = PFN_ALIGN(_text);
-   unsigned long end = PFN_ALIGN(__stop___ex_table);
+   unsigned long end = PFN_ALIGN(_etext);
 
if (!kernel_set_to_readonly)
return;
@@ -1301,7 +1301,7 @@ void mark_rodata_ro(void)
unsigned long start = PFN_ALIGN(_text);
unsigned long rodata_start = PFN_ALIGN(__start_rodata);
unsigned long end = (unsigned long) &__end_rodata_hpage_align;
-   unsigned long text_end = PFN_ALIGN(&__stop___ex_table);
+   unsigned long text_end = PFN_ALIGN(&_etext);
unsigned long rodata_end = PFN_ALIGN(&__end_rodata);
unsigned long all_end;
 
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index b196524759ec..bd3404fd9d80 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -572,7 +572,7 @@ static void pti_clone_kernel_text(void)
 */
unsigned long start = PFN_ALIGN(_text);
unsigned long end_clone  = (unsigned long)__end_rodata_aligned;
-   unsigned long end_global = PFN_ALIGN((unsigned long)__stop___ex_table);
+   unsigned long end_global = PFN_ALIGN((unsigned long)_etext);
 
if (!pti_kernel_image_global_ok())
return;
-- 
2.17.1



[PATCH 22/29] microblaze: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/microblaze/kernel/vmlinux.lds.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/microblaze/kernel/vmlinux.lds.S 
b/arch/microblaze/kernel/vmlinux.lds.S
index b8efb08204a1..abe5ff0f3773 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -11,6 +11,8 @@
 OUTPUT_ARCH(microblaze)
 ENTRY(microblaze_start)
 
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  16
+
 #include 
 #include 
 #include 
@@ -52,7 +54,6 @@ SECTIONS {
 
. = ALIGN(16);
RO_DATA(4096)
-   EXCEPTION_TABLE(16)
 
/*
 * sdata2 section can go anywhere, but must be word aligned
-- 
2.17.1



[PATCH 16/29] x86: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The exception table was needlessly marked executable. In preparation
for execute-only memory, this moves the table into the RO_DATA segment
via a new macro that can be used by any architectures that want to make
a similar consolidation.

Signed-off-by: Kees Cook 
---
 arch/x86/kernel/vmlinux.lds.S | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index a1a758e25b2b..a5c8571e4967 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -22,6 +22,7 @@
 #endif
 
 #define EMITS_PT_NOTE
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  16
 
 #include 
 #include 
@@ -145,8 +146,6 @@ SECTIONS
 #endif
} :text = 0x9090
 
-   EXCEPTION_TABLE(16)
-
/* End of text section, which should occupy whole number of pages */
_etext = .;
. = ALIGN(PAGE_SIZE);
-- 
2.17.1



[PATCH 03/29] powerpc: Rename PT_LOAD identifier "kernel" to "text"

2019-09-26 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, this renames the linker
script internal identifier for the PT_LOAD Program Header from "kernel"
to "text" to match other architectures.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index a3c8492b2b19..e184a63aa5b0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -18,7 +18,7 @@
 ENTRY(_stext)
 
 PHDRS {
-   kernel PT_LOAD FLAGS(7); /* RWX */
+   text PT_LOAD FLAGS(7); /* RWX */
note PT_NOTE FLAGS(0);
 }
 
@@ -63,7 +63,7 @@ SECTIONS
 #else /* !CONFIG_PPC64 */
HEAD_TEXT
 #endif
-   } :kernel
+   } :text
 
__head_end = .;
 
@@ -112,7 +112,7 @@ SECTIONS
__got2_end = .;
 #endif /* CONFIG_PPC32 */
 
-   } :kernel
+   } :text
 
. = ALIGN(ETEXT_ALIGN_SIZE);
_etext = .;
@@ -163,9 +163,9 @@ SECTIONS
 #endif
EXCEPTION_TABLE(0)
 
-   NOTES :kernel :note
+   NOTES :text :note
/* Restore program header away from PT_NOTE. */
-   .dummy : { *(.dummy) } :kernel
+   .dummy : { *(.dummy) } :text
 
 /*
  * Init sections discarded at runtime
@@ -180,7 +180,7 @@ SECTIONS
 #ifdef CONFIG_PPC64
*(.tramp.ftrace.init);
 #endif
-   } :kernel
+   } :text
 
/* .exit.text is discarded at runtime, not link time,
 * to deal with references from __bug_table
-- 
2.17.1



[PATCH 00/29] vmlinux.lds.h: Refactor EXCEPTION_TABLE and NOTES

2019-09-26 Thread Kees Cook
This series works to move the linker sections for NOTES and
EXCEPTION_TABLE into the RO_DATA area, where they belong on most
(all?) architectures. The problem being addressed was the discovery
by Rick Edgecombe that the exception table was accidentally marked
executable while he was developing his execute-only-memory series. When
permissions were flipped from readable-and-executable to only-executable,
the exception table became unreadable, causing things to explode rather
badly. :)

Roughly speaking, the steps are:

- regularize the linker names for PT_NOTE and PT_LOAD program headers
  (to "note" and "text" respectively)
- regularize restoration of linker section to program header assignment
  (when PT_NOTE exists)
- move NOTES into RO_DATA
- finish macro naming conversions for RO_DATA and RW_DATA
- move EXCEPTION_TABLE into RO_DATA on architectures where this is clear
- clean up some x86-specific reporting of kernel memory resources
- switch x86 linker fill byte from x90 (NOP) to 0xcc (INT3), just because
  I finally realized what that trailing ": 0x9090" meant -- and we should
  trap, not slide, if execution lands in section padding

Since these changes are treewide, I'd love to get architecture-maintainer
Acks and either have this live in x86 -tip or in my own tree, however
people think it should go.

Thanks!

-Kees

Kees Cook (29):
  powerpc: Rename "notes" PT_NOTE to "note"
  powerpc: Remove PT_NOTE workaround
  powerpc: Rename PT_LOAD identifier "kernel" to "text"
  alpha: Rename PT_LOAD identifier "kernel" to "text"
  ia64: Rename PT_LOAD identifier "code" to "text"
  s390: Move RO_DATA into "text" PT_LOAD Program Header
  x86: Restore "text" Program Header with dummy section
  vmlinux.lds.h: Provide EMIT_PT_NOTE to indicate export of .notes
  vmlinux.lds.h: Move Program Header restoration into NOTES macro
  vmlinux.lds.h: Move NOTES into RO_DATA
  vmlinux.lds.h: Replace RODATA with RO_DATA
  vmlinux.lds.h: Replace RO_DATA_SECTION with RO_DATA
  vmlinux.lds.h: Replace RW_DATA_SECTION with RW_DATA
  vmlinux.lds.h: Allow EXCEPTION_TABLE to live in RO_DATA
  x86: Actually use _etext for end of text segment
  x86: Move EXCEPTION_TABLE to RO_DATA segment
  alpha: Move EXCEPTION_TABLE to RO_DATA segment
  arm64: Move EXCEPTION_TABLE to RO_DATA segment
  c6x: Move EXCEPTION_TABLE to RO_DATA segment
  h8300: Move EXCEPTION_TABLE to RO_DATA segment
  ia64: Move EXCEPTION_TABLE to RO_DATA segment
  microblaze: Move EXCEPTION_TABLE to RO_DATA segment
  parisc: Move EXCEPTION_TABLE to RO_DATA segment
  powerpc: Move EXCEPTION_TABLE to RO_DATA segment
  xtensa: Move EXCEPTION_TABLE to RO_DATA segment
  x86/mm: Remove redundant  on addresses
  x86/mm: Report which part of kernel image is freed
  x86/mm: Report actual image regions in /proc/iomem
  x86: Use INT3 instead of NOP for linker fill bytes

 arch/alpha/kernel/vmlinux.lds.S  | 18 +-
 arch/arc/kernel/vmlinux.lds.S|  6 ++--
 arch/arm/kernel/vmlinux-xip.lds.S|  4 +--
 arch/arm/kernel/vmlinux.lds.S|  4 +--
 arch/arm64/kernel/vmlinux.lds.S  |  9 ++---
 arch/c6x/kernel/vmlinux.lds.S|  8 ++---
 arch/csky/kernel/vmlinux.lds.S   |  5 ++-
 arch/h8300/kernel/vmlinux.lds.S  |  9 ++---
 arch/hexagon/kernel/vmlinux.lds.S|  5 ++-
 arch/ia64/kernel/vmlinux.lds.S   | 20 +--
 arch/m68k/kernel/vmlinux-nommu.lds   |  4 +--
 arch/m68k/kernel/vmlinux-std.lds |  2 +-
 arch/m68k/kernel/vmlinux-sun3.lds|  2 +-
 arch/microblaze/kernel/vmlinux.lds.S |  8 ++---
 arch/mips/kernel/vmlinux.lds.S   | 15 
 arch/nds32/kernel/vmlinux.lds.S  |  5 ++-
 arch/nios2/kernel/vmlinux.lds.S  |  5 ++-
 arch/openrisc/kernel/vmlinux.lds.S   |  7 ++--
 arch/parisc/kernel/vmlinux.lds.S | 11 +++---
 arch/powerpc/kernel/vmlinux.lds.S| 37 ---
 arch/riscv/kernel/vmlinux.lds.S  |  5 ++-
 arch/s390/kernel/vmlinux.lds.S   | 12 +++
 arch/sh/kernel/vmlinux.lds.S |  3 +-
 arch/sparc/kernel/vmlinux.lds.S  |  3 +-
 arch/um/include/asm/common.lds.S |  3 +-
 arch/unicore32/kernel/vmlinux.lds.S  |  5 ++-
 arch/x86/include/asm/processor.h |  2 +-
 arch/x86/include/asm/sections.h  |  1 -
 arch/x86/kernel/setup.c  | 12 ++-
 arch/x86/kernel/vmlinux.lds.S| 16 -
 arch/x86/mm/init.c   |  8 ++---
 arch/x86/mm/init_64.c| 16 +
 arch/x86/mm/pti.c|  2 +-
 arch/xtensa/kernel/vmlinux.lds.S |  8 ++---
 include/asm-generic/vmlinux.lds.h| 53 
 35 files changed, 159 insertions(+), 174 deletions(-)

-- 
2.17.1



[PATCH 12/29] vmlinux.lds.h: Replace RO_DATA_SECTION with RO_DATA

2019-09-26 Thread Kees Cook
This finishes renaming RO_DATA_SECTION to RO_DATA. (Calling this a
"section" is a lie, since it's multiple sections and section flags cannot
be applied to the macro.)

Signed-off-by: Kees Cook 
---
 arch/arc/kernel/vmlinux.lds.S   | 2 +-
 arch/c6x/kernel/vmlinux.lds.S   | 2 +-
 arch/csky/kernel/vmlinux.lds.S  | 2 +-
 arch/h8300/kernel/vmlinux.lds.S | 2 +-
 arch/hexagon/kernel/vmlinux.lds.S   | 2 +-
 arch/m68k/kernel/vmlinux-nommu.lds  | 2 +-
 arch/nds32/kernel/vmlinux.lds.S | 2 +-
 arch/nios2/kernel/vmlinux.lds.S | 2 +-
 arch/openrisc/kernel/vmlinux.lds.S  | 4 ++--
 arch/parisc/kernel/vmlinux.lds.S| 4 ++--
 arch/riscv/kernel/vmlinux.lds.S | 2 +-
 arch/s390/kernel/vmlinux.lds.S  | 2 +-
 arch/unicore32/kernel/vmlinux.lds.S | 2 +-
 include/asm-generic/vmlinux.lds.h   | 7 ++-
 14 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 1d6eef4b6976..7d1d27066deb 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -95,7 +95,7 @@ SECTIONS
_etext = .;
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
 
/*
 * 1. this is .data essentially
diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S
index d6e3802536b3..a3547f9d415b 100644
--- a/arch/c6x/kernel/vmlinux.lds.S
+++ b/arch/c6x/kernel/vmlinux.lds.S
@@ -82,7 +82,7 @@ SECTIONS
 
EXCEPTION_TABLE(16)
 
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
.const :
{
*(.const .const.* .gnu.linkonce.r.*)
diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S
index 75dd31412242..8598bd7a7bcd 100644
--- a/arch/csky/kernel/vmlinux.lds.S
+++ b/arch/csky/kernel/vmlinux.lds.S
@@ -49,7 +49,7 @@ SECTIONS
 
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 88776e785245..d3247d33b115 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -38,7 +38,7 @@ SECTIONS
_etext = . ;
}
EXCEPTION_TABLE(16)
-   RO_DATA_SECTION(4)
+   RO_DATA(4)
ROMEND = .;
 #if defined(CONFIG_ROMKERNEL)
. = RAMTOP;
diff --git a/arch/hexagon/kernel/vmlinux.lds.S 
b/arch/hexagon/kernel/vmlinux.lds.S
index 6a6e8fc422ee..0145251fa317 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
 
_sdata = .;
RW_DATA_SECTION(32,PAGE_SIZE,_THREAD_SIZE)
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
_edata = .;
 
EXCEPTION_TABLE(16)
diff --git a/arch/m68k/kernel/vmlinux-nommu.lds 
b/arch/m68k/kernel/vmlinux-nommu.lds
index cf6edda38971..de80f8b8ae78 100644
--- a/arch/m68k/kernel/vmlinux-nommu.lds
+++ b/arch/m68k/kernel/vmlinux-nommu.lds
@@ -60,7 +60,7 @@ SECTIONS {
 #endif
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
diff --git a/arch/nds32/kernel/vmlinux.lds.S b/arch/nds32/kernel/vmlinux.lds.S
index c4f1c5a604c3..10ff570ba95b 100644
--- a/arch/nds32/kernel/vmlinux.lds.S
+++ b/arch/nds32/kernel/vmlinux.lds.S
@@ -53,7 +53,7 @@ SECTIONS
_etext = .; /* End of text and rodata section */
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata  =  .;
 
diff --git a/arch/nios2/kernel/vmlinux.lds.S b/arch/nios2/kernel/vmlinux.lds.S
index 20e4078b3477..318804a2c7a1 100644
--- a/arch/nios2/kernel/vmlinux.lds.S
+++ b/arch/nios2/kernel/vmlinux.lds.S
@@ -49,7 +49,7 @@ SECTIONS
__init_end = .;
 
_sdata = .;
-   RO_DATA_SECTION(PAGE_SIZE)
+   RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
diff --git a/arch/openrisc/kernel/vmlinux.lds.S 
b/arch/openrisc/kernel/vmlinux.lds.S
index 142c51c994f5..f73e0d3ea09f 100644
--- a/arch/openrisc/kernel/vmlinux.lds.S
+++ b/arch/openrisc/kernel/vmlinux.lds.S
@@ -67,8 +67,8 @@ SECTIONS
 
_sdata = .;
 
-   /* Page alignment required for RO_DATA_SECTION */
-   RO_DATA_SECTION(PAGE_SIZE)
+   /* Page alignment required for RO_DATA */
+   RO_DATA(PAGE_SIZE)
_e_kernel_ro = .;
 
/* Whatever comes after _e_kernel_ro had better be page-aligend, too */
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 168d12b2ebb8..e1c563c7dca1 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -109,7 +109,7 @@ SECTIONS
_sdata = .;
 
/* Architecturally we need to keep 

[PATCH 07/29] x86: Restore "text" Program Header with dummy section

2019-09-26 Thread Kees Cook
Instead of depending on markings in the section following NOTES to
restore the associated Program Header, use a dummy section, as done
in other architectures. This is preparation for moving NOTES into the
RO_DATA macro.

Signed-off-by: Kees Cook 
---
 arch/x86/kernel/vmlinux.lds.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index e2feacf921a0..788e78978030 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -147,8 +147,9 @@ SECTIONS
} :text = 0x9090
 
NOTES :text :note
+   .dummy : { *(.dummy) } :text
 
-   EXCEPTION_TABLE(16) :text = 0x9090
+   EXCEPTION_TABLE(16)
 
/* .text should occupy whole number of pages */
. = ALIGN(PAGE_SIZE);
-- 
2.17.1



[PATCH 10/29] vmlinux.lds.h: Move NOTES into RO_DATA

2019-09-26 Thread Kees Cook
The .notes section should be non-executable read-only data. As such, it
can live in the RO_DATA macro instead of being per-architecture defined.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S  | 2 --
 arch/arc/kernel/vmlinux.lds.S| 2 --
 arch/arm/kernel/vmlinux-xip.lds.S| 2 --
 arch/arm/kernel/vmlinux.lds.S| 2 --
 arch/arm64/kernel/vmlinux.lds.S  | 1 -
 arch/c6x/kernel/vmlinux.lds.S| 1 -
 arch/csky/kernel/vmlinux.lds.S   | 1 -
 arch/h8300/kernel/vmlinux.lds.S  | 1 -
 arch/hexagon/kernel/vmlinux.lds.S| 1 -
 arch/ia64/kernel/vmlinux.lds.S   | 2 --
 arch/microblaze/kernel/vmlinux.lds.S | 1 -
 arch/mips/kernel/vmlinux.lds.S   | 2 --
 arch/nds32/kernel/vmlinux.lds.S  | 1 -
 arch/nios2/kernel/vmlinux.lds.S  | 1 -
 arch/openrisc/kernel/vmlinux.lds.S   | 1 -
 arch/parisc/kernel/vmlinux.lds.S | 1 -
 arch/powerpc/kernel/vmlinux.lds.S| 2 --
 arch/riscv/kernel/vmlinux.lds.S  | 1 -
 arch/s390/kernel/vmlinux.lds.S   | 2 --
 arch/sh/kernel/vmlinux.lds.S | 1 -
 arch/sparc/kernel/vmlinux.lds.S  | 1 -
 arch/um/include/asm/common.lds.S | 1 -
 arch/unicore32/kernel/vmlinux.lds.S  | 1 -
 arch/x86/kernel/vmlinux.lds.S| 2 --
 arch/xtensa/kernel/vmlinux.lds.S | 1 -
 include/asm-generic/vmlinux.lds.h| 9 +
 26 files changed, 5 insertions(+), 38 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index cdfdc91ce64c..bf28043485f6 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -34,8 +34,6 @@ SECTIONS
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   NOTES
-
RODATA
EXCEPTION_TABLE(16)
 
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 6c693a9d29b6..1d6eef4b6976 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -118,8 +118,6 @@ SECTIONS
/DISCARD/ : {   *(.eh_frame) }
 #endif
 
-   NOTES
-
. = ALIGN(PAGE_SIZE);
_end = . ;
 
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S 
b/arch/arm/kernel/vmlinux-xip.lds.S
index 8c74037ade22..d2a9651c24ad 100644
--- a/arch/arm/kernel/vmlinux-xip.lds.S
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
@@ -70,8 +70,6 @@ SECTIONS
ARM_UNWIND_SECTIONS
 #endif
 
-   NOTES
-
_etext = .; /* End of text and rodata section */
 
ARM_VECTORS
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 23150c0f0f4d..068db6860867 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -81,8 +81,6 @@ SECTIONS
ARM_UNWIND_SECTIONS
 #endif
 
-   NOTES
-
 #ifdef CONFIG_STRICT_KERNEL_RWX
. = ALIGN(1<

[PATCH 18/29] arm64: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/arm64/kernel/vmlinux.lds.S | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 81d94e371c95..c6ba2eee0ee8 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -5,6 +5,8 @@
  * Written by Martin Mares 
  */
 
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  8
+
 #include 
 #include 
 #include 
@@ -135,8 +137,8 @@ SECTIONS
. = ALIGN(SEGMENT_ALIGN);
_etext = .; /* End of text section */
 
-   RO_DATA(PAGE_SIZE)  /* everything from this point to */
-   EXCEPTION_TABLE(8)  /* __init_begin will be marked RO NX */
+   /* everything from this point to __init_begin will be marked RO NX */
+   RO_DATA(PAGE_SIZE)
 
. = ALIGN(PAGE_SIZE);
idmap_pg_dir = .;
-- 
2.17.1



[PATCH 09/29] vmlinux.lds.h: Move Program Header restoration into NOTES macro

2019-09-26 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, the Program Header
assignment restoration needs to be part of the NOTES macro itself.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S   |  5 +
 arch/ia64/kernel/vmlinux.lds.S|  4 +---
 arch/mips/kernel/vmlinux.lds.S|  3 +--
 arch/powerpc/kernel/vmlinux.lds.S |  4 +---
 arch/s390/kernel/vmlinux.lds.S|  4 +---
 arch/x86/kernel/vmlinux.lds.S |  3 +--
 include/asm-generic/vmlinux.lds.h | 13 +++--
 7 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 363a60ba7c31..cdfdc91ce64c 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -34,10 +34,7 @@ SECTIONS
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   NOTES :text :note
-   .dummy : {
-   *(.dummy)
-   } :text
+   NOTES
 
RODATA
EXCEPTION_TABLE(16)
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index e034a6a4a444..fdcc992ab360 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -70,9 +70,7 @@ SECTIONS {
/*
 * Read-only data
 */
-   NOTES :text :note   /* put .notes in text and mark in PT_NOTE  */
-   code_continues : {
-   } :text/* switch back to regular program...  */
+   NOTES
 
EXCEPTION_TABLE(16)
 
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 1c95612eb800..6a22f531d815 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -81,8 +81,7 @@ SECTIONS
__stop___dbe_table = .;
}
 
-   NOTES NOTES_HEADERS
-   .dummy : { *(.dummy) } :text
+   NOTES
 
_sdata = .; /* Start of data section */
RODATA
diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 7e26e20c8324..4f19d814d592 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -164,9 +164,7 @@ SECTIONS
 #endif
EXCEPTION_TABLE(0)
 
-   NOTES :text :note
-   /* Restore program header away from PT_NOTE. */
-   .dummy : { *(.dummy) } :text
+   NOTES
 
 /*
  * Init sections discarded at runtime
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 646d939346df..f88eedeb915a 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -52,9 +52,7 @@ SECTIONS
_etext = .; /* End of text section */
} :text = 0x0700
 
-   NOTES :text :note
-
-   .dummy : { *(.dummy) } :text
+   NOTES
 
RO_DATA_SECTION(PAGE_SIZE)
 
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 2e18bf5c1aed..8be25b09c2b7 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -148,8 +148,7 @@ SECTIONS
_etext = .;
} :text = 0x9090
 
-   NOTES :text :note
-   .dummy : { *(.dummy) } :text
+   NOTES
 
EXCEPTION_TABLE(16)
 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 2cc3ff9ac8c7..6a0a657dfdb4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -56,10 +56,18 @@
 
 /*
  * Only some architectures want to have the .notes segment visible in
- * a separate PT_NOTE ELF Program Header.
+ * a separate PT_NOTE ELF Program Header. When this happens, it needs
+ * to be visible in both the kernel text's PT_LOAD and the PT_NOTE
+ * Program Headers. In this case, though, the PT_LOAD needs to be made
+ * the default again so that all the following sections don't also end
+ * up in the PT_NOTE Program Header.
  */
 #ifdef EMITS_PT_NOTE
 #define NOTES_HEADERS  :text :note
+#define NOTES_HEADERS_RESTORE  __restore_ph : { *(.__restore_ph) } :text
+#else
+#define NOTES_HEADERS
+#define NOTES_HEADERS_RESTORE
 #endif
 
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
@@ -792,7 +800,8 @@
__start_notes = .;  \
KEEP(*(.note.*))\
__stop_notes = .;   \
-   }
+   } NOTES_HEADERS \
+   NOTES_HEADERS_RESTORE
 
 #define INIT_SETUP(initsetup_align)\
. = ALIGN(initsetup_align); \
-- 
2.17.1



[PATCH 25/29] xtensa: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/xtensa/kernel/vmlinux.lds.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index bdbd7c4056c1..7341964722ae 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -14,6 +14,8 @@
  * Joe Taylor 
  */
 
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  16
+
 #include 
 #include 
 #include 
@@ -130,7 +132,6 @@ SECTIONS
 
   .fixup   : { *(.fixup) }
 
-  EXCEPTION_TABLE(16)
   /* Data section */
 
   _sdata = .;
-- 
2.17.1



[PATCH 29/29] x86: Use INT3 instead of NOP for linker fill bytes

2019-09-26 Thread Kees Cook
Instead of using 0x90 (NOP) to fill bytes between functions, which makes
it easier to sloppily target functions in function pointer overwrite
attacks, fill with 0xCC (INT3) to force a trap. Also drops the space
between "=" and the value to better match the binutils documentation
https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html#Output-Section-Fill

Example "objdump -d" before:

...
810001e0 :
810001e0:   48 8b 25 e1 b1 51 01mov 0x151b1e1(%rip),%rsp
# 8251b3c8 
810001e7:   e9 d5 fe ff ff  jmpq   81c1 

810001ec:   90  nop
810001ed:   90  nop
810001ee:   90  nop
810001ef:   90  nop

810001f0 <__startup_64>:
...

After:

...
810001e0 :
810001e0:   48 8b 25 41 79 53 01mov 0x1537941(%rip),%rsp
# 82537b28 
810001e7:   e9 d5 fe ff ff  jmpq   81c1 

810001ec:   cc  int3
810001ed:   cc  int3
810001ee:   cc  int3
810001ef:   cc  int3

810001f0 <__startup_64>:
...

Signed-off-by: Kees Cook 
---
 arch/x86/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index a5c8571e4967..a37817fafb22 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -144,7 +144,7 @@ SECTIONS
*(.text.__x86.indirect_thunk)
__indirect_thunk_end = .;
 #endif
-   } :text = 0x9090
+   } :text =0x
 
/* End of text section, which should occupy whole number of pages */
_etext = .;
-- 
2.17.1



[PATCH 17/29] alpha: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index edc45f45523b..72303827bcb4 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
 #define EMITS_PT_NOTE
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  16
 
 #include 
 #include 
@@ -35,7 +36,6 @@ SECTIONS
_etext = .; /* End of text section */
 
RO_DATA(4096)
-   EXCEPTION_TABLE(16)
 
/* Will be freed after init */
__init_begin = ALIGN(PAGE_SIZE);
-- 
2.17.1



[PATCH 14/29] vmlinux.lds.h: Allow EXCEPTION_TABLE to live in RO_DATA

2019-09-26 Thread Kees Cook
Many architectures have an EXCEPTION_TABLE that needs only to be
read-only. As such, it should live in RO_DATA. This creates a macro to
identify this case for the architectures that can move EXCEPTION_TABLE
into RO_DATA.

Signed-off-by: Kees Cook 
---
 include/asm-generic/vmlinux.lds.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index d57a28786bb8..35a6cba39d9f 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -69,6 +69,17 @@
 #define NOTES_HEADERS_RESTORE
 #endif
 
+/*
+ * Some architectures have non-executable read-only exception tables.
+ * They can be added to the RO_DATA segment by specifying their desired
+ * alignment.
+ */
+#ifdef RO_DATA_EXCEPTION_TABLE_ALIGN
+#define RO_DATA_EXCEPTION_TABLE
EXCEPTION_TABLE(RO_DATA_EXCEPTION_TABLE_ALIGN)
+#else
+#define RO_DATA_EXCEPTION_TABLE
+#endif
+
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
@@ -508,6 +519,7 @@
__stop___modver = .;\
}   \
\
+   RO_DATA_EXCEPTION_TABLE \
NOTES   \
\
. = ALIGN((align)); \
-- 
2.17.1



[PATCH 08/29] vmlinux.lds.h: Provide EMIT_PT_NOTE to indicate export of .notes

2019-09-26 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, this provides a mechanism
for architectures that want to emit a PT_NOTE Program Header to do so.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S   |  3 +++
 arch/ia64/kernel/vmlinux.lds.S|  2 ++
 arch/mips/kernel/vmlinux.lds.S| 12 ++--
 arch/powerpc/kernel/vmlinux.lds.S |  1 +
 arch/s390/kernel/vmlinux.lds.S|  2 ++
 arch/x86/kernel/vmlinux.lds.S |  2 ++
 include/asm-generic/vmlinux.lds.h |  8 
 7 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 781090cacc96..363a60ba7c31 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+
+#define EMITS_PT_NOTE
+
 #include 
 #include 
 #include 
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index c1067992fcd1..e034a6a4a444 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -5,6 +5,8 @@
 #include 
 #include 
 
+#define EMITS_PT_NOTE
+
 #include 
 
 OUTPUT_FORMAT("elf64-ia64-little")
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 33ee0d18fb0a..1c95612eb800 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -10,6 +10,11 @@
  */
 #define BSS_FIRST_SECTIONS *(.bss..swapper_pg_dir)
 
+/* Cavium Octeon should not have a separate PT_NOTE Program Header. */
+#ifndef CONFIG_CAVIUM_OCTEON_SOC
+#define EMITS_PT_NOTE
+#endif
+
 #include 
 
 #undef mips
@@ -76,12 +81,7 @@ SECTIONS
__stop___dbe_table = .;
}
 
-#ifdef CONFIG_CAVIUM_OCTEON_SOC
-#define NOTES_HEADER
-#else /* CONFIG_CAVIUM_OCTEON_SOC */
-#define NOTES_HEADER :note
-#endif /* CONFIG_CAVIUM_OCTEON_SOC */
-   NOTES :text NOTES_HEADER
+   NOTES NOTES_HEADERS
.dummy : { *(.dummy) } :text
 
_sdata = .; /* Start of data section */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index e184a63aa5b0..7e26e20c8324 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
 #endif
 
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
+#define EMITS_PT_NOTE
 
 #include 
 #include 
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 13294fef473e..646d939346df 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -15,6 +15,8 @@
 /* Handle ro_after_init data on our own. */
 #define RO_AFTER_INIT_DATA
 
+#define EMITS_PT_NOTE
+
 #include 
 #include 
 
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 788e78978030..2e18bf5c1aed 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -21,6 +21,8 @@
 #define LOAD_OFFSET __START_KERNEL_map
 #endif
 
+#define EMITS_PT_NOTE
+
 #include 
 #include 
 #include 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index cd28f63bfbc7..2cc3ff9ac8c7 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -54,6 +54,14 @@
 #define LOAD_OFFSET 0
 #endif
 
+/*
+ * Only some architectures want to have the .notes segment visible in
+ * a separate PT_NOTE ELF Program Header.
+ */
+#ifdef EMITS_PT_NOTE
+#define NOTES_HEADERS  :text :note
+#endif
+
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
-- 
2.17.1



[PATCH 19/29] c6x: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/c6x/kernel/vmlinux.lds.S | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S
index a3547f9d415b..9a09aab63ab3 100644
--- a/arch/c6x/kernel/vmlinux.lds.S
+++ b/arch/c6x/kernel/vmlinux.lds.S
@@ -5,6 +5,9 @@
  *  Copyright (C) 2010, 2011 Texas Instruments Incorporated
  *  Mark Salter 
  */
+
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  16
+
 #include 
 #include 
 #include 
@@ -80,8 +83,6 @@ SECTIONS
*(.gnu.warning)
}
 
-   EXCEPTION_TABLE(16)
-
RO_DATA(PAGE_SIZE)
.const :
{
-- 
2.17.1



[PATCH 24/29] powerpc: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 4e7cec088c8b..2ed44e5824d5 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -7,6 +7,7 @@
 
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
 #define EMITS_PT_NOTE
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  0
 
 #include 
 #include 
@@ -162,7 +163,6 @@ SECTIONS
__stop__btb_flush_fixup = .;
}
 #endif
-   EXCEPTION_TABLE(0)
 
 /*
  * Init sections discarded at runtime
-- 
2.17.1



[PATCH 01/29] powerpc: Rename "notes" PT_NOTE to "note"

2019-09-26 Thread Kees Cook
The Program Header identifiers are internal to the linker scripts. In
preparation for moving the NOTES segment declaration into RO_DATA,
standardize the identifier for the PT_NOTE entry to "note" as used by
all other architectures that emit PT_NOTE.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 060a1acd7c6d..81e672654789 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -19,7 +19,7 @@ ENTRY(_stext)
 
 PHDRS {
kernel PT_LOAD FLAGS(7); /* RWX */
-   notes PT_NOTE FLAGS(0);
+   note PT_NOTE FLAGS(0);
dummy PT_NOTE FLAGS(0);
 
/* binutils < 2.18 has a bug that makes it misbehave when taking an
@@ -177,7 +177,7 @@ SECTIONS
 #endif
EXCEPTION_TABLE(0)
 
-   NOTES :kernel :notes
+   NOTES :kernel :note
 
/* The dummy segment contents for the bug workaround mentioned above
   near PHDRS.  */
-- 
2.17.1



[PATCH 26/29] x86/mm: Remove redundant on addresses

2019-09-26 Thread Kees Cook
The  on addresses are redundant and are better removed to match all
the other similar functions.

Signed-off-by: Kees Cook 
---
 arch/x86/mm/init_64.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 26299e9ce6da..e67ddca8b7a8 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1300,9 +1300,9 @@ void mark_rodata_ro(void)
 {
unsigned long start = PFN_ALIGN(_text);
unsigned long rodata_start = PFN_ALIGN(__start_rodata);
-   unsigned long end = (unsigned long) &__end_rodata_hpage_align;
-   unsigned long text_end = PFN_ALIGN(&_etext);
-   unsigned long rodata_end = PFN_ALIGN(&__end_rodata);
+   unsigned long end = (unsigned long)__end_rodata_hpage_align;
+   unsigned long text_end = PFN_ALIGN(_etext);
+   unsigned long rodata_end = PFN_ALIGN(__end_rodata);
unsigned long all_end;
 
printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
-- 
2.17.1



[PATCH 04/29] alpha: Rename PT_LOAD identifier "kernel" to "text"

2019-09-26 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, this renames the linker
script internal identifier for the PT_LOAD Program Header from "kernel"
to "text" to match other architectures.

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index c4b5ceceab52..781090cacc96 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -8,7 +8,7 @@
 OUTPUT_FORMAT("elf64-alpha")
 OUTPUT_ARCH(alpha)
 ENTRY(__start)
-PHDRS { kernel PT_LOAD; note PT_NOTE; }
+PHDRS { text PT_LOAD; note PT_NOTE; }
 jiffies = jiffies_64;
 SECTIONS
 {
@@ -27,14 +27,14 @@ SECTIONS
LOCK_TEXT
*(.fixup)
*(.gnu.warning)
-   } :kernel
+   } :text
swapper_pg_dir = SWAPPER_PGD;
_etext = .; /* End of text section */
 
-   NOTES :kernel :note
+   NOTES :text :note
.dummy : {
*(.dummy)
-   } :kernel
+   } :text
 
RODATA
EXCEPTION_TABLE(16)
-- 
2.17.1



[PATCH 28/29] x86/mm: Report actual image regions in /proc/iomem

2019-09-26 Thread Kees Cook
The resource reservations in made for the kernel image did not reflect
the gaps between text, rodata, and data. This adds the rodata resource
and updates the start/end calculations to match the respective calls to
free_kernel_image_pages().

Before (booted with "nokaslr" for easier comparison):

0010-bffd9fff : System RAM
  0100-01e011d0 : Kernel code
  01e011d1-025619bf : Kernel data
  02a95000-035f : Kernel bss

After:

0010-bffd9fff : System RAM
  0100-01e011d0 : Kernel code
  0200-023d4fff : Kernel rodata
  0240-025619ff : Kernel data
  02a95000-035f : Kernel bss

Signed-off-by: Kees Cook 
---
 arch/x86/kernel/setup.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index bbe35bf879f5..0bc71ee3a9c3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -143,6 +143,13 @@ struct boot_params boot_params;
 /*
  * Machine setup..
  */
+static struct resource rodata_resource = {
+   .name   = "Kernel rodata",
+   .start  = 0,
+   .end= 0,
+   .flags  = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
+};
+
 static struct resource data_resource = {
.name   = "Kernel data",
.start  = 0,
@@ -951,7 +958,9 @@ void __init setup_arch(char **cmdline_p)
 
code_resource.start = __pa_symbol(_text);
code_resource.end = __pa_symbol(_etext)-1;
-   data_resource.start = __pa_symbol(_etext);
+   rodata_resource.start = __pa_symbol(__start_rodata);
+   rodata_resource.end = __pa_symbol(__end_rodata)-1;
+   data_resource.start = __pa_symbol(_sdata);
data_resource.end = __pa_symbol(_edata)-1;
bss_resource.start = __pa_symbol(__bss_start);
bss_resource.end = __pa_symbol(__bss_stop)-1;
@@ -1040,6 +1049,7 @@ void __init setup_arch(char **cmdline_p)
 
/* after parse_early_param, so could debug it */
insert_resource(_resource, _resource);
+   insert_resource(_resource, _resource);
insert_resource(_resource, _resource);
insert_resource(_resource, _resource);
 
-- 
2.17.1



[PATCH 27/29] x86/mm: Report which part of kernel image is freed

2019-09-26 Thread Kees Cook
The memory freeing report wasn't very useful for figuring out which
parts of the kernel image were being freed. This adds the details for
clearer reporting.

Before:

[2.150450] Freeing unused kernel image memory: 1348K
[2.154574] Write protecting the kernel read-only data: 20480k
[2.157641] Freeing unused kernel image memory: 2040K
[2.158827] Freeing unused kernel image memory: 172K

After:

[2.329678] Freeing unused kernel image (initmem) memory: 1348K
[2.331953] Write protecting the kernel read-only data: 20480k
[2.335361] Freeing unused kernel image (text/rodata gap) memory: 2040K
[2.336927] Freeing unused kernel image (rodata/data gap) memory: 172K

Signed-off-by: Kees Cook 
---
 arch/x86/include/asm/processor.h | 2 +-
 arch/x86/mm/init.c   | 8 
 arch/x86/mm/init_64.c| 6 --
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 6e0a3b43d027..790f250d39a8 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -958,7 +958,7 @@ static inline uint32_t hypervisor_cpuid_base(const char 
*sig, uint32_t leaves)
 
 extern unsigned long arch_align_stack(unsigned long sp);
 void free_init_pages(const char *what, unsigned long begin, unsigned long end);
-extern void free_kernel_image_pages(void *begin, void *end);
+extern void free_kernel_image_pages(const char *what, void *begin, void *end);
 
 void default_idle(void);
 #ifdef CONFIG_XEN
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index fd10d91a6115..e7bb483557c9 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -829,14 +829,13 @@ void free_init_pages(const char *what, unsigned long 
begin, unsigned long end)
  * used for the kernel image only.  free_init_pages() will do the
  * right thing for either kind of address.
  */
-void free_kernel_image_pages(void *begin, void *end)
+void free_kernel_image_pages(const char *what, void *begin, void *end)
 {
unsigned long begin_ul = (unsigned long)begin;
unsigned long end_ul = (unsigned long)end;
unsigned long len_pages = (end_ul - begin_ul) >> PAGE_SHIFT;
 
-
-   free_init_pages("unused kernel image", begin_ul, end_ul);
+   free_init_pages(what, begin_ul, end_ul);
 
/*
 * PTI maps some of the kernel into userspace.  For performance,
@@ -865,7 +864,8 @@ void __ref free_initmem(void)
 
mem_encrypt_free_decrypted_mem();
 
-   free_kernel_image_pages(&__init_begin, &__init_end);
+   free_kernel_image_pages("unused kernel image (initmem)",
+   &__init_begin, &__init_end);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index e67ddca8b7a8..dcb9bc961b39 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1334,8 +1334,10 @@ void mark_rodata_ro(void)
set_memory_ro(start, (end-start) >> PAGE_SHIFT);
 #endif
 
-   free_kernel_image_pages((void *)text_end, (void *)rodata_start);
-   free_kernel_image_pages((void *)rodata_end, (void *)_sdata);
+   free_kernel_image_pages("unused kernel image (text/rodata gap)",
+   (void *)text_end, (void *)rodata_start);
+   free_kernel_image_pages("unused kernel image (rodata/data gap)",
+   (void *)rodata_end, (void *)_sdata);
 
debug_checkwx();
 }
-- 
2.17.1



[PATCH 13/29] vmlinux.lds.h: Replace RW_DATA_SECTION with RW_DATA

2019-09-26 Thread Kees Cook
This renames RW_DATA_SECTION to RW_DATA. (Calling this a "section" is
a lie, since it's multiple sections and section flags cannot be applied
to the macro.)

Signed-off-by: Kees Cook 
---
 arch/alpha/kernel/vmlinux.lds.S  | 2 +-
 arch/arc/kernel/vmlinux.lds.S| 2 +-
 arch/arm/kernel/vmlinux-xip.lds.S| 2 +-
 arch/arm/kernel/vmlinux.lds.S| 2 +-
 arch/arm64/kernel/vmlinux.lds.S  | 2 +-
 arch/csky/kernel/vmlinux.lds.S   | 2 +-
 arch/h8300/kernel/vmlinux.lds.S  | 2 +-
 arch/hexagon/kernel/vmlinux.lds.S| 2 +-
 arch/m68k/kernel/vmlinux-nommu.lds   | 2 +-
 arch/m68k/kernel/vmlinux-std.lds | 2 +-
 arch/m68k/kernel/vmlinux-sun3.lds| 2 +-
 arch/microblaze/kernel/vmlinux.lds.S | 2 +-
 arch/nds32/kernel/vmlinux.lds.S  | 2 +-
 arch/nios2/kernel/vmlinux.lds.S  | 2 +-
 arch/openrisc/kernel/vmlinux.lds.S   | 2 +-
 arch/parisc/kernel/vmlinux.lds.S | 2 +-
 arch/riscv/kernel/vmlinux.lds.S  | 2 +-
 arch/s390/kernel/vmlinux.lds.S   | 2 +-
 arch/sh/kernel/vmlinux.lds.S | 2 +-
 arch/sparc/kernel/vmlinux.lds.S  | 2 +-
 arch/unicore32/kernel/vmlinux.lds.S  | 2 +-
 arch/xtensa/kernel/vmlinux.lds.S | 2 +-
 include/asm-generic/vmlinux.lds.h| 4 ++--
 23 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index af411817dd7d..edc45f45523b 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
 
_sdata = .; /* Start of rw data section */
_data = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
.got : {
*(.got)
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 7d1d27066deb..54139a6f469b 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -101,7 +101,7 @@ SECTIONS
 * 1. this is .data essentially
 * 2. THREAD_SIZE for init.task, must be kernel-stk sz aligned
 */
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
_edata = .;
 
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S 
b/arch/arm/kernel/vmlinux-xip.lds.S
index d2a9651c24ad..21b8b271c80d 100644
--- a/arch/arm/kernel/vmlinux-xip.lds.S
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
@@ -112,7 +112,7 @@ SECTIONS
 
. = ALIGN(THREAD_SIZE);
_sdata = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
.data.ro_after_init : AT(ADDR(.data.ro_after_init) - LOAD_OFFSET) {
*(.data..ro_after_init)
}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 068db6860867..319ccb10846a 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -141,7 +141,7 @@ SECTIONS
__init_end = .;
 
_sdata = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
BSS_SECTION(0, 0, 0)
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 5cf9424485d5..81d94e371c95 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -205,7 +205,7 @@ SECTIONS
 
_data = .;
_sdata = .;
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
 
/*
 * Data written with the MMU off but read with the MMU on requires
diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S
index 8598bd7a7bcd..2ff37beaf2bf 100644
--- a/arch/csky/kernel/vmlinux.lds.S
+++ b/arch/csky/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
 
_sdata = .;
RO_DATA(PAGE_SIZE)
-   RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
_edata = .;
 
EXCEPTION_TABLE(L1_CACHE_BYTES)
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index d3247d33b115..2ac7bdcd2fe0 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -47,7 +47,7 @@ SECTIONS
 #endif
_sdata = . ;
__data_start = . ;
-   RW_DATA_SECTION(0, PAGE_SIZE, THREAD_SIZE)
+   RW_DATA(0, PAGE_SIZE, THREAD_SIZE)
 #if defined(CONFIG_ROMKERNEL)
 #undef ADDR
 #endif
diff --git a/arch/hexagon/kernel/vmlinux.lds.S 
b/arch/hexagon/kernel/vmlinux.lds.S
index 0145251fa317..0ca2471ddb9f 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -49,7 +49,7 @@ SECTIONS
INIT_DATA_SECTION(PAGE_SIZE)
 
_sdata = .;
-   RW_DATA_SECTION(32,PAGE_SIZE,_THREAD_SIZE)
+   RW_DATA(32,PAGE_SIZE,_THREAD_SIZE)
RO_DATA(PAGE_SIZE)
_edata =

[PATCH 20/29] h8300: Move EXCEPTION_TABLE to RO_DATA segment

2019-09-26 Thread Kees Cook
The EXCEPTION_TABLE is read-only, so collapse it into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/h8300/kernel/vmlinux.lds.S | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 2ac7bdcd2fe0..aba90398b774 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+
+#define RO_DATA_EXCEPTION_TABLE_ALIGN  16
+
 #include 
 #include 
 #include 
@@ -37,7 +40,6 @@ SECTIONS
 #endif
_etext = . ;
}
-   EXCEPTION_TABLE(16)
RO_DATA(4)
ROMEND = .;
 #if defined(CONFIG_ROMKERNEL)
-- 
2.17.1



[PATCH 05/29] ia64: Rename PT_LOAD identifier "code" to "text"

2019-09-26 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, this renames the linker
script internal identifier for the PT_LOAD Program Header from "code"
to "text" to match other architectures.

Signed-off-by: Kees Cook 
---
 arch/ia64/kernel/vmlinux.lds.S | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 0da58cf8e213..c1067992fcd1 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -13,7 +13,7 @@ ENTRY(phys_start)
 jiffies = jiffies_64;
 
 PHDRS {
-   code   PT_LOAD;
+   text   PT_LOAD;
percpu PT_LOAD;
data   PT_LOAD;
note   PT_NOTE;
@@ -36,7 +36,7 @@ SECTIONS {
phys_start = _start - LOAD_OFFSET;
 
code : {
-   } :code
+   } :text
. = KERNEL_START;
 
_text = .;
@@ -68,9 +68,9 @@ SECTIONS {
/*
 * Read-only data
 */
-   NOTES :code :note   /* put .notes in text and mark in PT_NOTE  */
+   NOTES :text :note   /* put .notes in text and mark in PT_NOTE  */
code_continues : {
-   } : code   /* switch back to regular program...  */
+   } :text/* switch back to regular program...  */
 
EXCEPTION_TABLE(16)
 
@@ -102,9 +102,9 @@ SECTIONS {
__start_unwind = .;
*(.IA_64.unwind*)
__end_unwind = .;
-   } :code :unwind
+   } :text :unwind
code_continues2 : {
-   } : code
+   } :text
 
RODATA
 
@@ -224,7 +224,7 @@ SECTIONS {
_end = .;
 
code : {
-   } :code
+   } :text
 
STABS_DEBUG
DWARF_DEBUG
-- 
2.17.1



[PATCH 06/29] s390: Move RO_DATA into "text" PT_LOAD Program Header

2019-09-26 Thread Kees Cook
In preparation for moving NOTES into RO_DATA, this moves RO_DATA back
into the "text" PT_LOAD Program Header, as done with other
architectures. The "data" PT_LOAD now starts with the writable data
section.

Signed-off-by: Kees Cook 
---
 arch/s390/kernel/vmlinux.lds.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 7e0eb4020917..13294fef473e 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -52,7 +52,7 @@ SECTIONS
 
NOTES :text :note
 
-   .dummy : { *(.dummy) } :data
+   .dummy : { *(.dummy) } :text
 
RO_DATA_SECTION(PAGE_SIZE)
 
@@ -64,7 +64,7 @@ SECTIONS
.data..ro_after_init : {
 *(.data..ro_after_init)
JUMP_TABLE_DATA
-   }
+   } :data
EXCEPTION_TABLE(16)
. = ALIGN(PAGE_SIZE);
__end_ro_after_init = .;
-- 
2.17.1



[PATCH 02/29] powerpc: Remove PT_NOTE workaround

2019-09-26 Thread Kees Cook
The kernel requires gcc 4.6 now, so this PT_NOTE workaround can be
removed in preparation for moving NOTES into RO_DATA.

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/vmlinux.lds.S | 24 ++--
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 81e672654789..a3c8492b2b19 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -20,20 +20,6 @@ ENTRY(_stext)
 PHDRS {
kernel PT_LOAD FLAGS(7); /* RWX */
note PT_NOTE FLAGS(0);
-   dummy PT_NOTE FLAGS(0);
-
-   /* binutils < 2.18 has a bug that makes it misbehave when taking an
-  ELF file with all segments at load address 0 as input.  This
-  happens when running "strip" on vmlinux, because of the AT() magic
-  in this linker script.  People using GCC >= 4.2 won't run into
-  this problem, because the "build-id" support will put some data
-  into the "notes" segment (at a non-zero load address).
-
-  To work around this, we force some data into both the "dummy"
-  segment and the kernel segment, so the dummy segment will get a
-  non-zero load address.  It's not enough to always create the
-  "notes" segment, since if nothing gets assigned to it, its load
-  address will be zero.  */
 }
 
 #ifdef CONFIG_PPC64
@@ -178,14 +164,8 @@ SECTIONS
EXCEPTION_TABLE(0)
 
NOTES :kernel :note
-
-   /* The dummy segment contents for the bug workaround mentioned above
-  near PHDRS.  */
-   .dummy : AT(ADDR(.dummy) - LOAD_OFFSET) {
-   LONG(0)
-   LONG(0)
-   LONG(0)
-   } :kernel :dummy
+   /* Restore program header away from PT_NOTE. */
+   .dummy : { *(.dummy) } :kernel
 
 /*
  * Init sections discarded at runtime
-- 
2.17.1