@@ -1027,6 +1027,11 @@ static noinline void __init kernel_init_freeable(void)
do_basic_setup();
+#ifdef CONFIG_MEMORY_SANITIZE
+ pr_debug("[CONFIG_MEMORY_SANITIZE]: page_poisoning_enabled? %s\n",
+ page_poisoning_enabled() ? "yes" : "no");
+#endif
+
/* Open the /dev/console on the rootfs, this should never fail */
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
pr_err("Warning: unable to open an initial console.\n");
@@ -97,3 +97,25 @@ config DEBUG_RODATA_TEST
---help---
This option enables a testcase for the setting rodata read-only.
+config MEMORY_SANITIZE
+ bool "Enable memory sanitization features"
+ select SLUB_DEBUG
+ select PAGE_POISONING
+ select PAGE_POISONING_NO_SANITY
+ ---help---
+ This option enables memory sanitization features. Particularly,
+ when you turn on this option, it auto-enables:
+ - SLUB debug
+ - page poisoning
+ - page poisoning no sanity.
+
+ Implication: turning this option on _will_ implicitly enable:
+ - the SLUB_DEBUG switch to the equivalent of the kernel command-line
+ 'slub_debug=p' ; (where p=SLAB_POISON),
+ - page poisoning, equivalent to passing the kernel command-line option
+ 'page_poison=on'.
+ Of course, kernel command-line options 'page_poison' and 'slub_debug'
+ are still honoured (except that slub-debug will always have the 'p' set).
+
+ If unsure, say N.
+
@@ -7,7 +7,8 @@
#include <linux/ratelimit.h>
static bool __page_poisoning_enabled __read_mostly;
-static bool want_page_poisoning __read_mostly;
+static bool want_page_poisoning __read_mostly =
+ IS_ENABLED(CONFIG_MEMORY_SANITIZE);
static int early_page_poison_param(char *buf)
{
@@ -49,6 +50,17 @@ struct page_ext_operations page_poisoning_ops = {
.init = init_page_poisoning,
};
+static int __init memory_sanitize_pagepoison_init(void)
+{
+ */
+ if (IS_ENABLED(CONFIG_MEMORY_SANITIZE) && !want_page_poisoning)
+ __page_poisoning_enabled = false;
+ return 0;
+}
+early_initcall(memory_sanitize_pagepoison_init);
+
static inline void set_page_poison(struct page *page)
{
struct page_ext *page_ext;
@@ -450,15 +450,30 @@ static inline void *restore_red_left(struct kmem_cache *s, void *p)
/*
* Debug settings:
*/
-#if defined(CONFIG_SLUB_DEBUG_ON)
-static int slub_debug = DEBUG_DEFAULT_FLAGS;
-#else
static int slub_debug;
-#endif
static char *slub_debug_slabs;
static int disable_higher_order_debug;
+static int __init memory_sanitize_slubdebug_init(void)
+{
+/* With MEMORY_SANITIZE On, slub_debug Must be set to 'p' */
+ if (IS_ENABLED(CONFIG_SLUB_DEBUG_ON) &&
+ IS_ENABLED(CONFIG_MEMORY_SANITIZE)) {
+ slub_debug |= SLAB_POISON;
+ } else if (!IS_ENABLED(CONFIG_SLUB_DEBUG_ON) &&
+ IS_ENABLED(CONFIG_MEMORY_SANITIZE)) {
+ slub_debug = SLAB_POISON;
+ } else if (IS_ENABLED(CONFIG_SLUB_DEBUG_ON) &&
+ !IS_ENABLED(CONFIG_MEMORY_SANITIZE)) {
+ slub_debug = DEBUG_DEFAULT_FLAGS;
+ } else { /* both disabled */
+ slub_debug = 0;
+ }
+ return 0;
+}
+early_initcall(memory_sanitize_slubdebug_init);
+
/*
* slub is about to manipulate internal object metadata. This memory lies
* outside the range of the allocated object, so accessing it would normally
@@ -5755,6 +5770,11 @@ static int __init slab_sysfs_init(void)
struct kmem_cache *s;
int err;
+#ifdef CONFIG_MEMORY_SANITIZE
+ pr_info("[CONFIG_MEMORY_SANITIZE]: slub_debug = P? %s [0x%x]\n",
+ slub_debug & SLAB_POISON ? "yes" : "no", slub_debug);
+#endif
+
mutex_lock(&slab_mutex);
slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj);