Invalid read in mpz_sub

Miha Marolt miham at beyondsemi.com
Wed Apr 6 11:58:41 UTC 2016


Hello,

In some cases a previously freed memory is read inside the mpz_sub function. Here is
an example program that demonstrates the problem:

```
#include <gmp.h>


typedef struct {
     mpz_t a;
     mpz_t b;
} pair_t;


void pair_sub(pair_t *out, pair_t in)
{
     // Description of the problem:
     // Given the arguments &x and x (see main function) out->a->_mp_d and
     // in.a->_mp_d point to the same memory.  
     // Inside the mpz_sub function out->a->_mp_d gets reallocated, but in.a->_mp_d
     // stays the same (now pointing to invalid memory) because in.a and out->a are
     //not the same object.
     mpz_sub(out->a, in.b, in.a);
}


int main(void)
{
     mpz_t a, b;
     mpz_init_set_str(a, "10", 0);
     mpz_init_set_str(b, "20", 0);

     pair_t x;
     mpz_inits(x.a, x.b, NULL);
     mpz_set(x.a, a); // x.a: _mp_size == _mp_alloc.
     mpz_set(x.b, b); // x.b: _mp_size == _mp_alloc.

     pair_sub(&x, x);

     mpz_clears(a, b, x.a, x.b, NULL);
}
```

Compile it with `$ gcc main.c -o main -lgmp` and run under Valgrind with
`$ valgrind --leak-check=full --show-leak-kinds=all ./main`. Valgrind reports
invalid reads:

```
==14174== Memcheck, a memory error detector
==14174== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14174== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==14174== Command: ./e_bug_mpz_sub
==14174==
==14174== Invalid read of size 8
==14174==    at 0x4E57AB0: UnknownInlinedFun (gmp.h:2155)
==14174==    by 0x4E57AB0: __gmpz_sub (aors.h:96)
==14174==    by 0x400808: pair_sub (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==    by 0x4008A2: main (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==  Address 0x546e180 is 0 bytes inside a block of size 8 free'd
==14174==    at 0x4C2AB8B: realloc (vg_replace_malloc.c:785)
==14174==    by 0x4E41803: __gmp_default_reallocate (memory.c:102)
==14174==    by 0x4E560C9: __gmpz_realloc (realloc.c:61)
==14174==    by 0x4E57BA0: __gmpz_sub (aors.h:76)
==14174==    by 0x400808: pair_sub (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==    by 0x4008A2: main (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==  Block was alloc'd at
==14174==    at 0x4C28BF6: malloc (vg_replace_malloc.c:299)
==14174==    by 0x4E417B8: __gmp_default_allocate (memory.c:54)
==14174==    by 0x4E50327: __gmpz_init (init.c:38)
==14174==    by 0x4E50429: __gmpz_inits (inits.c:45)
==14174==    by 0x400860: main (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==
==14174== Invalid read of size 8
==14174==    at 0x4E5C69E: __gmpn_sub_n (tmp-sub_n.s:116)
==14174==    by 0x4E57ADD: __gmpz_sub (aors.h:106)
==14174==    by 0x400808: pair_sub (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==    by 0x4008A2: main (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==  Address 0x546e180 is 0 bytes inside a block of size 8 free'd
==14174==    at 0x4C2AB8B: realloc (vg_replace_malloc.c:785)
==14174==    by 0x4E41803: __gmp_default_reallocate (memory.c:102)
==14174==    by 0x4E560C9: __gmpz_realloc (realloc.c:61)
==14174==    by 0x4E57BA0: __gmpz_sub (aors.h:76)
==14174==    by 0x400808: pair_sub (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==    by 0x4008A2: main (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==  Block was alloc'd at
==14174==    at 0x4C28BF6: malloc (vg_replace_malloc.c:299)
==14174==    by 0x4E417B8: __gmp_default_allocate (memory.c:54)
==14174==    by 0x4E50327: __gmpz_init (init.c:38)
==14174==    by 0x4E50429: __gmpz_inits (inits.c:45)
==14174==    by 0x400860: main (in /home/miha/coding/ssike/src/examples/e_bug_mpz_sub)
==14174==
==14174==
==14174== HEAP SUMMARY:
==14174==     in use at exit: 0 bytes in 0 blocks
==14174==   total heap usage: 7 allocs, 7 frees, 80 bytes allocated
==14174==
==14174== All heap blocks were freed -- no leaks are possible
==14174==
==14174== For counts of detected and suppressed errors, rerun with: -v
==14174== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
```

Versions of used components:

  * GMP 6.0.0 from the Fedora 23 repositories.
  * GCC 5.3.1 from the Fedora 23 repositories.

Verbose GCC version:

```
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
```

Output of `$ uname -a`:

```
Linux ariel 4.4.6-300.fc23.x86_64 #1 SMP Wed Mar 16 22:10:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
```

Output of `$ ./config.guess`:

```
nehalem-pc-linux-gnu
```

Best regards,
Miha Marolt


More information about the gmp-bugs mailing list