Re: Upstream patch to remove abort() that occur during memory overflow

2021-06-12 Thread Marco Bodrato

Il 2020-09-13 11:38 t...@gmplib.org ha scritto:

Marco Bodrato  writes:

  With ABI=64 I get:
  16777216 ^ 768614336404564651 = 256

  With ABI=32 I get:
  16777216 ^ 178956971 = 256

  Not a signal, nor an abort, simply an incorrect result :-)

That's undesirable.

I thought we cought overflows also in this difficult a^b case by
(indirectly means of allocation errors).


Yet another...

$ cat provo.c
#include 
#include "gmp.h"

int
main ()
{
  unsigned long b, e;
  mpz_t p;
  mpz_t bz;

  mpz_init (p);
  mpz_init (bz);

  b = 24 * GMP_NUMB_BITS;
  mpz_setbit (bz, b);
  e = ~0UL / 24 + 1;
  mpz_pow_ui (p, bz, e);
  gmp_printf ("(2 ^ %lu) ^ %lu = %Zd\n", b, e, p);

  mpz_clear (bz);
  mpz_clear (p);
}

$ gcc provo.c -lgmp -o provo&& ./provo
(2 ^ 1536) ^ 768614336404564651 = 
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096


And here is a possible patch (for the 6.2 branch):

$ hg diff mpz
diff -r e1fd9db13b47 mpz/n_pow_ui.c
--- a/mpz/n_pow_ui.cTue Dec 22 23:49:51 2020 +0100
+++ b/mpz/n_pow_ui.cSat Jun 12 15:24:36 2021 +0200
@@ -206,11 +206,33 @@

   /* Strip low zero limbs from b. */
   rtwos_limbs = 0;
+#if 1
   for (blimb = *bp; blimb == 0; blimb = *++bp)
 {
   rtwos_limbs += e;
+  if (UNLIKELY (rtwos_limbs < e))
+   {
+ fprintf (stderr, "gmp: overflow in mpz type\n");
+ abort ();
+   }
   bsize--; ASSERT (bsize >= 1);
 }
+#else
+  blimb = *bp;
+  if (blimb == 0)
+{
+  do
+   ++rtwos_limbs;
+  while ((blimb = *++bp) == 0);
+  bsize -= rtwos_limbs; ASSERT (bsize >= 1);
+  umul_ppmm (ovfl, rtwos_limbs, e, rtwos_limbs);
+  if (ovfl)
+   {
+ fprintf (stderr, "gmp: overflow in mpz type\n");
+ abort ();
+   }
+}
+#endif
   TRACE (printf ("trailing zero rtwos_limbs=%ld\n", rtwos_limbs));

   /* Strip low zero bits from b. */

As you can see, I tried two different patches. One adds a (well 
predicted?) branch in the (on average O(1)) loop. The other uses a 
multiplication.


But we should probably consider to add a piece of code, at the beginning 
of the function, estimating the total size of the result, to avoid so 
many spurious checks...


Ĝis,
m
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: Upstream patch to remove abort() that occur during memory overflow

2020-09-13 Thread Torbjörn Granlund
Marco Bodrato  writes:

  With ABI=64 I get:
  16777216 ^ 768614336404564651 = 256

  With ABI=32 I get:
  16777216 ^ 178956971 = 256

  Not a signal, nor an abort, simply an incorrect result :-)

That's undesirable.

I thought we cought overflows also in this difficult a^b case by
(indirectly means of allocation errors).

-- 
Torbjörn
Please encrypt, key id 0xC8601622
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: Upstream patch to remove abort() that occur during memory overflow

2020-09-13 Thread Marco Bodrato

Ciao,

Il 2020-09-03 19:22 ni...@lysator.liu.se ha scritto:

Mustafa Mohamad  writes:

Currently GMP aborts which sends SIGBART and forcibly aborts Julia or 
any linked program. With the above patch,  GMP will instead throw a  
__GMP_ALLOC_OVERFLOW_FUNC

Instead of forcibly aborting


Hi, I understand aborting may be undesirable, but can you provide a bit
more context. How do you handle the callback on overflow? If you 
longjmp

out, how do you arrange so that your mpz variables are in a consistent
state?


I believe that a "safe" mpz type, is anyway difficult to obtain. We may 
say that if the result is outside of the range supported by mpz, the 
behavior is undefined.


Try the following code on a Linux or BSD system.

int
main (int argc, char *argv[])
{
  unsigned long b, e;
  mpz_t p;
  mpz_init (p);

  b = 1;
  b <<= 24;
  e = ~0UL / 24 + 1;

  mpz_ui_pow_ui (p, b, e);

  gmp_printf ("%lu ^ %lu = %Zd", b, e, p);
  mpz_clear (p);

  return 0;
}

With ABI=64 I get:
16777216 ^ 768614336404564651 = 256

With ABI=32 I get:
16777216 ^ 178956971 = 256

Not a signal, nor an abort, simply an incorrect result :-)

Anyway this patch might be a way to give a little bit more control to 
the programs using the library...


Ĝis,
m
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: Upstream patch to remove abort() that occur during memory overflow

2020-09-03 Thread Niels Möller
Mustafa Mohamad  writes:

> Currently GMP aborts which sends SIGBART and forcibly aborts Julia or any 
> linked program. With the above patch,  GMP will instead throw a  
> __GMP_ALLOC_OVERFLOW_FUNC
> Instead of forcibly aborting

Hi, I understand aborting may be undesirable, but can you provide a bit
more context. How do you handle the callback on overflow? If you longjmp
out, how do you arrange so that your mpz variables are in a consistent
state?

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs