[PATCH 2/2] Make _gcry_burn_stack use variable length array

Jussi Kivilinna jussi.kivilinna at iki.fi
Tue Sep 3 19:18:29 CEST 2013


* configure.ac (HAVE_VLA): Add check.
* src/misc.c (_gcry_burn_stack) [HAVE_VLA]: Add VLA code.
--

Some gcc versions convert _gcry_burn_stack into loop that overwrites the same
64-byte stack buffer instead of burn stack deeper. It's mentioned in GCC
bugzilla that _gcry_burn_stack is doing wrong thing here [1] and that this
kind of optimization is allowed.

So lets fix _gcry_burn_stack by using variable length array when VLAs are
supported by compiler. This should ensure proper stack burning to the requested
depth and avoid GCC loop optimizations.

[1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52285

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 configure.ac |   18 ++++++++++++++++++
 src/misc.c   |    7 +++++++
 2 files changed, 25 insertions(+)

diff --git a/configure.ac b/configure.ac
index 959327a..993577b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -764,6 +764,24 @@ case "${host}" in
 esac
 AC_SUBST(FALLBACK_SOCKLEN_T)
 
+
+#
+# Check for VLA support (variable length arrays).
+#
+AC_CACHE_CHECK(whether the variable length arrays are supported,
+       [gcry_cv_have_vla],
+       [gcry_cv_have_vla=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void f1(char *, int);
+            char foo(int i) {
+              char b[(i < 0 ? 0 : i) + 1];
+              f1(b, sizeof b); return b[0];}]])],
+          [gcry_cv_have_vla=yes])])
+if test "$gcry_cv_have_vla" = "yes" ; then
+   AC_DEFINE(HAVE_VLA,1, [Defined if variable length arrays are supported])
+fi
+
+
 #
 # Check for ELF visibility support.
 #
diff --git a/src/misc.c b/src/misc.c
index 2d9c73a..97de322 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -290,6 +290,12 @@ _gcry_log_printhex (const char *text, const void *buffer, size_t length)
 void
 _gcry_burn_stack (int bytes)
 {
+#ifdef HAVE_VLA
+    int buflen = (((bytes <= 0) ? 1 : bytes) + 63) & ~63;
+    char buf[buflen];
+
+    wipememory (buf, sizeof buf);
+#else
     char buf[64];
 
     wipememory (buf, sizeof buf);
@@ -297,6 +303,7 @@ _gcry_burn_stack (int bytes)
     bytes -= sizeof buf;
     if (bytes > 0)
         _gcry_burn_stack (bytes);
+#endif
 }
 
 void




More information about the Gcrypt-devel mailing list