<br><br><div class="gmail_quote">On Mon, Jan 16, 2012 at 18:45, Jonathan Neuschäfer <span dir="ltr">&lt;<a href="mailto:j.neuschaefer@gmx.net">j.neuschaefer@gmx.net</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Mon, Jan 16, 2012 at 01:19:22PM -0500, Scott Lovenberg wrote:<br>
&gt; Let me walk you guys through how this bug could be exploited.<br>
&gt; The file that you want to access is blocked from you by file system<br>
&gt; permissions.  The root user (uid==0) can access this file (that contains<br>
&gt; credentials) and read it into memory that it has malloc()&#39;ed.  After the<br>
&gt; process running as root is done, it free()&#39;s the memory without zeroing it<br>
&gt; out.  Now you (you clever hacker) spawn a process that requests memory in<br>
&gt; large hunks.  It then searches for the string &quot;password=&quot; in that memory.<br>
&gt;  Since the memory was free()&#39;ed back to the pool without being changed, it<br>
&gt; still contains the original information that was in the file that you<br>
&gt; cannot read.  Does this make sense, or should I go into t a bit more detail?<br>
<br>
</div>But can you actually get this dirty memory on Linux?<br>
<br>
I know two sources of memory that are used by malloc. One is brk(), the<br>
other is mmapped pages of /dev/zero. With /dev/zero it&#39;s obvious that<br>
you get empty pages (all-zero); with brk I wasn&#39;t sure so I wrote the<br>
test program below and ran it. I didn&#39;t find any dirty (non-zero) memory.<br>
<br>
Thanks,<br>
        Jonathan Neuschäfer<br>
<br>
<br>
--<br>
#include &lt;unistd.h&gt;<br>
#include &lt;stdio.h&gt;<br>
<br>
#define BLOCKSZ (1024 * 1024) /* one Mibi */<br>
<br>
int main(void)<br>
{<br>
        int maxmb = 1024;<br>
        unsigned i;<br>
        void *BRK;<br>
<br>
        BRK = sbrk(0);<br>
<br>
        for (i = 0; i &lt; maxmb; i++) {<br>
                void *block = sbrk(BLOCKSZ);<br>
                unsigned j, *p;<br>
<br>
                if (block == (void *) -1) {<br>
                        printf(&quot;sbrk failed after %u blocks (%u bytes)\n&quot;, i, i * BLOCKSZ);<br>
                        break;<br>
                }<br>
<br>
                for (p = block, j = BLOCKSZ/sizeof(unsigned int); j--; p++)<br>
                        if (*p)<br>
                                printf(&quot;found data at BRK+%p: %u\n&quot;, ((void *)p) - BRK, *p);<br>
        }<br>
<br>
        return 0;<br>
}<br>
</blockquote></div><div><br></div>Thanks for posting this.  I&#39;m embarrassed that I never even bothered to check if dirty memory was given back.  I guess I just assumed.  You know what they say about assumptions...  Anyways, I think this is a great discussion. :)<br>
<br clear="all"><div><br></div>-- <br>Peace and Blessings,<br>-Scott.<br><br>