diff -u linux-2.6.29.4/arch/x86/include/asm/uaccess_32.h linux-2.6.29.4-devel/arch/x86/include/asm/uaccess_32.h
--- linux-2.6.29.4/arch/x86/include/asm/uaccess_32.h	2009-05-27 04:31:25.000000000 -0400
+++ linux-2.6.29.4-devel/arch/x86/include/asm/uaccess_32.h	2009-05-27 03:37:55.000000000 -0400
@@ -22,6 +22,10 @@
 unsigned long __must_check __copy_from_user_ll_nocache_nozero
 		(void *to, const void __user *from, unsigned long n);
 
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+extern void __chk_fail(void);
+#endif
+
 /**
  * __copy_to_user_inatomic: - Copy a block of data into user space, with less checking.
  * @to:   Destination address, in user space.
@@ -62,6 +66,10 @@
 			return ret;
 		}
 	}
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+	if (__bos0 (from) != (size_t) -1 && n > __bos0 (from))
+		__chk_fail();
+#endif
 	if (!__builtin_constant_p(n))
 		check_object_size(from, n, true);
 	return __copy_to_user_ll(to, from, n);
@@ -229,6 +237,10 @@
 static __always_inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+	if (__bos0 (to) != (size_t) -1 && n > __bos0 (to))
+		__chk_fail();
+#endif
 	if (access_ok(VERIFY_READ, from, n))
 		n = __copy_from_user(to, from, n);
 	else if ((long)n > 0)
diff -u linux-2.6.29.4/include/linux/gralloc.h linux-2.6.29.4-devel/include/linux/gralloc.h
--- linux-2.6.29.4/include/linux/gralloc.h	2009-05-27 04:31:29.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/gralloc.h	2009-06-01 20:20:26.000000000 -0400
@@ -2,7 +2,9 @@
 #define __GRALLOC_H
 
+#include <linux/compiler.h>
+
 void acl_free_all(void);
 int acl_alloc_stack_init(unsigned long size);
-void *acl_alloc(unsigned long len);
+void *acl_alloc(unsigned long len) __malloc__attributes;
 
 #endif
diff -u linux-2.6.29.4/include/linux/percpu.h linux-2.6.29.4-devel/include/linux/percpu.h
--- linux-2.6.29.4/include/linux/percpu.h	2009-05-27 04:31:29.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/percpu.h	2009-06-01 19:57:57.000000000 -0400
@@ -81,7 +81,7 @@
         (__typeof__(ptr))__p->ptrs[(cpu)];	          \
 })
 
-extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask);
+extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) __malloc__attributes;
 extern void percpu_free(void *__pdata);
 
 #else /* CONFIG_SMP */
diff -u linux-2.6.29.4/include/linux/slab.h linux-2.6.29.4-devel/include/linux/slab.h
--- linux-2.6.29.4/include/linux/slab.h	2009-05-27 04:31:30.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/slab.h	2009-06-01 19:57:21.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/gfp.h>
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 /*
  * Flags to pass to kmem_cache_create().
@@ -208,7 +209,14 @@
  * for general use, and so are not documented here. For a full list of
  * potential flags, always refer to linux/gfp.h.
  */
+
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+extern void *kcalloc(size_t n, size_t size, gfp_t flags)
+	__calloc__attributes;
+static inline void *__fortify_kcalloc(size_t n, size_t size, gfp_t flags)
+#else
 static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+#endif
 {
 	if (size != 0 && n > ULONG_MAX / size)
 		return NULL;
diff -u linux-2.6.29.4/include/linux/slub_def.h linux-2.6.29.4-devel/include/linux/slub_def.h
--- linux-2.6.29.4/include/linux/slub_def.h	2009-05-27 04:31:30.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/slub_def.h	2009-06-01 20:26:28.000000000 -0400
@@ -202,14 +203,19 @@
 #endif
 
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
-void *__kmalloc(size_t size, gfp_t flags);
+void *__kmalloc(size_t size, gfp_t flags) __malloc__attributes;
 
 static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 {
 	return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size));
 }
 
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+extern void *kmalloc(size_t size, gfp_t flags) __attribute__((malloc)) __attribute__((alloc_size(1)));
+static __always_inline void *__fortify_kmalloc(size_t size, gfp_t flags)
+#else
 static __always_inline void *kmalloc(size_t size, gfp_t flags)
