<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>
GitLab
</title>


<style>img {
max-width: 100%; height: auto;
}
</style>
</head>
<body>
<div class="content">
<div></div>
<h2 dir="auto">
<a id="user-content-description-of-problem" class="anchor" href="#description-of-problem" aria-hidden="true"></a>Description of problem:</h2>
<p dir="auto">A memory leak is reported for <code>gnutls_pkcs11_obj_list_import_url4</code> requesting certificate + private keys.</p>
<p dir="auto">The context looks suspicious:</p>
<pre class="code highlight js-syntax-highlight c" lang="c" v-pre="true"><code><span id="LC1" class="line" lang="c"><span class="n">find_privkeys</span><span class="p">(</span><span class="k">struct</span> <span class="n">pkcs11_session_info</span> <span class="o">*</span><span class="n">sinfo</span><span class="p">,</span></span>
<span id="LC2" class="line" lang="c">             <span class="k">struct</span> <span class="n">ck_token_info</span> <span class="o">*</span><span class="n">tinfo</span><span class="p">,</span> <span class="k">struct</span> <span class="n">find_pkey_list_st</span> <span class="o">*</span><span class="n">list</span><span class="p">)</span></span>
<span id="LC3" class="line" lang="c"><span class="p">{</span></span>
<span id="LC4" class="line" lang="c"><span class="c1">// ...</span></span>
<span id="LC5" class="line" lang="c">       <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">count</span><span class="p">,</span> <span class="n">current</span><span class="p">;</span></span>
<span id="LC6" class="line" lang="c"></span>
<span id="LC7" class="line" lang="c">       <span class="n">current</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></span>
<span id="LC8" class="line" lang="c">       <span class="k">while</span> <span class="p">(</span><span class="n">pkcs11_find_objects</span></span>
<span id="LC9" class="line" lang="c">              <span class="p">(</span><span class="n">sinfo</span><span class="o">-></span><span class="n">module</span><span class="p">,</span> <span class="n">sinfo</span><span class="o">-></span><span class="n">pks</span><span class="p">,</span> <span class="o">&</span><span class="n">ctx</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">&</span><span class="n">count</span><span class="p">)</span> <span class="o">==</span> <span class="n">CKR_OK</span></span>
<span id="LC10" class="line" lang="c">             <span class="o">&&</span> <span class="n">count</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span></span>
<span id="LC11" class="line" lang="c"><span class="c1">// ...</span></span>
<span id="LC12" class="line" lang="c">              <span class="n">_gnutls_buffer_init</span><span class="p">(</span><span class="o">&</span><span class="n">list</span><span class="o">-></span><span class="n">key_ids</span><span class="p">[</span><span class="n">current</span><span class="p">]);</span></span>
<span id="LC13" class="line" lang="c"></span>
<span id="LC14" class="line" lang="c">              <span class="k">if</span> <span class="p">(</span><span class="n">pkcs11_get_attribute_value</span></span>
<span id="LC15" class="line" lang="c">                  <span class="p">(</span><span class="n">sinfo</span><span class="o">-></span><span class="n">module</span><span class="p">,</span> <span class="n">sinfo</span><span class="o">-></span><span class="n">pks</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="n">CKR_OK</span><span class="p">)</span> <span class="p">{</span></span>
<span id="LC16" class="line" lang="c"><span class="c1">// ...</span></span>
<span id="LC17" class="line" lang="c">                      <span class="n">current</span><span class="o">++</span><span class="p">;</span></span>
<span id="LC18" class="line" lang="c">              <span class="p">}</span></span>
<span id="LC19" class="line" lang="c"></span>
<span id="LC20" class="line" lang="c">              <span class="k">if</span> <span class="p">(</span><span class="n">current</span> <span class="o">></span> <span class="n">list</span><span class="o">-></span><span class="n">key_ids_size</span><span class="p">)</span></span>
<span id="LC21" class="line" lang="c">                      <span class="k">break</span><span class="p">;</span></span>
<span id="LC22" class="line" lang="c">      <span class="p">}</span></span>
<span id="LC23" class="line" lang="c"><span class="c1">// ...</span></span>
<span id="LC24" class="line" lang="c"></span>
<span id="LC25" class="line" lang="c">        <span class="c1">// Potential integer underflow if the above loop does not match?</span></span>
<span id="LC26" class="line" lang="c">        <span class="c1">// Potentially loses track of the last element, causing a memleak?</span></span>
<span id="LC27" class="line" lang="c">      <span class="n">list</span><span class="o">-></span><span class="n">key_ids_size</span> <span class="o">=</span> <span class="n">current</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span></span></code></pre>
<h2 dir="auto">
<a id="user-content-version-of-gnutls-used" class="anchor" href="#version-of-gnutls-used" aria-hidden="true"></a>Version of gnutls used:</h2>
<p dir="auto">3.5.18-1ubuntu1</p>
<h2 dir="auto">
<a id="user-content-distributor-of-gnutls-eg-ubuntu-fedora-rhel" class="anchor" href="#distributor-of-gnutls-eg-ubuntu-fedora-rhel" aria-hidden="true"></a>Distributor of gnutls (e.g., Ubuntu, Fedora, RHEL)</h2>
<p dir="auto">Ubuntu 18.04</p>
<h2 dir="auto">
<a id="user-content-how-reproducible" class="anchor" href="#how-reproducible" aria-hidden="true"></a>How reproducible:</h2>
<p dir="auto">Steps to Reproduce:</p>
<ul dir="auto">
<li>Setup a PKCS#11 token (e.g. SoftHSM2).</li>
<li><code>cc -g $(pkgconf --cflags --libs gnutls) repro.c -fsanitize=address && ./a.out</code></li>
<li>Enter PIN code if requested and press Enter.</li>
</ul>
<h2 dir="auto">
<a id="user-content-actual-results" class="anchor" href="#actual-results" aria-hidden="true"></a>Actual results:</h2>
<p dir="auto">No error.</p>
<h2 dir="auto">
<a id="user-content-expected-results" class="anchor" href="#expected-results" aria-hidden="true"></a>Expected results:</h2>
<p dir="auto">Memory leak report (first backtraces have been manually converted with <code>addr2line</code>):</p>
<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">==17862==ERROR: LeakSanitizer: detected memory leaks</span>
<span id="LC2" class="line" lang="plaintext"></span>
<span id="LC3" class="line" lang="plaintext">Direct leak of 96 byte(s) in 1 object(s) allocated from:</span>
<span id="LC4" class="line" lang="plaintext">    #0 0x56431559d219 in malloc (/shared/a.out+0xf2219)</span>
<span id="LC5" class="line" lang="plaintext">    #1 0x7f8fba224e55  ./lib/pkcs11.c:2708</span>
<span id="LC6" class="line" lang="plaintext">    #2 0x7f8fba2260e9  ./lib/pkcs11.c:1420</span>
<span id="LC7" class="line" lang="plaintext">    #3 0x7f8fba22691b in gnutls_pkcs11_obj_list_import_url4 ./lib/pkcs11.c:3177</span>
<span id="LC8" class="line" lang="plaintext">    #4 0x5643155da92c in main /home/peter/work/hsm/demo/repro.c:27:13</span>
<span id="LC9" class="line" lang="plaintext">    #5 0x7f8fb920bb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310</span>
<span id="LC10" class="line" lang="plaintext">    #6 0x5643154ca0bd in _start (/shared/a.out+0x1f0bd)</span>
<span id="LC11" class="line" lang="plaintext"></span>
<span id="LC12" class="line" lang="plaintext">Indirect leak of 6144 byte(s) in 3 object(s) allocated from:</span>
<span id="LC13" class="line" lang="plaintext">    #0 0x56431559d6c8 in realloc (/shared/a.out+0xf26c8)</span>
<span id="LC14" class="line" lang="plaintext">    #1 0x7f8fba2088b5  (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x4c8b5)</span>
<span id="LC15" class="line" lang="plaintext">    #2 0x7f8fba20bf77 in gnutls_buffer_append_data (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x4ff77)</span>
<span id="LC16" class="line" lang="plaintext">    #3 0x7f8fba22512a  (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x6912a)</span>
<span id="LC17" class="line" lang="plaintext">    #4 0x7f8fba2260e9  (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x6a0e9)</span>
<span id="LC18" class="line" lang="plaintext">    #5 0x7f8fba22691b in gnutls_pkcs11_obj_list_import_url4 (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x6a91b)</span>
<span id="LC19" class="line" lang="plaintext">    #6 0x5643155da92c in main /home/peter/work/hsm/demo/repro.c:27:13</span>
<span id="LC20" class="line" lang="plaintext">    #7 0x7f8fb920bb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310</span>
<span id="LC21" class="line" lang="plaintext">    #8 0x5643154ca0bd in _start (/shared/a.out+0x1f0bd)</span></code></pre>
<p dir="auto">repro.c</p>
<pre class="code highlight js-syntax-highlight c" lang="c" v-pre="true"><code><span id="LC1" class="line" lang="c"><span class="cm">/*</span></span>
<span id="LC2" class="line" lang="c"><span class="cm">cc -g $(pkgconf --cflags --libs gnutls) repro.c -fsanitize=address</span></span>
<span id="LC3" class="line" lang="c"><span class="cm">*/</span></span>
<span id="LC4" class="line" lang="c"><span class="cp">#include <gnutls/gnutls.h></span></span>
<span id="LC5" class="line" lang="c"><span class="cp">#include <gnutls/pkcs11.h></span></span>
<span id="LC6" class="line" lang="c"><span class="cp">#include <stdio.h></span></span>
<span id="LC7" class="line" lang="c"><span class="cp">#include <string.h></span></span>
<span id="LC8" class="line" lang="c"><span class="cp">#include <unistd.h></span></span>
<span id="LC9" class="line" lang="c"></span>
<span id="LC10" class="line" lang="c"><span class="k">static</span> <span class="kt">int</span> <span class="nf">pin_callback</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">userdata</span><span class="p">,</span> <span class="kt">int</span> <span class="n">attempt</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">token_url</span><span class="p">,</span></span>
<span id="LC11" class="line" lang="c">                        <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">token_label</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">flags</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">pin</span><span class="p">,</span></span>
<span id="LC12" class="line" lang="c">                        <span class="kt">size_t</span> <span class="n">pin_max</span><span class="p">)</span> <span class="p">{</span></span>
<span id="LC13" class="line" lang="c">  <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">pass</span> <span class="o">=</span> <span class="n">getpass</span><span class="p">(</span><span class="s">"PIN: "</span><span class="p">);</span></span>
<span id="LC14" class="line" lang="c">  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">pass</span> <span class="o">||</span> <span class="o">!</span><span class="n">pass</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="p">{</span></span>
<span id="LC15" class="line" lang="c">    <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"PIN retrieval failed.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span></span>
<span id="LC16" class="line" lang="c">    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span></span>
<span id="LC17" class="line" lang="c">  <span class="p">}</span></span>
<span id="LC18" class="line" lang="c">  <span class="n">strncpy</span><span class="p">(</span><span class="n">pin</span><span class="p">,</span> <span class="n">pass</span><span class="p">,</span> <span class="n">pin_max</span><span class="p">);</span></span>
<span id="LC19" class="line" lang="c">  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span></span>
<span id="LC20" class="line" lang="c"><span class="p">}</span></span>
<span id="LC21" class="line" lang="c"></span>
<span id="LC22" class="line" lang="c"><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span> <span class="p">{</span></span>
<span id="LC23" class="line" lang="c">  <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">url</span> <span class="o">=</span> <span class="n">argc</span> <span class="o"><</span> <span class="mi">2</span> <span class="o">?</span> <span class="s">"pkcs11:"</span> <span class="o">:</span> <span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span></span>
<span id="LC24" class="line" lang="c">  <span class="n">gnutls_pkcs11_set_pin_function</span><span class="p">(</span><span class="n">pin_callback</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span></span>
<span id="LC25" class="line" lang="c">  <span class="n">gnutls_pkcs11_obj_t</span> <span class="o">*</span><span class="n">list</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span></span>
<span id="LC26" class="line" lang="c">  <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">nlist</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></span>
<span id="LC27" class="line" lang="c">  <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="n">gnutls_pkcs11_obj_list_import_url4</span><span class="p">(</span></span>
<span id="LC28" class="line" lang="c">      <span class="o">&</span><span class="n">list</span><span class="p">,</span> <span class="o">&</span><span class="n">nlist</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span></span>
<span id="LC29" class="line" lang="c">      <span class="n">GNUTLS_PKCS11_OBJ_FLAG_CRT</span> <span class="o">|</span> <span class="n">GNUTLS_PKCS11_OBJ_FLAG_WITH_PRIVKEY</span> <span class="o">|</span></span>
<span id="LC30" class="line" lang="c">          <span class="n">GNUTLS_PKCS11_OBJ_FLAG_LOGIN</span><span class="p">);</span></span>
<span id="LC31" class="line" lang="c">  <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span></span>
<span id="LC32" class="line" lang="c">    <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"import_url failed: %d (%s)</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">ret</span><span class="p">,</span> <span class="n">gnutls_strerror</span><span class="p">(</span><span class="n">ret</span><span class="p">));</span></span>
<span id="LC33" class="line" lang="c">  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span></span>
<span id="LC34" class="line" lang="c">    <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">nlist</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span></span>
<span id="LC35" class="line" lang="c">      <span class="n">gnutls_pkcs11_obj_deinit</span><span class="p">(</span><span class="n">list</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span></span>
<span id="LC36" class="line" lang="c">    <span class="p">}</span></span>
<span id="LC37" class="line" lang="c">    <span class="n">gnutls_free</span><span class="p">(</span><span class="n">list</span><span class="p">);</span></span>
<span id="LC38" class="line" lang="c">  <span class="p">}</span></span>
<span id="LC39" class="line" lang="c"><span class="p">}</span></span></code></pre>

</div>
<div class="footer" style="margin-top: 10px;">
<p style="font-size: small; color: #777777;">

<br>
Reply to this email directly or <a href="https://gitlab.com/gnutls/gnutls/issues/629">view it on GitLab</a>.
<br>
You're receiving this email because of your account on gitlab.com.
If you'd like to receive fewer emails, you can
<a href="https://gitlab.com/sent_notifications/80e571c3e67f93c1a0378a7e87b1582e/unsubscribe">unsubscribe</a>
from this thread or
adjust your notification settings.
<script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","action":{"@type":"ViewAction","name":"View Issue","url":"https://gitlab.com/gnutls/gnutls/issues/629"}}</script>
</p>
</div>
</body>
</html>