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
_______________________________________________
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs

Reply via email to