about summary refs log tree commit diff
path: root/setjmp
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-05-15 19:28:04 -0700
committerUlrich Drepper <drepper@redhat.com>2009-05-15 19:37:13 -0700
commitb50f8e42ba3010f0141e6a482e0820f658e89b63 (patch)
tree80cef469731d5857499883d45fd3424730f0db7c /setjmp
parentf1342e0be8e222dbca077beca94b5937564e8c4b (diff)
downloadglibc-b50f8e42ba3010f0141e6a482e0820f658e89b63.tar.gz
glibc-b50f8e42ba3010f0141e6a482e0820f658e89b63.tar.xz
glibc-b50f8e42ba3010f0141e6a482e0820f658e89b63.zip
Check for valid stack frame in longjmp.
If longjmp restores the stack frame to an address which is beyond
the stack frame at the time of the longjmp call it would install
an uninitialized stack frame.  If compiled with _FORTIFY_SOURCE
defined, longjmp will now bail out in this situation.
Diffstat (limited to 'setjmp')
-rw-r--r--setjmp/Makefile4
-rw-r--r--setjmp/bits/setjmp2.h41
-rw-r--r--setjmp/longjmp.c5
-rw-r--r--setjmp/setjmp.h8
4 files changed, 54 insertions, 4 deletions
diff --git a/setjmp/Makefile b/setjmp/Makefile
index b94370d858..509c1d9a0c 100644
--- a/setjmp/Makefile
+++ b/setjmp/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
+# Copyright (C) 1991, 92, 93, 94, 95, 97, 2009 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -21,7 +21,7 @@
 #
 subdir	:= setjmp
 
-headers	:= setjmp.h bits/setjmp.h
+headers	:= setjmp.h bits/setjmp.h bits/setjmp2.h
 
 routines	:= setjmp sigjmp bsd-setjmp bsd-_setjmp \
 		   longjmp __longjmp jmp-unwind
diff --git a/setjmp/bits/setjmp2.h b/setjmp/bits/setjmp2.h
new file mode 100644
index 0000000000..ba900b8d03
--- /dev/null
+++ b/setjmp/bits/setjmp2.h
@@ -0,0 +1,41 @@
+/* Checking macros for setjmp functions.
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * The GNU C Library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.  */
+
+#ifndef _SETJMP_H
+# error "Never include <bits/setjmp2.h> directly; use <setjmp.h> instead."
+#endif
+
+/* Variant of the longjmp functions which perform some sanity checking.  */
+#ifdef __REDIRECT_NTH
+extern void __REDIRECT_NTH (longjmp,
+			    (struct __jmp_buf_tag __env[1], int __val),
+			    __longjmp_chk) __attribute__ ((__noreturn__));
+extern void __REDIRECT_NTH (_longjmp,
+			    (struct __jmp_buf_tag __env[1], int __val),
+			    __longjmp_chk) __attribute__ ((__noreturn__));
+extern void __REDIRECT_NTH (siglongjmp,
+			    (struct __jmp_buf_tag __env[1], int __val),
+			    __longjmp_chk) __attribute__ ((__noreturn__));
+#else
+extern void __longjmp_chk (struct __jmp_buf_tag __env[1], int __val),
+     __THROW __attribute__ ((__noreturn__));
+# define longjmp __longjmp_chk
+# define _longjmp __longjmp_chk
+# define siglongjmp __longjmp_chk
+#endif
diff --git a/setjmp/longjmp.c b/setjmp/longjmp.c
index 9b1bda1caa..8545b36627 100644
--- a/setjmp/longjmp.c
+++ b/setjmp/longjmp.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,92,94,95,97,98,2000,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,94,95,97,98,2000,2002,2009
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -39,8 +40,10 @@ __libc_siglongjmp (sigjmp_buf env, int val)
   __longjmp (env[0].__jmpbuf, val ?: 1);
 }
 
+#ifndef __libc_siglongjmp
 strong_alias (__libc_siglongjmp, __libc_longjmp)
 libc_hidden_def (__libc_longjmp)
 weak_alias (__libc_siglongjmp, _longjmp)
 weak_alias (__libc_siglongjmp, longjmp)
 weak_alias (__libc_siglongjmp, siglongjmp)
+#endif
diff --git a/setjmp/setjmp.h b/setjmp/setjmp.h
index 6b1037fabd..3bc382ff1e 100644
--- a/setjmp/setjmp.h
+++ b/setjmp/setjmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1999, 2001, 2002, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1999,2001,2002,2007,2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -111,6 +111,12 @@ extern void siglongjmp (sigjmp_buf __env, int __val)
      __THROW __attribute__ ((__noreturn__));
 #endif /* Use POSIX.  */
 
+
+/* Define helper functions to catch unsafe code.  */
+#if __USE_FORTIFY_LEVEL > 0
+# include <bits/setjmp2.h>
+#endif
+
 __END_DECLS
 
 #endif /* setjmp.h  */