From: Benjamin LaHaise <bcrl@kvack.org>

The patch below makes kmalloc() fail at compile time for swapped flags and
size arguments when the flags are a constant.  It will also fail at runtime
(non-constant flags) due to the size being too large.

This is done by adding a new flag, __GFP_VALID, which is checked for in
kmalloc(), that results in the size being too large.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 include/linux/gfp.h  |   16 +++++++++-------
 include/linux/slab.h |    4 ++++
 2 files changed, 13 insertions(+), 7 deletions(-)

diff -puN include/linux/gfp.h~make-kmalloc-fail-for-swapped-size--gfp-flags include/linux/gfp.h
--- devel/include/linux/gfp.h~make-kmalloc-fail-for-swapped-size--gfp-flags	2005-09-07 20:10:58.000000000 -0700
+++ devel-akpm/include/linux/gfp.h	2005-09-07 20:10:58.000000000 -0700
@@ -48,6 +48,7 @@ struct vm_area_struct;
 #define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
 #define __GFP_NORECLAIM  0x20000u /* No realy zone reclaim during allocation */
 #define __GFP_HARDWALL   0x40000u /* Enforce hardwall cpuset memory allocs */
+#define __GFP_VALID	0x80000000u /* valid GFP flags */
 
 #define __GFP_BITS_SHIFT 20	/* Room for 20 __GFP_FOO bits */
 #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
@@ -58,13 +59,14 @@ struct vm_area_struct;
 			__GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \
 			__GFP_NOMEMALLOC|__GFP_NORECLAIM|__GFP_HARDWALL)
 
-#define GFP_ATOMIC	(__GFP_HIGH)
-#define GFP_NOIO	(__GFP_WAIT)
-#define GFP_NOFS	(__GFP_WAIT | __GFP_IO)
-#define GFP_KERNEL	(__GFP_WAIT | __GFP_IO | __GFP_FS)
-#define GFP_USER	(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
-#define GFP_HIGHUSER	(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \
-			 __GFP_HIGHMEM)
+#define GFP_ATOMIC	(__GFP_VALID | __GFP_HIGH)
+#define GFP_NOIO	(__GFP_VALID | __GFP_WAIT)
+#define GFP_NOFS	(__GFP_VALID | __GFP_WAIT | __GFP_IO)
+#define GFP_KERNEL	(__GFP_VALID | __GFP_WAIT | __GFP_IO | __GFP_FS)
+#define GFP_USER	(__GFP_VALID | __GFP_WAIT | __GFP_IO | __GFP_FS | \
+				__GFP_HARDWALL)
+#define GFP_HIGHUSER	(__GFP_VALID | __GFP_WAIT | __GFP_IO | __GFP_FS | \
+				__GFP_HIGHMEM | __GFP_HARDWALL)
 
 /* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
    platforms, used as appropriate on others */
diff -puN include/linux/slab.h~make-kmalloc-fail-for-swapped-size--gfp-flags include/linux/slab.h
--- devel/include/linux/slab.h~make-kmalloc-fail-for-swapped-size--gfp-flags	2005-09-07 20:10:58.000000000 -0700
+++ devel-akpm/include/linux/slab.h	2005-09-07 20:10:58.000000000 -0700
@@ -78,6 +78,10 @@ extern void *__kmalloc(size_t, unsigned 
 
 static inline void *kmalloc(size_t size, unsigned int __nocast flags)
 {
+	if (__builtin_constant_p(flags) && !(flags & __GFP_VALID)) {
+		extern void __your_kmalloc_flags_are_not_valid(void);
+		__your_kmalloc_flags_are_not_valid();
+	}
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 #define CACHE(x) \
_