<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>dot</title>
    <link>https://edictum.illuminati.industries/dot/</link>
    <description></description>
    <pubDate>Tue, 26 May 2026 06:36:50 +0000</pubDate>
    <item>
      <title>[0001] Fixing NULL for the entire system for fun and profit</title>
      <link>https://edictum.illuminati.industries/dot/0001-fixing-null-for-the-entire-system-for-fun-and-profit</link>
      <description>&lt;![CDATA[Prelude&#xA;&#xA;NULL pointers are the scourge of C programming. The very idea to dedicate a special value inside the pointer address space seems disastrous in the hindsight, and even Tony Hoare agrees with this sentiment, calling null references his &amp;ldquo;billion dollar miskate&amp;rdquo;. Fortunately, as far as operating systems are concerned, zero address is no different than any other address and we can actually use memory at that location.&#xA;&#xA;Fixing NULL for thee&#xA;&#xA;First, a bit of C magic. Consider the following program.&#xA;&#xA;include sys/mman.h&#xA;include stdio.h&#xA;include string.h&#xA;&#xA;define LEN 4096&#xA;&#xA;int main(void) {&#xA;    char addr = mmap(NULL, LEN, PROTREAD|PROTWRITE, MAPSHARED|MAPFIXED|MAPANONYMOUS, -1, 0);&#xA;    if (addr == MAPFAILED) {&#xA;        perror(&#34;mmap&#34;);&#xA;        return -1;&#xA;    }&#xA;    if (addr != NULL) {&#xA;        fprintf(stderr, &#34;Mapped addr (%p) is not NULL\n&#34;, addr);&#xA;        goto end;&#xA;    }&#xA;    strcpy(NULL, &#34;The NULL has been desecrated&#34;);&#xA;    printf(&#34;%s\n&#34;, NULL);&#xA;end:&#xA;    munmap(addr, LEN);&#xA;    return 0;&#xA;}&#xA;&#xA;Surprisingly to many, it works just fine. Albeit, on modern Linux systems it would require either root privileges or setting vm/mmapminaddr=0 in your sysctl.conf. The reason for the latter is to prevent exploitation of NULL dereference bugs in the kernel. In any way, running this snippet will output the desired piece of text.&#xA;&#xA;Make it so!&#xA;&#xA;Since our plan is to have this piece of code run in virtually all processes in the system, the next step is turning this code into a shared library. Our slightly modified C code:&#xA;&#xA;include stdbool.h&#xA;include stddef.h&#xA;include string.h&#xA;include sys/mman.h&#xA;&#xA;static const sizet len = 4096;&#xA;static bool success = false;&#xA;&#xA;void attribute((constructor)) desecratenull(void) {&#xA;    const char nullwords[] = &#34;The NULL is no longer sacred&#34;;&#xA;    char addr = mmap(NULL, len, PROTREAD|PROTWRITE, MAPSHARED|MAPFIXED|MAPANONYMOUS, -1, 0);&#xA;    if (addr != NULL &amp;&amp; addr != MAPFAILED) {&#xA;        munmap(addr, len);&#xA;        return;&#xA;    }&#xA;    success = true;&#xA;    strcpy(NULL, nullwords);&#xA;    memset(NULL + sizeof(nullwords), &#39;E&#39;, len - sizeof(nullwords));&#xA;}&#xA;&#xA;void attribute((destructor)) reconsecratenull(void) {&#xA;    if (success) {&#xA;        munmap(NULL, len);&#xA;        success = false;&#xA;    }&#xA;}&#xA;&#xA;The sole difference is that our main() is now turned into constructor function run when this shared library is loaded into a process. We can verify that this works with a simple program like this:&#xA;&#xA;include stdio.h&#xA;&#xA;int main(int argc, char *argv[]) {&#xA;    printf(&#34;%s\n&#34;, NULL);&#xA;    return 0;&#xA;}&#xA;&#xA;In a normal environment, this would obviously receive SIGSEGV and crash. In our case, however&amp;#x2026;&#xA;&#xA;$ LDPRELOAD=./libnull.so ./test&#xA;The NULL is no longer sacred&#xA;&#xA;Spread it all over the system&#xA;&#xA;You can put a path to libnull.so into your /etc/ld.so.preload. Or you can use your distro tooling for this. But as we can see, fixing NULL pointer dereference for the entire system is not that hard.&#xA;&#xA;Conclusion&#xA;&#xA;Obviously, this entire article is a joke. While you certainly can do something like this, you shouldn&amp;rsquo;t. Turning NULL into a valid memory address with mapped contents turns easy to debug NULL errors into much harder to debug memory corruption errors, potentially compromises the security of your system, and tarnishes your karma.]]&gt;</description>
      <content:encoded><![CDATA[<h1 id="prelude">Prelude</h1>

<p>NULL pointers are the scourge of C programming. The very idea to dedicate a special value inside the pointer address space seems disastrous in the hindsight, and even Tony Hoare agrees with this sentiment, calling null references his “billion dollar miskate”. Fortunately, as far as operating systems are concerned, zero address is no different than any other address and we can actually use memory at that location.</p>

<h1 id="fixing-null-for-thee">Fixing NULL for thee</h1>

<p>First, a bit of C magic. Consider the following program.</p>

<pre><code>#include &lt;sys/mman.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

#define LEN 4096

int main(void) {
    char *addr = mmap(NULL, LEN, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
    if (addr == MAP_FAILED) {
        perror(&#34;mmap&#34;);
        return -1;
    }
    if (addr != NULL) {
        fprintf(stderr, &#34;Mapped addr (%p) is not NULL\n&#34;, addr);
        goto end;
    }
    strcpy(NULL, &#34;The NULL has been desecrated&#34;);
    printf(&#34;%s\n&#34;, NULL);
end:
    munmap(addr, LEN);
    return 0;
}
</code></pre>

<p>Surprisingly to many, it works just fine. Albeit, on modern Linux systems it would require either root privileges or setting <code>vm/mmap_min_addr=0</code> in your sysctl.conf. The reason for the latter is to prevent exploitation of NULL dereference bugs in the kernel. In any way, running this snippet will output the desired piece of text.</p>

<h1 id="make-it-so">Make it so!</h1>

<p>Since our plan is to have this piece of code run in virtually all processes in the system, the next step is turning this code into a shared library. Our slightly modified C code:</p>

<pre><code class="language-c">#include &lt;stdbool.h&gt;
#include &lt;stddef.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/mman.h&gt;

static const size_t len = 4096;
static bool success = false;

void __attribute__((constructor)) desecrate_null(void) {
    const char null_words[] = &#34;The NULL is no longer sacred&#34;;
    char *addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
    if (addr != NULL &amp;&amp; addr != MAP_FAILED) {
        munmap(addr, len);
        return;
    }
    success = true;
    strcpy(NULL, null_words);
    memset(NULL + sizeof(null_words), &#39;E&#39;, len - sizeof(null_words));
}

void __attribute__((destructor)) reconsecrate_null(void) {
    if (success) {
        munmap(NULL, len);
        success = false;
    }
}
</code></pre>

<p>The sole difference is that our <code>main()</code> is now turned into constructor function run when this shared library is loaded into a process. We can verify that this works with a simple program like this:</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;

int main(int argc, char *argv[]) {
    printf(&#34;%s\n&#34;, NULL);
    return 0;
}
</code></pre>

<p>In a normal environment, this would obviously receive SIGSEGV and crash. In our case, however…</p>

<pre><code class="language-sh">$ LD_PRELOAD=./libnull.so ./test
The NULL is no longer sacred

</code></pre>

<h1 id="spread-it-all-over-the-system">Spread it all over the system</h1>

<p>You can put a path to <code>libnull.so</code> into your <code>/etc/ld.so.preload</code>. Or you can use your distro tooling for this. But as we can see, fixing NULL pointer dereference for the entire system is not that hard.</p>

<h1 id="conclusion">Conclusion</h1>

<p>Obviously, this entire article is a joke. While you certainly can do something like this, you shouldn’t. Turning <code>NULL</code> into a valid memory address with mapped contents turns easy to debug NULL errors into much harder to debug memory corruption errors, potentially compromises the security of your system, and tarnishes your karma.</p>
]]></content:encoded>
      <guid>https://edictum.illuminati.industries/dot/0001-fixing-null-for-the-entire-system-for-fun-and-profit</guid>
      <pubDate>Tue, 24 Sep 2024 09:34:47 +0000</pubDate>
    </item>
  </channel>
</rss>