Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1312429 > unrolled thread
| Started by | Kees Cook <keescook@chromium.org> |
|---|---|
| First post | 2016-01-19 19:20 +0100 |
| Last post | 2016-01-23 10:50 +0100 |
| Articles | 6 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v4 0/8] introduce post-init read-only memory Kees Cook <keescook@chromium.org> - 2016-01-19 19:20 +0100
[PATCH v4 7/8] lkdtm: verify that __ro_after_init works correctly Kees Cook <keescook@chromium.org> - 2016-01-19 19:20 +0100
Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory David Brown <david.brown@linaro.org> - 2016-01-22 18:30 +0100
Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory Laura Abbott <laura@labbott.name> - 2016-01-22 20:20 +0100
Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory Kees Cook <keescook@chromium.org> - 2016-01-22 21:00 +0100
Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory Geert Uytterhoeven <geert@linux-m68k.org> - 2016-01-23 10:50 +0100
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Date | 2016-01-19 19:20 +0100 |
| Subject | [PATCH v4 0/8] introduce post-init read-only memory |
| Message-ID | <qSIT8-33H-5@gated-at.bofh.it> |
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 uses it on the x86 vDSO to kill an extant kernel exploitation method. Also adds a new kernel parameter to help debug future use and adds an lkdtm test to check the results. -Kees v4: - rebased v3: - conslidated mark_rodata_ro() - make CONFIG_DEBUG_RODATA always enabled on x86, mingo - enhanced strtobool and potential callers to use "on"/"off" - use strtobool for rodata= param, gregkh v2: - renamed __read_only to __ro_after_init
[toc] | [next] | [standalone]
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Date | 2016-01-19 19:20 +0100 |
| Subject | [PATCH v4 7/8] lkdtm: verify that __ro_after_init works correctly |
| Message-ID | <qSJ2O-36W-25@gated-at.bofh.it> |
| In reply to | #1312429 |
The new __ro_after_init section should be writable before init, but
not after. Validate that it gets updated at init and can't be written
to afterwards.
Signed-off-by: Kees Cook <keescook@chromium.org>
---
drivers/misc/lkdtm.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index 11fdadc68e53..2a6eaf1122b4 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -103,6 +103,7 @@ enum ctype {
CT_EXEC_USERSPACE,
CT_ACCESS_USERSPACE,
CT_WRITE_RO,
+ CT_WRITE_RO_AFTER_INIT,
CT_WRITE_KERN,
};
@@ -140,6 +141,7 @@ static char* cp_type[] = {
"EXEC_USERSPACE",
"ACCESS_USERSPACE",
"WRITE_RO",
+ "WRITE_RO_AFTER_INIT",
"WRITE_KERN",
};
@@ -162,6 +164,7 @@ static DEFINE_SPINLOCK(lock_me_up);
static u8 data_area[EXEC_SIZE];
static const unsigned long rodata = 0xAA55AA55;
+static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
module_param(recur_count, int, 0644);
MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test");
@@ -503,11 +506,28 @@ static void lkdtm_do_action(enum ctype which)
break;
}
case CT_WRITE_RO: {
- unsigned long *ptr;
+ /* Explicitly cast away "const" for the test. */
+ unsigned long *ptr = (unsigned long *)&rodata;
- ptr = (unsigned long *)&rodata;
+ pr_info("attempting bad rodata write at %p\n", ptr);
+ *ptr ^= 0xabcd1234;
- pr_info("attempting bad write at %p\n", ptr);
+ break;
+ }
+ case CT_WRITE_RO_AFTER_INIT: {
+ unsigned long *ptr = &ro_after_init;
+
+ /*
+ * Verify we were written to during init. Since an Oops
+ * is considered a "success", a failure is to just skip the
+ * real test.
+ */
+ if ((*ptr & 0xAA) != 0xAA) {
+ pr_info("%p was NOT written during init!?\n", ptr);
+ break;
+ }
+
+ pr_info("attempting bad ro_after_init write at %p\n", ptr);
*ptr ^= 0xabcd1234;
break;
@@ -817,6 +837,9 @@ static int __init lkdtm_module_init(void)
int n_debugfs_entries = 1; /* Assume only the direct entry */
int i;
+ /* Make sure we can write to __ro_after_init values during __init */
+ ro_after_init |= 0xAA;
+
/* Register debugfs interface */
lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
if (!lkdtm_debugfs_root) {
--
2.6.3
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@linaro.org> |
|---|---|
| Date | 2016-01-22 18:30 +0100 |
| Subject | Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory |
| Message-ID | <qTNH3-7bM-3@gated-at.bofh.it> |
| In reply to | #1312429 |
On Tue, Jan 19, 2016 at 10:08:34AM -0800, Kees Cook wrote: >This introduces __ro_after_init as a way to mark such memory, and uses >it on the x86 vDSO to kill an extant kernel exploitation method. Also >adds a new kernel parameter to help debug future use and adds an lkdtm >test to check the results. I've tested these patches on 32-bit ARM using the provoke-crashes test. However, they do require CONFIG_ARM_KERNMEM_PERMS to be enabled as well, which does incur additional memory usage. Do we want to consider making CONFIG_ARM_KERNMEM_PERMS default y for security reasons, and just document that memory-constrained systems may want to turn it off? I'll test the arm64 next. David
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <laura@labbott.name> |
|---|---|
| Date | 2016-01-22 20:20 +0100 |
| Subject | Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory |
| Message-ID | <qTPpw-8pj-19@gated-at.bofh.it> |
| In reply to | #1315153 |
On 1/22/16 9:19 AM, David Brown wrote: > On Tue, Jan 19, 2016 at 10:08:34AM -0800, Kees Cook wrote: > >> This introduces __ro_after_init as a way to mark such memory, and uses >> it on the x86 vDSO to kill an extant kernel exploitation method. Also >> adds a new kernel parameter to help debug future use and adds an lkdtm >> test to check the results. > > I've tested these patches on 32-bit ARM using the provoke-crashes > test. However, they do require CONFIG_ARM_KERNMEM_PERMS to be enabled > as well, which does incur additional memory usage. > > Do we want to consider making CONFIG_ARM_KERNMEM_PERMS default y for > security reasons, and just document that memory-constrained systems > may want to turn it off? > > I'll test the arm64 next. > > David Kees had previously pushed a patch to do so but it exposed a couple of underlying issues, mostly with low power paths (c.f. http://article.gmane.org/gmane.linux.ports.arm.kernel/471199, http://article.gmane.org/gmane.linux.kernel.mm/143489) Those will need to be all fixed up before this could be made default. Thanks, Laura
[toc] | [prev] | [next] | [standalone]
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Date | 2016-01-22 21:00 +0100 |
| Subject | Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory |
| Message-ID | <qTQ2d-cO-1@gated-at.bofh.it> |
| In reply to | #1315234 |
On Fri, Jan 22, 2016 at 11:16 AM, Laura Abbott <laura@labbott.name> wrote: > On 1/22/16 9:19 AM, David Brown wrote: >> >> On Tue, Jan 19, 2016 at 10:08:34AM -0800, Kees Cook wrote: >> >>> This introduces __ro_after_init as a way to mark such memory, and uses >>> it on the x86 vDSO to kill an extant kernel exploitation method. Also >>> adds a new kernel parameter to help debug future use and adds an lkdtm >>> test to check the results. >> >> >> I've tested these patches on 32-bit ARM using the provoke-crashes >> test. However, they do require CONFIG_ARM_KERNMEM_PERMS to be enabled >> as well, which does incur additional memory usage. Thanks for testing! >> Do we want to consider making CONFIG_ARM_KERNMEM_PERMS default y for >> security reasons, and just document that memory-constrained systems >> may want to turn it off? >> >> I'll test the arm64 next. >> >> David > > > Kees had previously pushed a patch to do so but it exposed a couple of > underlying issues, mostly with low power paths > (c.f. http://article.gmane.org/gmane.linux.ports.arm.kernel/471199, > http://article.gmane.org/gmane.linux.kernel.mm/143489) > Those will need to be all fixed up before this could be made default. Yeah, I've got a patch waiting to reorganize CONFIG_ARM_KERNMEM_PERMS to look more like arm64 (and x86) and get the feature correctly under CONFIG_DEBUG_RODATA. I made it default=y on v7+. rmk asked me to wait until -rc1 before resubmitting it. http://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?h=kspp/arm-rodata&id=08bebfd2e7fb8a9f364ced74c356642d64e1f43e and a small improvement too: http://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?h=kspp/arm-rodata&id=8e16f005ce0d4069aee5502379cff845b4c6f950 -Kees -- Kees Cook Chrome OS & Brillo Security
[toc] | [prev] | [next] | [standalone]
| From | Geert Uytterhoeven <geert@linux-m68k.org> |
|---|---|
| Date | 2016-01-23 10:50 +0100 |
| Subject | Re: [kernel-hardening] [PATCH v4 0/8] introduce post-init read-only memory |
| Message-ID | <qU2Zr-K2-7@gated-at.bofh.it> |
| In reply to | #1315242 |
Hi Kees,
On Fri, Jan 22, 2016 at 8:57 PM, Kees Cook <keescook@chromium.org> wrote:
> On Fri, Jan 22, 2016 at 11:16 AM, Laura Abbott <laura@labbott.name> wrote:
>> Kees had previously pushed a patch to do so but it exposed a couple of
>> underlying issues, mostly with low power paths
>> (c.f. http://article.gmane.org/gmane.linux.ports.arm.kernel/471199,
>> http://article.gmane.org/gmane.linux.kernel.mm/143489)
>> Those will need to be all fixed up before this could be made default.
I'm working on fixing that...
BTW, making the sections read-only is done quite late in the kernel startup
process, which means it doesn't trigger for the writes to the text segment in
secondary CPU bringup, but only for suspend/resume.
> Yeah, I've got a patch waiting to reorganize CONFIG_ARM_KERNMEM_PERMS
> to look more like arm64 (and x86) and get the feature correctly under
> CONFIG_DEBUG_RODATA. I made it default=y on v7+. rmk asked me to wait
> until -rc1 before resubmitting it.
>
> http://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?h=kspp/arm-rodata&id=08bebfd2e7fb8a9f364ced74c356642d64e1f43e
One other concern is indeed memory usage ("ALIGN(1<<SECTION_SHIFT)"?).
Enabling CONFIG_ARM_KERNMEM_PERMS and CONFIG_DEBUG_RODATA in my test kernel
configs make the kernel too big to boot (overwritten DTB?) for 3 out of 4 arm
shmobile targets...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web