[PATCH v2] Replace deliberate division by zero with _gcry_divide_by_zero.

Xi Wang xi.wang at gmail.com
Wed Aug 15 00:54:40 CEST 2012


* mpi/mpi-pow.c: Replace 1 / msize.
* mpi/mpih-div.c: Replace 1 / dsize.
* src/misc.c: Add _gcry_divide_by_zero.

1) Division by zero doesn't "provoke a signal" on architectures
   like PowerPC.

2) C compilers like clang will optimize away these divisions, even
   though the code tries "to make the compiler not remove" them.

This patch redirects these cases to _gcry_divide_by_zero.
---
For simplicity, _gcry_divide_by_zero reuses _gcry_fatal_error to
signal an error.

If we really want to do an intentional division by zero, we might
need to replicate most of _gcry_fatal_error in _gcry_divide_by_zero:

  int rc;
  const char *text = "divide by zero";
  volatile int x = 1, y = 0, z;

  gpg_err_set_errno (EDOM);
  rc = gpg_err_code_from_errno (errno);

  if (fatal_error_handler && !fips_mode () )
    fatal_error_handler (fatal_error_handler_value, rc, text);

  fips_signal_fatal_error (text);
  _gcry_secmem_term ();
  z = x / y;
  raise(SIGFPE);
  abort ();
---
 mpi/mpi-pow.c  |    2 +-
 mpi/mpih-div.c |    5 ++---
 src/g10lib.h   |    2 ++
 src/misc.c     |    8 ++++++++
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 33bbebe..891a7e6 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -76,7 +76,7 @@ gcry_mpi_powm (gcry_mpi_t res,
   ep = expo->d;
 
   if (!msize)
-    msize = 1 / msize;	    /* Provoke a signal.  */
+    _gcry_divide_by_zero();
 
   if (!esize)
     {
diff --git a/mpi/mpih-div.c b/mpi/mpih-div.c
index 224b810..b33dcbf 100644
--- a/mpi/mpih-div.c
+++ b/mpi/mpih-div.c
@@ -212,9 +212,8 @@ _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
 
     switch(dsize) {
       case 0:
-	/* We are asked to divide by zero, so go ahead and do it!  (To make
-	   the compiler not remove this statement, return the value.)  */
-	return 1 / dsize;
+	_gcry_divide_by_zero();
+	break;
 
       case 1:
 	{
diff --git a/src/g10lib.h b/src/g10lib.h
index ec86c97..c580c08 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -101,6 +101,8 @@ void _gcry_bug (const char *file, int line);
 void _gcry_assert_failed (const char *expr, const char *file, int line);
 #endif
 
+void _gcry_divide_by_zero (void) JNLIB_GCC_A_NR;
+
 const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
 void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
 void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
diff --git a/src/misc.c b/src/misc.c
index 17bd546..ed72ed6 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -19,6 +19,7 @@
  */
 
 #include <config.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -296,3 +297,10 @@ _gcry_burn_stack (int bytes)
     if (bytes > 0)
         _gcry_burn_stack (bytes);
 }
+
+void
+_gcry_divide_by_zero (void)
+{
+    gpg_err_set_errno (EDOM);
+    _gcry_fatal_error (gpg_err_code_from_errno (errno), "divide by zero");
+}
-- 
1.7.9.5





More information about the Gcrypt-devel mailing list