Hi Daiki, Daiki Ueno <u...@gnu.org> skribis:
> Ludovic Courtès <l...@gnu.org> writes: > >> This is because Guile >= 3.0.1 and >= 2.2.7 changes the GMP allocation >> functions such that they go through libgc¹. As a result, libgc may >> reuse that memory when it becomes unreachable from its point of view; in >> this case, since GnuTLS structures are not scanned by libgc, libgc >> doesn’t “see” pointers to those bignums and thus considers they are no >> longer reachable. > > That's interesting, though I might not follow completely. > >> • In Guile-GnuTLS, arrange so that GnuTLS allocations are made through >> libgc. Unfortunately, ‘gnutls_global_set_mem_functions’ was >> deprecated in GnuTLS 3.3.0 so this doesn’t look like an option. > > GnuTLS doesn't call mp_set_memory_functions, so even if it is possible, > I doubt that it would affect the current behavior. What happens currently is that data structures allocated by GnuTLS are not scanned by the GC; thus, when those data structures refer to an ‘mpz_t’, the GC doesn’t “see” those references. If we could arrange so that GnuTLS allocates via libgc, those ‘mpz_t’ references would become visible to the GC, which would solve this issue. Would it be an option? > On the other hand, if GnuTLS (or Nettle) internally allocates an > mpz_t, it should be done using the libgc-backed allocator set by Guile > and the pointers should be reachable until it is no longer, if I > understand correctly. Therefore, I suspect that there might be some > code that confuses libgc to track the pointers; one thing that comes > to my mind is a manual copy of mpz_t values: > https://gitlab.com/gnutls/gnutls/-/blob/master/lib/nettle/pk.c#L141 > > If you replace memcpy with mpz_init_set, does it work? I tried the patch below but it doesn’t help. Thanks for taking a look! Ludo’.
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 588e9df502..fc4d50db44 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -138,7 +138,7 @@ _dsa_params_get(const gnutls_pk_params_st * pk_params, memcpy(pub->p, pk_params->params[DSA_P], SIZEOF_MPZT); if (pk_params->params[DSA_Q]) - memcpy(&pub->q, pk_params->params[DSA_Q], SIZEOF_MPZT); + mpz_init_set(pub->q, pk_params->params[DSA_Q]); memcpy(pub->g, pk_params->params[DSA_G], SIZEOF_MPZT); }