[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