mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Kees Cook](/assets/img/avatar_default.png)
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>
81 lines
2.1 KiB
C
81 lines
2.1 KiB
C
#ifndef __LINUX_CACHE_H
|
|
#define __LINUX_CACHE_H
|
|
|
|
#include <uapi/linux/kernel.h>
|
|
#include <asm/cache.h>
|
|
|
|
#ifndef L1_CACHE_ALIGN
|
|
#define L1_CACHE_ALIGN(x) __ALIGN_KERNEL(x, L1_CACHE_BYTES)
|
|
#endif
|
|
|
|
#ifndef SMP_CACHE_BYTES
|
|
#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
|
|
|
|
#ifndef ____cacheline_aligned_in_smp
|
|
#ifdef CONFIG_SMP
|
|
#define ____cacheline_aligned_in_smp ____cacheline_aligned
|
|
#else
|
|
#define ____cacheline_aligned_in_smp
|
|
#endif /* CONFIG_SMP */
|
|
#endif
|
|
|
|
#ifndef __cacheline_aligned
|
|
#define __cacheline_aligned \
|
|
__attribute__((__aligned__(SMP_CACHE_BYTES), \
|
|
__section__(".data..cacheline_aligned")))
|
|
#endif /* __cacheline_aligned */
|
|
|
|
#ifndef __cacheline_aligned_in_smp
|
|
#ifdef CONFIG_SMP
|
|
#define __cacheline_aligned_in_smp __cacheline_aligned
|
|
#else
|
|
#define __cacheline_aligned_in_smp
|
|
#endif /* CONFIG_SMP */
|
|
#endif
|
|
|
|
/*
|
|
* The maximum alignment needed for some critical structures
|
|
* These could be inter-node cacheline sizes/L3 cacheline
|
|
* size etc. Define this in asm/cache.h for your arch
|
|
*/
|
|
#ifndef INTERNODE_CACHE_SHIFT
|
|
#define INTERNODE_CACHE_SHIFT L1_CACHE_SHIFT
|
|
#endif
|
|
|
|
#if !defined(____cacheline_internodealigned_in_smp)
|
|
#if defined(CONFIG_SMP)
|
|
#define ____cacheline_internodealigned_in_smp \
|
|
__attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))
|
|
#else
|
|
#define ____cacheline_internodealigned_in_smp
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef CONFIG_ARCH_HAS_CACHE_LINE_SIZE
|
|
#define cache_line_size() L1_CACHE_BYTES
|
|
#endif
|
|
|
|
#endif /* __LINUX_CACHE_H */
|