mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	arch: Introduce post-init read-only memory
One of the easiest ways to protect the kernel from attack is to reduce the internal attack surface exposed when a "write" flaw is available. By making as much of the kernel read-only as possible, we reduce the attack surface. Many things are written to only during __init, and never changed again. These cannot be made "const" since the compiler will do the wrong thing (we do actually need to write to them). Instead, move these items into a memory region that will be made read-only during mark_rodata_ro() which happens after all kernel __init code has finished. This introduces __ro_after_init as a way to mark such memory, and adds some documentation about the existing __read_mostly marking. This improves the security of the Linux kernel by marking formerly read-write memory regions as read-only on a fully booted up system. Based on work by PaX Team and Brad Spengler. Signed-off-by: Kees Cook <keescook@chromium.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Borislav Petkov <bp@alien8.de> Cc: Brad Spengler <spender@grsecurity.net> Cc: Brian Gerst <brgerst@gmail.com> Cc: David Brown <david.brown@linaro.org> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Emese Revfy <re.emese@gmail.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mathias Krause <minipli@googlemail.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: PaX Team <pageexec@freemail.hu> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: kernel-hardening@lists.openwall.com Cc: linux-arch <linux-arch@vger.kernel.org> Link: http://lkml.kernel.org/r/1455748879-21872-5-git-send-email-keescook@chromium.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									9ccaf77cf0
								
							
						
					
					
						commit
						c74ba8b348
					
				
					 3 changed files with 18 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -22,6 +22,9 @@
 | 
			
		|||
 | 
			
		||||
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 | 
			
		||||
 | 
			
		||||
/* Read-only memory is marked before mark_rodata_ro() is called. */
 | 
			
		||||
#define __ro_after_init	__read_mostly
 | 
			
		||||
 | 
			
		||||
void parisc_cache_init(void);	/* initializes cache-flushing */
 | 
			
		||||
void disable_sr_hashing_asm(int); /* low level support for above */
 | 
			
		||||
void disable_sr_hashing(void);   /* turns off space register hashing */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -256,6 +256,7 @@
 | 
			
		|||
	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
 | 
			
		||||
		VMLINUX_SYMBOL(__start_rodata) = .;			\
 | 
			
		||||
		*(.rodata) *(.rodata.*)					\
 | 
			
		||||
		*(.data..ro_after_init)	/* Read only after init */	\
 | 
			
		||||
		*(__vermagic)		/* Kernel version magic */	\
 | 
			
		||||
		. = ALIGN(8);						\
 | 
			
		||||
		VMLINUX_SYMBOL(__start___tracepoints_ptrs) = .;		\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,10 +12,24 @@
 | 
			
		|||
#define SMP_CACHE_BYTES L1_CACHE_BYTES
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * __read_mostly is used to keep rarely changing variables out of frequently
 | 
			
		||||
 * updated cachelines. If an architecture doesn't support it, ignore the
 | 
			
		||||
 * hint.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __read_mostly
 | 
			
		||||
#define __read_mostly
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * __ro_after_init is used to mark things that are read-only after init (i.e.
 | 
			
		||||
 * after mark_rodata_ro() has been called). These are effectively read-only,
 | 
			
		||||
 * but may get written to during init, so can't live in .rodata (via "const").
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __ro_after_init
 | 
			
		||||
#define __ro_after_init __attribute__((__section__(".data..ro_after_init")))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef ____cacheline_aligned
 | 
			
		||||
#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue