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);
 }
 

Reply via email to