summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXi Wang <xi.wang@gmail.com>2012-08-14 18:54:40 -0400
committerWerner Koch <wk@gnupg.org>2014-08-07 19:32:05 +0200
commit6c3598f1f6a6f2548b60a31ce3c0dd9885558a4f (patch)
treea99cd002e12f3bb6c3b7b15ff81d9c0a3ba4dee4
parent2c05a943c5183ca7bfc76115abde29c634198bac (diff)
downloadlibgcrypt-6c3598f1f6a6f2548b60a31ce3c0dd9885558a4f.tar.gz
Replace deliberate division by zero with _gcry_divide_by_zero.
* 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. (cherry picked from commit 2c54c4da19d3a79e9f749740828026dd41f0521a)
-rw-r--r--mpi/mpi-pow.c2
-rw-r--r--mpi/mpih-div.c5
-rw-r--r--src/g10lib.h2
-rw-r--r--src/misc.c8
4 files changed, 13 insertions, 4 deletions
diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index a63fc6dd..85d6fd8f 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -77,7 +77,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 224b8108..b33dcbfa 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 30706a2b..9e017b1a 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 17bd5467..ed72ed63 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");
+}