Uninitialised memory after mpn_sec_tabselect on i686
Mike Crowe
mac at mcrowe.com
Mon Jul 21 18:04:01 CEST 2025
I'm having some trouble with Valgrind reporting use of uninitialised memory
from code using gnutls on 32-bit x86 and I believe that I have narrowed the
problem down to the x86 asm version of mpn_sec_tabselect.
The problem goes away if I configure gmp with --disable-assembly.
If I insert VALGRIND_CHECK_MEM_IS_DEFINED(rp, n) immediately after the call
to mpn_sec_tabselect (rp, pp, n, 1 << windowsize, expbits) in mpn_sec_powm
(sec_powm.c:353) then I get:
==2458744== Uninitialised byte(s) found during client check request
==2458744== at 0x56A86D7: __gmpn_sec_powm (sec_powm.c:353)
==2458744== by 0x7AFDD07: rsa_sec_blind (rsa-sign-tr.c:201)
==2458744== by 0x7AFDD07: _nettle_rsa_sec_compute_root_tr (rsa-sign-tr.c:336)
==2458744== by 0x7AFE0DA: nettle_rsa_compute_root_tr (rsa-sign-tr.c:377)
==2458744== by 0x7AFE70A: nettle_rsa_pkcs1_sign_tr (rsa-pkcs1-sign-tr.c:56)
==2458744== by 0x5A35160: _wrap_nettle_pk_sign (pk.c:1616)
==2458744== by 0x5998AB3: privkey_sign_and_hash_data (privkey.c:1344)
==2458744== by 0x5998D96: gnutls_privkey_sign_data2 (privkey.c:1235)
==2458744== by 0x59857DC: _gnutls_check_key_cert_match (cert-cred.c:1031)
==2458744== by 0x5992476: gnutls_certificate_set_x509_key_mem2 (cert-cred-x509.c:678)
...
==2458744== Address 0xa427374 is 4 bytes inside a block of size 512 alloc'd
==2458744== at 0x4E11616: malloc (vg_replace_malloc.c:446)
==2458744== by 0x56718EF: __gmp_default_allocate (memory.c:53)
==2458744== by 0x7B02CEE: _nettle_gmp_alloc (gmp-glue.c:310)
==2458744== by 0x7AFDB0A: _nettle_rsa_sec_compute_root_tr (rsa-sign-tr.c:332)
==2458744== by 0x7AFE0DA: nettle_rsa_compute_root_tr (rsa-sign-tr.c:377)
==2458744== by 0x7AFE70A: nettle_rsa_pkcs1_sign_tr (rsa-pkcs1-sign-tr.c:56)
==2458744== by 0x5A35160: _wrap_nettle_pk_sign (pk.c:1616)
==2458744== by 0x5998AB3: privkey_sign_and_hash_data (privkey.c:1344)
==2458744== by 0x5998D96: gnutls_privkey_sign_data2 (privkey.c:1235)
==2458744== by 0x59857DC: _gnutls_check_key_cert_match (cert-cred.c:1031)
==2458744== by 0x5992476: gnutls_certificate_set_x509_key_mem2 (cert-cred-x509.c:678)
...
==2458744== Uninitialised value was created by a heap allocation
==2458744== at 0x4E11616: malloc (vg_replace_malloc.c:446)
==2458744== by 0x56718EF: __gmp_default_allocate (memory.c:53)
==2458744== by 0x7B02CEE: _nettle_gmp_alloc (gmp-glue.c:310)
==2458744== by 0x7AFDB0A: _nettle_rsa_sec_compute_root_tr (rsa-sign-tr.c:332)
==2458744== by 0x7AFE0DA: nettle_rsa_compute_root_tr (rsa-sign-tr.c:377)
==2458744== by 0x7AFE70A: nettle_rsa_pkcs1_sign_tr (rsa-pkcs1-sign-tr.c:56)
==2458744== by 0x5A35160: _wrap_nettle_pk_sign (pk.c:1616)
==2458744== by 0x5998AB3: privkey_sign_and_hash_data (privkey.c:1344)
==2458744== by 0x5998D96: gnutls_privkey_sign_data2 (privkey.c:1235)
==2458744== by 0x59857DC: _gnutls_check_key_cert_match (cert-cred.c:1031)
==2458744== by 0x5992476: gnutls_certificate_set_x509_key_mem2 (cert-cred-x509.c:678)
I believe that the following simple program, when built and run against gmp
6.3.0 or r18486:f1c983debf6c on Debian 12 configured with
--host=i686-my-linux might show the same problem in a simpler way:
--8<--
#include <gmp.h>
#include <stdio.h>
int main()
{
mpz_t rop, base, exp, mod;
mpz_init(rop);
mpz_init(base);
mpz_init(exp);
mpz_init(mod);
mpz_set_si(base, 10);
mpz_set_si(exp, 63);
mpz_set_si(mod, 65537);
mpz_powm_sec(rop, base, exp, mod);
mpz_out_str(stdout, 10, rop);
putchar('\n');
return 0;
}
-->8--
The valgrind 3.25.1 output from this program is:
==43680== Conditional jump or move depends on uninitialised value(s)
==43680== at 0x487707B: __gmpz_powm_sec (powm_sec.c:88)
==43680== by 0x4001124: main (reproduce.c:14)
==43680==
==43680== Conditional jump or move depends on uninitialised value(s)
==43680== at 0x4887B6F: mpn_bc_get_str (get_str.c:239)
==43680== by 0x4887F8B: __gmpn_get_str (get_str.c:430)
==43680== by 0x4876300: __gmpz_out_str (out_str.c:93)
==43680== by 0x4001137: main (reproduce.c:15)
==43680==
==43680== Conditional jump or move depends on uninitialised value(s)
==43680== at 0x4887B9C: mpn_bc_get_str (get_str.c:239)
==43680== by 0x4887F8B: __gmpn_get_str (get_str.c:430)
==43680== by 0x4876300: __gmpz_out_str (out_str.c:93)
==43680== by 0x4001137: main (reproduce.c:15)
==43680==
==43680== Use of uninitialised value of size 4
==43680== at 0x487631E: __gmpz_out_str (out_str.c:97)
==43680== by 0x4001137: main (reproduce.c:15)
==43680==
though Debian 12's valgrind 3.19 also reports the same. If, as before, I
insert the same VALGRIND_CHECK_MEM_IS_DEFINED(rp, n) call immediately after
the call to mpn_sec_tabselect (rp, pp, n, 1 << windowsize, expbits) in
mpn_sec_powm (sec_powm.c:350) then it fires:
==50688== Uninitialised byte(s) found during client check request
==50688== at 0x48AB003: __gmpn_sec_powm (sec_powm.c:350)
I do not see this problem when using Debian 12's gmp-6.2.1.
Is this a real bug?
Thanks.
Mike.
More information about the gmp-discuss
mailing list