]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge tag 'lkdtm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Mar 2016 00:51:19 +0000 (16:51 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Mar 2016 00:51:19 +0000 (16:51 -0800)
Kees writes:

Become maintainer, add hardening tests for use-after-free and atomic wrapping.

1  2 
MAINTAINERS
drivers/misc/lkdtm.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile

diff --combined MAINTAINERS
index 403248c768d0246a7d236e528bb11d275217bf46,f9eb9914828bb5642a7ab412ef89ff5aa84703d2..229c17da456859e5759b6bc03e548c2910be180e
@@@ -5747,7 -5747,6 +5747,7 @@@ S:      Supporte
  F:    include/uapi/linux/mei.h
  F:    include/linux/mei_cl_bus.h
  F:    drivers/misc/mei/*
 +F:    drivers/watchdog/mei_wdt.c
  F:    Documentation/misc-devices/mei/*
  
  INTEL MIC DRIVERS (mic)
@@@ -6581,6 -6580,11 +6581,11 @@@ F:    samples/livepatch
  L:    live-patching@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching.git
  
+ LINUX KERNEL DUMP TEST MODULE (LKDTM)
+ M:    Kees Cook <keescook@chromium.org>
+ S:    Maintained
+ F:    drivers/misc/lkdtm.c
  LLC (802.2)
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  S:    Maintained
diff --combined drivers/misc/lkdtm.c
index 5c1351b1902955161add739071cb34f0f141d5bb,9345999f56730e60cc698ca2011b92b240ff442b..fb354e8a12652fd53d04c294dc37be02e581ab03
@@@ -92,6 -92,9 +92,9 @@@ enum ctype 
        CT_UNALIGNED_LOAD_STORE_WRITE,
        CT_OVERWRITE_ALLOCATION,
        CT_WRITE_AFTER_FREE,
+       CT_READ_AFTER_FREE,
+       CT_WRITE_BUDDY_AFTER_FREE,
+       CT_READ_BUDDY_AFTER_FREE,
        CT_SOFTLOCKUP,
        CT_HARDLOCKUP,
        CT_SPINLOCKUP,
        CT_ACCESS_USERSPACE,
        CT_WRITE_RO,
        CT_WRITE_KERN,
+       CT_WRAP_ATOMIC
  };
  
  static char* cp_name[] = {
@@@ -129,6 -133,9 +133,9 @@@ static char* cp_type[] = 
        "UNALIGNED_LOAD_STORE_WRITE",
        "OVERWRITE_ALLOCATION",
        "WRITE_AFTER_FREE",
+       "READ_AFTER_FREE",
+       "WRITE_BUDDY_AFTER_FREE",
+       "READ_BUDDY_AFTER_FREE",
        "SOFTLOCKUP",
        "HARDLOCKUP",
        "SPINLOCKUP",
        "ACCESS_USERSPACE",
        "WRITE_RO",
        "WRITE_KERN",
+       "WRAP_ATOMIC"
  };
  
  static struct jprobe lkdtm;
@@@ -335,7 -343,7 +343,7 @@@ static noinline void corrupt_stack(void
        memset((void *)data, 0, 64);
  }
  
 -static void execute_location(void *dst)
 +static void noinline execute_location(void *dst)
  {
        void (*func)(void) = dst;
  
@@@ -409,12 -417,109 +417,109 @@@ static void lkdtm_do_action(enum ctype 
                break;
        }
        case CT_WRITE_AFTER_FREE: {
+               int *base, *again;
                size_t len = 1024;
-               u32 *data = kmalloc(len, GFP_KERNEL);
+               /*
+                * The slub allocator uses the first word to store the free
+                * pointer in some configurations. Use the middle of the
+                * allocation to avoid running into the freelist
+                */
+               size_t offset = (len / sizeof(*base)) / 2;
+               base = kmalloc(len, GFP_KERNEL);
+               pr_info("Allocated memory %p-%p\n", base, &base[offset * 2]);
+               pr_info("Attempting bad write to freed memory at %p\n",
+                       &base[offset]);
+               kfree(base);
+               base[offset] = 0x0abcdef0;
+               /* Attempt to notice the overwrite. */
+               again = kmalloc(len, GFP_KERNEL);
+               kfree(again);
+               if (again != base)
+                       pr_info("Hmm, didn't get the same memory range.\n");
  
