diff options
author | Xi Wang <xi.wang@gmail.com> | 2012-08-14 18:54:40 -0400 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2014-08-07 19:32:05 +0200 |
commit | 6c3598f1f6a6f2548b60a31ce3c0dd9885558a4f (patch) | |
tree | a99cd002e12f3bb6c3b7b15ff81d9c0a3ba4dee4 | |
parent | 2c05a943c5183ca7bfc76115abde29c634198bac (diff) | |
download | libgcrypt-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.c | 2 | ||||
-rw-r--r-- | mpi/mpih-div.c | 5 | ||||
-rw-r--r-- | src/g10lib.h | 2 | ||||
-rw-r--r-- | src/misc.c | 8 |
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); @@ -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"); +} |