Skip to content

d2i_ASN1_OBJECT leaks the 'sn' and 'ln' fields of ASN1_OBJECT #14667

@smcpeak

Description

@smcpeak

If a program creates an ASN1_OBJECT using ASN1_OBJECT_create, the resulting object will have dynamically allocated sn and ln fields. If the program then calls d2i_ASN1_OBJECT to repopulate that same object with a new object identifier, the dynamically allocated fields will be leaked:

// Exercise the bug 'leak_sn_and_ln' in 'c2i_ASN1_OBJECT'.
void leak_sn_and_ln()
{
  // Make my own object representing the 'countryName' OID.
  //
  // This creates an object that owns dynamically allocated 'sn' and
  // 'ln' fields.
  ASN1_OBJECT *o =
    ASN1_OBJECT_create(NID_undef, derC+2, sizeof(derC)-2, "C", "countryName");
  print_ASN1_OBJECT(o);

  // Now parse something, reusing 'o'.
  //
  // This does not free the dynamically allocated 'sn' and 'ln' fields,
  // instead simply overwriting them with NULL.
  unsigned char const *p = der1234567;
  CHECK_NZ(d2i_ASN1_OBJECT(&o, &p, sizeof(der1234567)));
  print_ASN1_OBJECT(o);

  // This frees the new object, but the old 'sn' and 'ln' are already
  // lost.
  ASN1_OBJECT_free(o);
}

I have attached a complete program leak_sn_and_ln.c.txt demonstrating the leak (attached as text because GitHub insisted; remove ".txt" extension). When run, it prints:

$ leak_sn_and_ln.exe
countryName
1.2.3.4.5.6.7
[21:34:28]     6 file=crypto/objects/obj_lib.c, line=44, thread=15280, number=12, address=0x1441930
[21:34:28]     7 file=crypto/objects/obj_lib.c, line=47, thread=15280, number=2, address=0x14419b0
14 bytes leaked in 2 chunks
no_leaks: 0

The leak printouts require that OpenSSL be configured with the enable-crypto-mdebug flag before building.

Relatedly, the source code of c2i_ASN1_OBJECT contains this incorrect comment:

    /*
     * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
     * ->ln
     */

This isn't true since, as demonstrated, ASN1_OBJECT_create creates an object that is not part of the predefined OID table (nid_objs) but has non-NULL sn and ln fields.

I have observed this behavior with OpenSSL 1.1.1b and 1.1.1j running on Windows 10, built from source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    branch: 1.1.1Applies to OpenSSL_1_1_1-stable branch (EOL)branch: masterApplies to master branchtriaged: bugThe issue/pr is/fixes a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions