Page MenuHome GnuPG

Resource leak in file "cipher/primegen.c" at line 676 , 1215 and at 1221
Closed, ResolvedPublic

Description

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.

Details

Version
1.6.1

Event Timeline

An no reminders after 3 days please. We are all unpaid volunteers.

ok sir, i will abide by what you say.

Thanks. I appreciate that you look at the code.

Hello, Werner, Kindly have a look at this bug and patch,as and when you are
free. Thanks.

Hello werner,if possible have a look.

Hello werner, a gentle reminder for this bug, have a look, if possible, it has
been over 3 months now.

Sorry for the long delay. Fixed with commit 8c5eee5 for 1.7.

I won't backport it to 1.6 because the leak is only triggered by wrong usage of
the functions.

werner removed a project: Restricted Project.