-               kfree(data);
+               break;
+       }
+       case CT_READ_AFTER_FREE: {
+               int *base, *val, saw;
+               size_t len = 1024;
+               /*
+                * The slub allocator uses the first word to store the free
+                * pointer in some configurations. Use the middle of the
+                * allocation to avoid running into the freelist
+                */
+               size_t offset = (len / sizeof(*base)) / 2;
+               base = kmalloc(len, GFP_KERNEL);
+               if (!base)
+                       break;
+               val = kmalloc(len, GFP_KERNEL);
+               if (!val)
+                       break;
+               *val = 0x12345678;
+               base[offset] = *val;
+               pr_info("Value in memory before free: %x\n", base[offset]);
+               kfree(base);
+               pr_info("Attempting bad read from freed memory\n");
+               saw = base[offset];
+               if (saw != *val) {
+                       /* Good! Poisoning happened, so declare a win. */
+                       pr_info("Memory correctly poisoned (%x)\n", saw);
+                       BUG();
+               }
+               pr_info("Memory was not poisoned\n");
+               kfree(val);
+               break;
+       }
+       case CT_WRITE_BUDDY_AFTER_FREE: {
+               unsigned long p = __get_free_page(GFP_KERNEL);
+               if (!p)
+                       break;
+               pr_info("Writing to the buddy page before free\n");
+               memset((void *)p, 0x3, PAGE_SIZE);
+               free_page(p);
+               schedule();
+               pr_info("Attempting bad write to the buddy page after free\n");
+               memset((void *)p, 0x78, PAGE_SIZE);
+               /* Attempt to notice the overwrite. */
+               p = __get_free_page(GFP_KERNEL);
+               free_page(p);
                schedule();
-               memset(data, 0x78, len);
+               break;
+       }
+       case CT_READ_BUDDY_AFTER_FREE: {
+               unsigned long p = __get_free_page(GFP_KERNEL);
+               int saw, *val = kmalloc(1024, GFP_KERNEL);
+               int *base;
+               if (!p)
+                       break;
+               if (!val)
+                       break;
+               base = (int *)p;
+               *val = 0x12345678;
+               base[0] = *val;
+               pr_info("Value in memory before free: %x\n", base[0]);
+               free_page(p);
+               pr_info("Attempting to read from freed memory\n");
+               saw = base[0];
+               if (saw != *val) {
+                       /* Good! Poisoning happened, so declare a win. */
+                       pr_info("Memory correctly poisoned (%x)\n", saw);
+                       BUG();
+               }
+               pr_info("Buddy page was not poisoned\n");
+               kfree(val);
                break;
        }
        case CT_SOFTLOCKUP:
                do_overwritten();
                break;
        }
+       case CT_WRAP_ATOMIC: {
+               atomic_t under = ATOMIC_INIT(INT_MIN);
+               atomic_t over = ATOMIC_INIT(INT_MAX);
+               pr_info("attempting atomic underflow\n");
+               atomic_dec(&under);
+               pr_info("attempting atomic overflow\n");
+               atomic_inc(&over);
+               return;
+       }
        case CT_NONE:
        default:
                break;
diff --combined drivers/watchdog/Kconfig
index 86c2392bd9684ff5c6f604bbf1c004ec9e7581f6,80825a7e8e48e1ebd06af14a1bcf208acb733daf..9289da313d985f434f7c350a88db97321437372e
@@@ -1214,21 -1214,6 +1214,21 @@@ config SBC_EPX_C3_WATCHDO
          To compile this driver as a module, choose M here: the
          module will be called sbc_epx_c3.
  
 +config INTEL_MEI_WDT
 +      tristate "Intel MEI iAMT Watchdog"
 +      depends on INTEL_MEI && X86
 +      select WATCHDOG_CORE
 +      ---help---
 +        A device driver for the Intel MEI iAMT watchdog.
 +
 +        The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog.
 +        Whenever the OS hangs or crashes, iAMT will send an event
 +        to any subscriber to this event. The watchdog doesn't reset the
 +        the platform.
 +
 +        To compile this driver as a module, choose M here:
 +        the module will be called mei_wdt.
 +
  # M32R Architecture
  
  # M68K Architecture
@@@ -1584,6 -1569,17 +1584,17 @@@ config WATCHDOG_RI
          machines.  The watchdog timeout period is normally one minute but
          can be changed with a boot-time parameter.
  
+ config WATCHDOG_SUN4V
+       tristate "Sun4v Watchdog support"
+       select WATCHDOG_CORE
+       depends on SPARC64
+       help
+         Say Y here to support the hypervisor watchdog capability embedded
+         in the SPARC sun4v architecture.
+         To compile this driver as a module, choose M here. The module will
+         be called sun4v_wdt.
  # XTENSA Architecture
  
  # Xen Architecture
index efc4f788e0f29cb1e5c69f488a0717728e16438f,f6a6a387c6c71f7a5e9e2cda4cc91ae3f39edf2c..14bd772d3e66673cfcb2a495a9fe41863d0faf00
@@@ -126,7 -126,6 +126,7 @@@ obj-$(CONFIG_MACHZ_WDT) += machzwd.
  obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
  obj-$(CONFIG_INTEL_SCU_WATCHDOG) += intel_scu_watchdog.o
  obj-$(CONFIG_INTEL_MID_WATCHDOG) += intel-mid_wdt.o
 +obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o
  
  # M32R Architecture
  
@@@ -180,6 -179,7 +180,7 @@@ obj-$(CONFIG_SH_WDT) += shwdt.
  
  obj-$(CONFIG_WATCHDOG_RIO)            += riowd.o
  obj-$(CONFIG_WATCHDOG_CP1XXX)         += cpwd.o
+ obj-$(CONFIG_WATCHDOG_SUN4V)          += sun4v_wdt.o
  
  # XTENSA Architecture