Replace deliberate division by zero with _gcry_divide_by_zero.
authorXi Wang <xi.wang@gmail.com>
Tue, 14 Aug 2012 22:54:40 +0000 (18:54 -0400)
committerWerner Koch <wk@gnupg.org>
Thu, 16 Aug 2012 08:48:03 +0000 (10:48 +0200)
* 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.

mpi/mpi-pow.c
mpi/mpih-div.c
src/g10lib.h
src/misc.c

index 33bbebe..891a7e6 100644 (file)
@@ -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)
     {
index 224b810..b33dcbf 100644 (file)
@@ -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:
        {
index ec86c97..c580c08 100644 (file)
@@ -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);
index 17bd546..ed72ed6 100644 (file)
@@ -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");
+}