File: cipher/primegen.c
Function: prime_generate_internal
Line of error:642-645
Resource leak occurs as certain variables with assigned memories, are not freed
at required locations which causes memory leak.
Libgcrypt version 1.6.1 code:
if (g) { /* Create a generator (start with 3). */ gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime)); gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime)); gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime)); if (need_q_factor) err = GPG_ERR_NOT_IMPLEMENTED; else { factors[n] = q; factors[n + 1] = mpi_alloc_set_ui (2);
->The variables tmp , b, pmin1 are allocated memory outside "else" section and
are freed inside else section which may lead to resource leak in cases where
code flow doesn't goes into else section.
And Since these variables are used only inside the else section so there
declaration and defination can exists within else and all chances of leak would
be removed.
Recommended Code:
if (g) { if (need_q_factor) err = GPG_ERR_NOT_IMPLEMENTED; else { gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime)); gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime)); gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime)); factors[n] = q; factors[n + 1] = mpi_alloc_set_ui (2); mpi_sub_ui (pmin1, prime, 1);
Function: _gcry_prime_group_generator
Line: 1215 and 1221
Libgcrypt Version 1.6.1 code:
gcry_mpi_t tmp = mpi_new (0);
gcry_mpi_t b = mpi_new (0); gcry_mpi_t pmin1 = mpi_new (0); gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); int first = 1; int i, n; if (!factors || !r_g || !prime) return GPG_ERR_INV_ARG; *r_g = NULL; for (n=0; factors[n]; n++) ; if (n < 2) return GPG_ERR_INV_ARG;
-> the variables tmp , b, g , pmin1 should be freed before the two return's
Recommended Code:
gcry_mpi_t tmp = mpi_new (0);
gcry_mpi_t b = mpi_new (0); gcry_mpi_t pmin1 = mpi_new (0); gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); gcry_err_code_t err = 0; int first = 1; int i, n; if (!factors || !r_g || !prime) { err= GPG_ERR_INV_ARG; goto leave; } *r_g = NULL; for (n=0; factors[n]; n++) ; if (n < 2) { err= GPG_ERR_INV_ARG; goto leave; }
The code within label leave-:
leave:
_gcry_mpi_release (tmp); _gcry_mpi_release (b); _gcry_mpi_release (pmin1); if (err) { _gcry_mpi_release (g); return err; } *r_g = g; return 0;
I am attaching a patch "primegen.patch" for the above mentioned bugs, it may
give a much clear picture and resolution.