Re: Serious bugs in kernel - related to misuse of GFP_ATOMIC

Pavel Machek (pavel@Elf.mj.gts.cz)
Fri, 19 Sep 1997 16:11:42 +0200


Hi!

I've created new version of unreliable-malloc patch. This time it is
tunable via echo "0" > /proc/sys/kernel/unreliable-malloc (0 == be
reliable, 1 == fail always, 2 == 50% failures, 3 = 33% failures etc.)

Pavel

(Against 2.1.55)

here it goes:

Index: linux/Documentation/Configure.help
===================================================================
RCS file: /home/pavel/cvsroot/linux/Documentation/Configure.help,v
retrieving revision 1.15
diff -u -r1.15 Configure.help
--- Configure.help 1997/09/14 09:35:39 1.15
+++ Configure.help 1997/09/19 08:54:47
@@ -5422,6 +5422,15 @@
mean is "Use the source, Luke!" -- read drivers/char/sysrq.c.
Don't say Y unless you really know what this hack does.

+Unreliable malloc
+CONFIG_UNRELIABLE_MALLOC
+ This switch is meant for kernel hackers and testers. Under normal
+ circumstances ATOMIC allocations rarely fail. Too many things are
+ dependend on GFP_ATOMIC not failing, and this is why 'Could not get a
+ free page...' is deadly. This switch makes ATOMIC allocations fail
+ pretty often - so it is easy to see bugs. Has bad impact on TCP
+ performance. Say N, unless you want to test your kernel cruel way.
+
ISDN subsystem
CONFIG_ISDN
ISDN ("Integrated Services Digital Networks", called RNIS in France)
Index: linux/arch/i386/config.in
===================================================================
RCS file: /home/pavel/cvsroot/linux/arch/i386/config.in,v
retrieving revision 1.10
diff -u -r1.10 config.in
--- config.in 1997/09/07 16:20:43 1.10
+++ config.in 1997/09/19 08:54:48
@@ -107,6 +107,7 @@
bool 'SMP Profiling' CONFIG_SMP_PROF
fi
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Unreliable kmalloc' CONFIG_UNRELIABLE_MALLOC
endmenu


Index: linux/include/linux/sysctl.h
===================================================================
RCS file: /home/pavel/cvsroot/linux/include/linux/sysctl.h,v
retrieving revision 1.4
diff -u -r1.4 sysctl.h
--- sysctl.h 1997/09/06 15:57:01 1.4
+++ sysctl.h 1997/09/19 08:55:28
@@ -69,7 +69,8 @@
KERN_CTLALTDEL, /* int: allow ctl-alt-del to reboot */
KERN_PRINTK, /* sturct: control printk logging parameters */
KERN_NAMETRANS, /* Name translation */
- KERN_STATINODE
+ KERN_STATINODE,
+ KERN_UNRELIABLE_MALLOC /* unreliable malloc debugging hack */
};


Index: linux/kernel/sysctl.c
===================================================================
RCS file: /home/pavel/cvsroot/linux/kernel/sysctl.c,v
retrieving revision 1.4
diff -u -r1.4 sysctl.c
--- sysctl.c 1997/07/18 11:55:51 1.4
+++ sysctl.c 1997/09/19 08:55:36
@@ -117,6 +117,10 @@
static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
#endif

+#ifdef CONFIG_UNRELIABLE_MALLOC
+extern int unreliable_malloc_fail_ratio;
+#endif
+
/* The default sysctl tables: */

static ctl_table root_table[] = {
@@ -174,6 +178,10 @@
#ifdef __sparc__
{KERN_SPARC_REBOOT, "reboot-cmd", reboot_command,
256, 0644, NULL, &proc_dostring, &sysctl_string },
+#endif
+#ifdef CONFIG_UNRELIABLE_MALLOC
+ {KERN_UNRELIABLE_MALLOC, "unreliable-malloc", &unreliable_malloc_fail_ratio, sizeof(int),
+ 0644, NULL, &proc_dointvec},
#endif
{KERN_CTLALTDEL, "ctrl-alt-del", &C_A_D, sizeof(int),
0644, NULL, &proc_dointvec},
Index: linux/mm/slab.c
===================================================================
RCS file: /home/pavel/cvsroot/linux/mm/slab.c,v
retrieving revision 1.5
diff -u -r1.5 slab.c
--- slab.c 1997/08/16 17:04:13 1.5
+++ slab.c 1997/09/19 08:55:40
@@ -1350,6 +1350,13 @@
cachep->c_freep = slabp;
}

+#ifdef CONFIG_UNRELIABLE_MALLOC
+static int random_seed;
+int unreliable_malloc_fail_ratio = 2; /* 0 = be reliable, 1 = fail 50%, 2 = fail 25%, etc. */
+//#define RANDOM (random_seed = (random_seed * 43214 + 875)%6854653, ! ((jiffies ^ random_seed) % unreliable_malloc_fail_ratio))
+#define RANDOM (! (jiffies % unreliable_malloc_fail_ratio))
+#endif
+
/* Returns a ptr to an obj in the given cache. */
static inline void *
__kmem_cache_alloc(kmem_cache_t *cachep, int flags)
@@ -1358,7 +1365,12 @@
kmem_bufctl_t *bufp;
void *objp;
unsigned long save_flags;
-
+#ifdef CONFIG_UNRELIABLE_MALLOC
+ if (unreliable_malloc_fail_ratio &&
+ ((flags & SLAB_LEVEL_MASK) == SLAB_ATOMIC))
+ if (RANDOM)
+ return NULL;
+#endif
/* Sanity check. */
if (!cachep)
goto nul_ptr;

-- 
I'm really pavel@atrey.karlin.mff.cuni.cz. 	   Pavel
Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).