Page MenuHome GnuPG

Memory leak in BER decoder tree expansion
Closed, ResolvedPublic

Description

Reported by: Francisco Tacliad


Severity: Low
CWE: CWE-401 (Missing Release of Memory after Effective Lifetime)
Location: src/asn1-func.c, do_expand_tree(), line 1145
Trigger: Crafted binary input to _ksba_derdn_to_str()

This is a SEPARATE finding from Finding 1, triggered through a
different code path (DER-to-string conversion, not string-to-DER).

When do_expand_tree() processes certain crafted ASN.1 structures,
allocated tree nodes are not freed on the error path. The fuzzer
found one input (starting with "C=" followed by binary data) that
leaks 556 bytes across 10 allocations per invocation.

LeakSanitizer trace:

Indirect leak of 176 byte(s) in 2 object(s) allocated from:
    #0 malloc
    #1 _ksba_malloc        src/util.c:130:10
    #2 _ksba_xmalloc       src/util.c:238:13
    #3 do_expand_tree       src/asn1-func.c:1145:15
    #4 do_expand_tree       src/asn1-func.c:1208:14 (recursive)
    ...
    #8 decoder_init         src/ber-decoder.c:809:13
    #9 create_and_run_decoder  src/dn.c:612:9
    #10 _ksba_derdn_to_str  src/dn.c:639:9

Impact: In a long-running process (gpg-agent, dirmngr), repeated
processing of crafted certificates could gradually exhaust memory.

Reproducer: Available on request (33-byte binary input).

Event Timeline

werner created this task.
werner created this object in space Restricted Space.
werner created this object with edit policy "Contributor (Project)".
werner updated the task description. (Show Details)

I found a possible leak and a possible access of freed memory.

diff --git a/src/ber-decoder.c b/src/ber-decoder.c
index fe8eb87..9adb3c0 100644
--- a/src/ber-decoder.c
+++ b/src/ber-decoder.c
@@ -1328,7 +1328,10 @@ _ksba_ber_decoder_decode (BerDecoder d, const char *start_name,
     err = 0;
 
   if (err)
-    xfree (d->image.buf);
+    {
+      xfree (d->image.buf);
+      d->image.buf = NULL;
+    }
 
   if (r_root && !err)
     {
@@ -1351,6 +1354,11 @@ _ksba_ber_decoder_decode (BerDecoder d, const char *start_name,
           _ksba_asn_node_dump_all (*r_root, stderr);
         }
     }
+  else
+    {
+      _ksba_asn_release_nodes (d->root);
+      d->root = NULL;
+    }
 
   decoder_deinit (d);
   xfree (buf);
gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Feb 23, 4:04 AM
werner shifted this object from the Restricted Space space to the S1 Public space.