+#endif
 {
 	if (__builtin_constant_p(size)) {
 		if (size > PAGE_SIZE)
@@ -231,7 +237,12 @@
 void *__kmalloc_node(size_t size, gfp_t flags, int node);
 void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+extern void *kmalloc_node(size_t size, gfp_t flags, int node) __malloc__attributes;
+static __always_inline void *__fortify_kmalloc_node(size_t size, gfp_t flags, int node)
+#else
 static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+#endif
 {
 	if (__builtin_constant_p(size) &&
 		size <= PAGE_SIZE && !(flags & SLUB_DMA)) {
diff -u linux-2.6.29.4/include/linux/vmalloc.h linux-2.6.29.4-devel/include/linux/vmalloc.h
--- linux-2.6.29.4/include/linux/vmalloc.h	2009-05-27 04:31:30.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/vmalloc.h	2009-06-01 00:15:03.000000000 -0400
@@ -55,13 +55,13 @@
 }
 #endif
 
-extern void *vmalloc(unsigned long size);
-extern void *vmalloc_user(unsigned long size);
-extern void *vmalloc_node(unsigned long size, int node);
-extern void *vmalloc_exec(unsigned long size);
-extern void *vmalloc_32(unsigned long size);
-extern void *vmalloc_32_user(unsigned long size);
-extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
+extern void *vmalloc(unsigned long size) __malloc__attributes;
+extern void *vmalloc_user(unsigned long size) __malloc__attributes;
+extern void *vmalloc_node(unsigned long size, int node) __malloc__attributes;
+extern void *vmalloc_exec(unsigned long size) __malloc__attributes;
+extern void *vmalloc_32(unsigned long size) __malloc__attributes;
+extern void *vmalloc_32_user(unsigned long size) __malloc__attributes;
+extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) __malloc__attributes;
 extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask,
 				pgprot_t prot);
 extern void vfree(const void *addr);
diff -u linux-2.6.29.4/mm/page_alloc.c linux-2.6.29.4-devel/mm/page_alloc.c
--- linux-2.6.29.4/mm/page_alloc.c	2009-05-27 04:31:31.000000000 -0400
+++ linux-2.6.29.4-devel/mm/page_alloc.c	2009-06-01 20:16:51.000000000 -0400
@@ -1703,6 +1703,7 @@
 
 EXPORT_SYMBOL(__get_free_pages);
 
+#undef get_zeroed_page
 unsigned long get_zeroed_page(gfp_t gfp_mask)
 {
 	struct page * page;
diff -u linux-2.6.29.4/security/Kconfig linux-2.6.29.4-devel/security/Kconfig
--- linux-2.6.29.4/security/Kconfig	2009-05-27 04:31:31.000000000 -0400
+++ linux-2.6.29.4-devel/security/Kconfig	2009-05-27 03:08:50.000000000 -0400
@@ -442,6 +442,14 @@
 	  Since this has a negligible performance impact, you should enable
 	  this feature.
 
+config PAX_FORTIFY_SOURCE
+	bool "Enable limited buffer overflow checking"
+	depends on GRKERNSEC && X86_32
+	help
+	  By saying Y here the kernel will use a recent gcc feature that
+	  allows several key kernel string/memory copying routines to
+	  check for buffer overflows when dealing with static buffers.
+
 config PAX_USERCOPY
 	bool "Bounds check heap object copies between kernel and userland"
 	depends on X86
only in patch2:
unchanged:
--- linux-2.6.29.4/arch/x86/lib/memcpy_32.c	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/arch/x86/lib/memcpy_32.c	2009-05-31 14:51:32.000000000 -0400
@@ -3,6 +3,7 @@
 
 #undef memcpy
 #undef memset
+#undef memmove
 
 void *memcpy(void *to, const void *from, size_t n)
 {
only in patch2:
unchanged:
--- linux-2.6.29.4/drivers/isdn/hardware/eicon/platform.h	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/drivers/isdn/hardware/eicon/platform.h	2009-05-31 14:08:30.000000000 -0400
@@ -127,8 +127,6 @@
 #define DIVAS_CONTAINING_RECORD(address, type, field) \
         ((type *)((char*)(address) - (char*)(&((type *)0)->field)))
 
-extern int sprintf(char *, const char*, ...);
-
 typedef void* LIST_ENTRY;
 
 typedef char    DEVICE_NAME[64];
only in patch2:
unchanged:
--- linux-2.6.29.4/include/linux/compiler-gcc4.h	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/compiler-gcc4.h	2009-06-01 00:09:34.000000000 -0400
@@ -12,6 +12,13 @@
 #define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
 #define __always_inline		inline __attribute__((always_inline))
 
+#if __GNUC_MINOR__ >= 3
+#define __bos1(ptr) __builtin_object_size (ptr, 1)
+#define __bos0(ptr) __builtin_object_size (ptr, 0)
+#define __malloc__attributes	__attribute__((malloc)) __attribute__((alloc_size(1)))
+#define __calloc__attributes	__attribute__((malloc)) __attribute__((alloc_size(1, 2)))
+#endif
+
 /*
  * A trick to suppress uninitialized variable warning without generating any
  * code
only in patch2:
unchanged:
--- linux-2.6.29.4/include/linux/compiler.h	2009-05-27 00:30:00.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/compiler.h	2009-06-01 00:10:19.000000000 -0400
@@ -275,4 +275,20 @@ void ftrace_likely_update(struct ftrace_
  */
 #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
 
+#ifndef __bos1
+#define __bos1(x) -1
+#endif
+
+#ifndef __bos0
+#define __bos0(x) -1
+#endif
+
+#ifndef __malloc__attributes
+#define __malloc__attributes
+#endif
+
+#ifndef __calloc__attributes
+#define __calloc__attributes
+#endif
+
 #endif /* __LINUX_COMPILER_H */
only in patch2:
unchanged:
--- linux-2.6.29.4/include/linux/gfp.h	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/gfp.h	2009-06-01 20:15:42.000000000 -0400
@@ -220,9 +220,15 @@ extern struct page *alloc_page_vma(gfp_t
 #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
 
 extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
+
 extern unsigned long get_zeroed_page(gfp_t gfp_mask);
 
-void *alloc_pages_exact(size_t size, gfp_t gfp_mask);
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+extern void *get_zeroed_page_chk(size_t size, gfp_t gfp_mask) __malloc__attributes;
+#define get_zeroed_page(x) (unsigned long)get_zeroed_page_chk(PAGE_SIZE, (x))
+#endif
+
+void *alloc_pages_exact(size_t size, gfp_t gfp_mask) __malloc__attributes;
 void free_pages_exact(void *virt, size_t size);
 
 #define __get_free_page(gfp_mask) \
only in patch2:
unchanged:
--- linux-2.6.29.4/include/linux/kernel.h	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/kernel.h	2009-05-31 12:27:15.000000000 -0400
@@ -196,6 +196,25 @@ extern int sscanf(const char *, const ch
 extern int vsscanf(const char *, const char *, va_list)
 	__attribute__ ((format (scanf, 2, 0)));
 
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+#undef sprintf
+#define sprintf(buf, fmt, ...) \
+	__builtin___sprintf_chk (buf, 0, __bos0 (buf), fmt, ## __VA_ARGS__)
+
+#undef vsprintf
+#define vsprintf(buf, fmt, va_list) \
+	__builtin___vsprintf_chk (buf, 0, __bos0 (buf), fmt, va_list)
+
+#undef snprintf
+#define snprintf(buf, maxlen, fmt, ...) \
+	__builtin___snprintf_chk (buf, maxlen, 0, __bos0 (buf), fmt, ## __VA_ARGS__)
+
+#undef vsnprintf
+#define vsnprintf(buf, maxlen, fmt, va_list) \
+	__builtin___vsnprintf_chk (buf, maxlen, 0, __bos0 (buf), fmt, va_list)
+
+#endif
+
 extern int get_option(char **str, int *pint);
 extern char *get_options(const char *str, int nints, int *ints);
 extern unsigned long long memparse(const char *ptr, char **retptr);
only in patch2:
unchanged:
--- linux-2.6.29.4/include/linux/string.h	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/include/linux/string.h	2009-06-01 19:31:44.000000000 -0400
@@ -102,6 +102,143 @@ extern int memcmp(const void *,const voi
 extern void * memchr(const void *,int,__kernel_size_t);
 #endif
 
+#ifdef CONFIG_PAX_FORTIFY_SOURCE
+
+/*
+ * "fortified" variants of some of these functions that for certain cases make
+ * gcc emit code that checks for buffer overflows.
+ */
+
+#undef strcpy
+#undef __HAVE_ARCH_STRCPY
+#define strcpy(dest, src) \
+  ((__bos1 (dest) != (size_t) -1)                                        \
+   ? __builtin___strcpy_chk (dest, src, __bos1 (dest))                   \
+   : __strcpy_ichk (dest, src))
+#if 1
+extern char *
+__strcpy_ichk (char * __dest, const char * __src);
+#else
+static __always_inline char *
+__strcpy_ichk (char * __dest, const char * __src)
+{
+  return __builtin___strcpy_chk (__dest, __src, __bos1 (__dest));
+}
+#endif
+
+#undef strncpy
+#undef __HAVE_ARCH_STRNCPY
+#define strncpy(dest, src, len) \
+  ((__bos1 (dest) != (size_t) -1)                                        \
+   ? __builtin___strncpy_chk (dest, src, len, __bos1 (dest))             \
+   : __strncpy_ichk (dest, src, len))
+#if 1
+extern char *
+__strncpy_ichk (char * __dest, const char * __src, size_t __len);
+#else
+static __always_inline char *
+__strncpy_ichk (char * __dest, const char * __src, size_t __len)
+{
+  return __builtin___strncpy_chk (__dest, __src, __len, __bos1 (__dest));
+}
+#endif
+
+#undef strcat
+#undef __HAVE_ARCH_STRCAT
+#define strcat(dest, src) \
+  ((__bos1 (dest) != (size_t) -1)                                        \
+   ? __builtin___strcat_chk (dest, src, __bos1 (dest))                   \
+   : __strcat_ichk (dest, src))
+
+#if 1
+extern char *
+__strcat_ichk (char * __dest, const char * __src);
+#else
+static __always_inline char *
+__strcat_ichk (char * __dest, const char * __src)
+{
+  return __builtin___strcat_chk (__dest, __src, __bos1 (__dest));
+}
+#endif
+
+#undef strncat
+#undef __HAVE_ARCH_STRNCAT
+#define strncat(dest, src, len) \
+  ((__bos1 (dest) != (size_t) -1)                                        \
+   ? __builtin___strncat_chk (dest, src, len, __bos1 (dest))             \
+   : __strncat_ichk (dest, src, len))
+
+#if 1
+extern char *
+__strncat_ichk (char * __dest, const char * __src, size_t __len);
+#else
+static __always_inline char *
+__strncat_ichk (char * __dest, const char * __src, size_t __len)
+{
+  return __builtin___strncat_chk (__dest, __src, __len, __bos1 (__dest));
+}
+#endif
+
+#undef memcpy
+#define memcpy(dest, src, len) \
+  ((__bos0 (dest) != (size_t) -1)                                       \
+   ? __builtin___memcpy_chk (dest, src, len, __bos0 (dest))             \
+   : __memcpy_ichk (dest, src, len))
+
+#if 1
+extern void *
+__memcpy_ichk (void * __dest, const void *__src, size_t __len);
+#else
+static __always_inline void *
+__memcpy_ichk (void * __dest, const void *__src, size_t __len)
+{
+  return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
+}
+#endif
+
+#undef memmove
+#define memmove(dest, src, len) \
+  ((__bos0 (dest) != (size_t) -1)                                       \
+   ? __builtin___memmove_chk (dest, src, len, __bos0 (dest))             \
+   : __memmove_ichk (dest, src, len))
+
+#if 1
+extern void *
+__memmove_ichk (void * __dest, const void *__src, size_t __len);
+#else
+static __always_inline void *
+__memmove_ichk (void * __dest, const void *__src, size_t __len)
+{
+  return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
+}
+#endif
+
+/* memset(x,y,0) is a common typo; this dummy non-existent function is
+ * there to create a linker error in that case
+ */
+extern void __warn_memset_zero_len(void);
+
+#undef memset
+#define memset(dest, ch, len) \
+  (__builtin_constant_p (len) && (len) == 0 && (!__builtin_constant_p(ch) || ((ch)!=0)) \
+   ? (__warn_memset_zero_len (), (void) (ch), (void) (len), (void *) (dest))  \
+   : ((__bos0 (dest) != (size_t) -1)                                          \
+      ? __builtin___memset_chk (dest, ch, len, __bos0 (dest))                 \
+      : __memset_ichk (dest, ch, len)))
+
+#if 1
+extern void *
+__memset_ichk (void *__dest, int __ch, size_t __len);
+#else
+static __always_inline void *
+__memset_ichk (void *__dest, int __ch, size_t __len)
+{
+  return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
+}
+#endif
+
+#endif
+
 extern char *kstrdup(const char *s, gfp_t gfp);
 extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
 extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
@@ -116,3 +253,4 @@ extern ssize_t memory_read_from_buffer(v
 
 #endif
 #endif /* _LINUX_STRING_H_ */
+
only in patch2:
unchanged:
--- linux-2.6.29.4/lib/fortify.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.29.4-devel/lib/fortify.c	2009-06-01 20:55:17.000000000 -0400
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 1991, 1997, 2003, 2004 Free Software Foundation, Inc.
+ * *alloc/memmove/*printf support by Brad Spengler <spender@grsecurity.net>
+ * Portions Copyright (C) 2005 Arjan van de Ven <arjan@infreadead.org>
+ * Portions Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * (Several of these functions were copied from various FSF projects)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+char *__strcpy_ichk(char *d, const char *s)
+{
+	return NULL;
+}
+
+char *__strncpy_ichk(char *d, const char *s, size_t len)
+{
+	return NULL;
+}
+
+char *__strcat_ichk(char *d, const char *s)
+{
+	return NULL;
+}
+
+char *__strncat_ichk(char *d, const char *s, size_t len)
+{
+	return NULL;
+}
+
+void *__memcpy_ichk(void *d, const void *s, size_t len)
+{
+	return NULL;
+}
+
+void *__memmove_ichk(void *d, const void *s, size_t len)
+{
+	return NULL;
+}
+
+void *__memset_ichk(void *d, int i, size_t len)
+{
+	return NULL;
+}
+
+void __chk_fail(void) 
+{
+	if (current->signal->curr_ip)
+		printk(KERN_ALERT "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to overflow a kernel buffer\n",
+			NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid());
+	else
+		printk(KERN_ALERT "PAX: %s:%d, uid/euid: %u/%u, attempted to overflow a kernel buffer\n",
+			current->comm, task_pid_nr(current), current_uid(), current_euid());
+	BUG();
+}
+EXPORT_SYMBOL(__chk_fail);
+
+void * __memcpy_chk (void *dstpp, const void* srcpp, size_t len, size_t dstlen)
+{
+	char *d = (char *) dstpp;
+	const char *s = (const char *) srcpp;
+
+	if (unlikely(dstlen < len))
+		__chk_fail ();
+
+        while (len--)
+                *d++ = *s++;
+
+        return d;
+}
+
+EXPORT_SYMBOL(__memcpy_chk);
+
+void * __memmove_chk (void *dstpp, const void* srcpp, size_t len, size_t dstlen)
+{
+	char *d;
+	const char *s;
+
+	if (unlikely(dstlen < len))
+		__chk_fail ();
+
+	if (dstpp <= srcpp) {
+		d = (char *)dstpp;
+		s = (const char *)(srcpp);
+		while (len--)
+			*d++ = *s++;
+	} else {
+		d = (char *)dstpp;
+		d += len;
+		s = (const char *)srcpp;
+		s += len;
+		while (len--)
+			*--d = *--s;
+	}
+
+        return d;
+}
+
+EXPORT_SYMBOL(__memmove_chk);
+
+void * __memset_chk (void *dst, const int c, size_t len, size_t dstlen)
+{
+	char *d = (char *) dst;
+
+	if (unlikely(dstlen < len))
+		__chk_fail ();
+
+        while (len--)
+                *d++ = c;
+
+        return d;
+}
+
+EXPORT_SYMBOL(__memset_chk);
+
+/* Copy SRC to DEST with checking of destination buffer overflow.  */
+char * __strcpy_chk (char *dest, const char *src, size_t destlen)
+{
+  char c;
+  char *s = (char *) src;
+  const ptrdiff_t off = dest - s;
+
+  while (__builtin_expect (destlen >= 4, 0))
+    {
+      c = s[0];
+      s[off] = c;
+      if (c == '\0')
+        return dest;
+      c = s[1];
+      s[off + 1] = c;
+      if (c == '\0')
+        return dest;
+      c = s[2];
+      s[off + 2] = c;
+      if (c == '\0')
+        return dest;
+      c = s[3];
+      s[off + 3] = c;
+      if (c == '\0')
+        return dest;
+      destlen -= 4;
+      s += 4;
+    }
+
+  do
+    {
+      if (__builtin_expect (destlen-- == 0, 0))
+        __chk_fail ();
+      c = *s;
+      *(s++ + off) = c;
+    }
+  while (c != '\0');
+
+  return dest;
+}
+
+EXPORT_SYMBOL(__strcpy_chk);
+
+
+char * __strcat_chk (char *dest, const char *src, size_t destlen)
+{
+  char *s1 = dest;
+  const char *s2 = src;
+  char c;
+
+  /* Find the end of the string.  */
+  do
+    {
+      if (__builtin_expect (destlen-- == 0, 0))
+        __chk_fail ();
+      c = *s1++;
+    }
+  while (c != '\0');
+
+  /* Make S1 point before the next character, so we can increment
+     it while memory is read (wins on pipelined cpus).  */
+  ++destlen;
+  s1 -= 2;
+
+  do
+    {
+      if (__builtin_expect (destlen-- == 0, 0))
+        __chk_fail ();
+      c = *s2++;
+      *++s1 = c;
+    }
+  while (c != '\0');
+
+  return dest;
+}
+
+EXPORT_SYMBOL(__strcat_chk);
+
+char * __strncat_chk (char *s1, const char *s2, size_t n, size_t s1len)
+{
+  char c;
+  char *s = s1;
+
+  /* Find the end of S1.  */
+  do
+    {
+      if (__builtin_expect (s1len-- == 0, 0))
+	__chk_fail ();
+      c = *s1++;
+    }
+  while (c != '\0');
+
+  /* Make S1 point before next character, so we can increment
+     it while memory is read (wins on pipelined cpus).  */
+  ++s1len;
+  s1 -= 2;
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+      do
+	{
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	} while (--n4 > 0);
+      n &= 3;
+    }
+
+  while (n > 0)
+    {
+      if (__builtin_expect (s1len-- == 0, 0))
+	__chk_fail ();
+      c = *s2++;
+      *++s1 = c;
+      if (c == '\0')
+	return s;
+      n--;
+    }
+
+  if (c != '\0')
+    {
+      if (__builtin_expect (s1len-- == 0, 0))
+	__chk_fail ();
+      *++s1 = '\0';
+    }
+
+  return s;
+}
+
+EXPORT_SYMBOL(__strncat_chk);
+
+
+char * __strncpy_chk (char *s1, const char *s2, size_t n, size_t s1len)
+{
+  char c;
+  char *s = s1;
+
+  if (__builtin_expect (s1len < n, 0))
+    __chk_fail ();
+
+  --s1;
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+
+      for (;;)
+	{
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  if (--n4 == 0)
+	    goto last_chars;
+	}
+      n = n - (s1 - s) - 1;
+      if (n == 0)
+	return s;
+      goto zero_fill;
+    }
+
+ last_chars:
+  n &= 3;
+  if (n == 0)
+    return s;
+
+  do
+    {
+      c = *s2++;
+      *++s1 = c;
+      if (--n == 0)
+	return s;
+    }
+  while (c != '\0');
+
+ zero_fill:
+  do
+    *++s1 = '\0';
+  while (--n > 0);
+
+  return s;
+}
+
+EXPORT_SYMBOL(__strncpy_chk);
+
+int
+__vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen, const char *format, va_list args)
+{
+	if (__builtin_expect (slen < maxlen, 0))
+		__chk_fail ();
+
+	return __builtin___vsnprintf_chk (s, maxlen, 0, -1, format, args);
+}
+
+EXPORT_SYMBOL(__vsnprintf_chk);
+
+int
+__vsprintf_chk (char *s, int flags, size_t slen, const char *format, va_list args)
+{
+	if (slen == 0)
+		__chk_fail ();
+	return __vsnprintf_chk(s, INT_MAX, flags, slen, format, args);
+}
+
+EXPORT_SYMBOL(__vsprintf_chk);
+
+int
+__sprintf_chk (char *s, int flags, size_t slen, const char *format, ...)
+{
+	va_list arg;
+	int done;
+
+	va_start (arg, format);
+	done = __vsprintf_chk (s, flags, slen, format, arg);
+	va_end (arg);
+
+	return done;
+}
+
+EXPORT_SYMBOL(__sprintf_chk);
+
+int
+__snprintf_chk (char *s, size_t maxlen, int flags, size_t slen, const char *format, ...)
+{
+	va_list arg;
+	int done;
+
+	va_start (arg, format);
+	done = __vsnprintf_chk (s, maxlen, flags, slen, format, arg);
+	va_end (arg);
+
+	return done;
+}
+
+EXPORT_SYMBOL(__snprintf_chk);
+
+void *kmalloc(size_t size, gfp_t flags)
+{
+	return __fortify_kmalloc(size, flags);
+}
+
+EXPORT_SYMBOL(kmalloc);
+
+void *kcalloc(size_t n, size_t size, gfp_t flags)
+{
+	return __fortify_kcalloc(n, size, flags);
+}
+
+EXPORT_SYMBOL(kcalloc);
+
+#ifdef CONFIG_NUMA
+void *kmalloc_node(size_t size, gfp_t flags, int node)
+{
+	return __fortify_kmalloc_node(size, flags, node);
+}
+
+EXPORT_SYMBOL(kmalloc_node);
+
+#endif
+
+void *get_zeroed_page_chk(size_t size, gfp_t flags)
+{
+	return (void *)get_zeroed_page(flags);
+}
+
+EXPORT_SYMBOL(get_zeroed_page_chk);
only in patch2:
unchanged:
--- linux-2.6.29.4/lib/Makefile	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/lib/Makefile	2009-05-27 03:09:46.000000000 -0400
@@ -44,6 +44,7 @@ obj-$(CONFIG_PLIST) += plist.o
 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
 obj-$(CONFIG_DEBUG_LIST) += list_debug.o
 obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o
+lib-$(CONFIG_PAX_FORTIFY_SOURCE) += fortify.o
 
 ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
   lib-y += dec_and_lock.o
only in patch2:
unchanged:
--- linux-2.6.29.4/lib/string.c	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/lib/string.c	2009-05-31 11:48:48.000000000 -0400
@@ -95,7 +95,7 @@ EXPORT_SYMBOL(strncasecmp);
  * @src: Where to copy the string from
  */
 #undef strcpy
-char *strcpy(char *dest, const char *src)
+char * __attribute__((weak)) strcpy(char *dest, const char *src)
 {
 	char *tmp = dest;
 
@@ -120,7 +120,8 @@ EXPORT_SYMBOL(strcpy);
  * count, the remainder of @dest will be padded with %NUL.
  *
  */
-char *strncpy(char *dest, const char *src, size_t count)
+#undef strncpy
+char * __attribute__((weak)) strncpy(char *dest, const char *src, size_t count)
 {
 	char *tmp = dest;
 
@@ -168,7 +169,7 @@ EXPORT_SYMBOL(strlcpy);
  * @src: The string to append to it
  */
 #undef strcat
-char *strcat(char *dest, const char *src)
+char * __attribute__((weak)) strcat(char *dest, const char *src)
 {
 	char *tmp = dest;
 
@@ -191,7 +192,8 @@ EXPORT_SYMBOL(strcat);
  * Note that in contrast to strncpy(), strncat() ensures the result is
  * terminated.
  */
-char *strncat(char *dest, const char *src, size_t count)
+#undef strncat
+char * __attribute__((weak)) strncat(char *dest, const char *src, size_t count)
 {
 	char *tmp = dest;
 
@@ -529,6 +531,7 @@ EXPORT_SYMBOL(sysfs_streq);
  *
  * Do not use memset() to access IO space, use memset_io() instead.
  */
+#undef memset
 void *memset(void *s, int c, size_t count)
 {
 	char *xs = s;
@@ -550,6 +553,7 @@ EXPORT_SYMBOL(memset);
  * You should not use this function to access IO space, use memcpy_toio()
  * or memcpy_fromio() instead.
  */
+#undef memcpy
 void *memcpy(void *dest, const void *src, size_t count)
 {
 	char *tmp = dest;
@@ -571,6 +575,7 @@ EXPORT_SYMBOL(memcpy);
  *
  * Unlike memcpy(), memmove() copes with overlapping areas.
  */
+#undef memmove
 void *memmove(void *dest, const void *src, size_t count)
 {
 	char *tmp;
only in patch2:
unchanged:
--- linux-2.6.29.4/lib/vsprintf.c	2009-05-08 18:47:21.000000000 -0400
+++ linux-2.6.29.4-devel/lib/vsprintf.c	2009-05-31 15:26:02.000000000 -0400
@@ -723,7 +723,9 @@ static char *pointer(const char *fmt, ch
  * Call this function if you are already dealing with a va_list.
  * You probably want snprintf() instead.
  */
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
+
+#undef vsnprintf
+int __attribute__((weak)) vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 {
 	unsigned long long num;
 	int base;
@@ -978,7 +980,8 @@ EXPORT_SYMBOL(vscnprintf);
  *
  * See the vsnprintf() documentation for format string extensions over C99.
  */
-int snprintf(char * buf, size_t size, const char *fmt, ...)
+#undef snprintf
+int __attribute__((weak)) snprintf(char * buf, size_t size, const char *fmt, ...)
 {
 	va_list args;
 	int i;
@@ -1028,7 +1031,8 @@ EXPORT_SYMBOL(scnprintf);
  *
  * See the vsnprintf() documentation for format string extensions over C99.
  */
-int vsprintf(char *buf, const char *fmt, va_list args)
+#undef vsprintf
+int __attribute__((weak)) vsprintf(char *buf, const char *fmt, va_list args)
 {
 	return vsnprintf(buf, INT_MAX, fmt, args);
 }
@@ -1046,7 +1050,8 @@ EXPORT_SYMBOL(vsprintf);
  *
  * See the vsnprintf() documentation for format string extensions over C99.
  */
-int sprintf(char * buf, const char *fmt, ...)
+#undef sprintf
+int __attribute__((weak)) sprintf(char * buf, const char *fmt, ...)
 {
 	va_list args;
 	int i;
