<story><title>There’s a Hole in the Bottom of the C: Effectiveness of Allocation Protection [pdf]</title><url>http://web.mit.edu/ha22286/www/papers/SecDev18.pdf</url></story><parent_chain><item><author>Animats</author><text>Short version: yet another hokey scheme for fixing buffer overruns in C fails for&lt;p&gt;&lt;pre&gt;&lt;code&gt;   typedef struct {
        char buf[124];
        void* fptr;
    } mystruct;
&lt;/code&gt;&lt;/pre&gt;
because if you overrun &amp;quot;buf&amp;quot;, you can overstore &amp;quot;fptr&amp;quot; without going outside the bounds of &amp;quot;struct&amp;quot;. Exploit for Ngnix found.&lt;p&gt;We&amp;#x27;ve got to get more code out of C and into something with subscript checking. None of the kludges for fixing C work.</text></item></parent_chain><comment><author>derf_</author><text>One (non-generalizable) solution is to avoid using writable function pointers, to help maintain control flow integrity.&lt;p&gt;For example, in libopus we have platform-specific SIMD optimizations that are chosen at runtime.&lt;p&gt;The common solution is just to have a function pointer that points to the accelerated routine. But there are only a limited number of choices for each routine. So we put pointers to them in a static const array, which gets stored on a read-only page. Then instead of storing a pointer, we just store an index into this array. This index is chosen based on the available instruction sets detected at runtime. This lets us use the same index for every accelerated function.&lt;p&gt;Then, we pad the array size out to a power of two. To call an accelerated function, we mask off the upper bits of the index. Even if the index gets corrupted, we still call one of the functions in the array. So there&amp;#x27;s only so much damage it can do.&lt;p&gt;Obviously this doesn&amp;#x27;t apply if the set of functions you need to call is open-ended (e.g., a callback, like nginx was using). But it seems like a good pattern to follow when it applies.</text></comment>
<story><title>There’s a Hole in the Bottom of the C: Effectiveness of Allocation Protection [pdf]</title><url>http://web.mit.edu/ha22286/www/papers/SecDev18.pdf</url></story><parent_chain><item><author>Animats</author><text>Short version: yet another hokey scheme for fixing buffer overruns in C fails for&lt;p&gt;&lt;pre&gt;&lt;code&gt;   typedef struct {
        char buf[124];
        void* fptr;
    } mystruct;
&lt;/code&gt;&lt;/pre&gt;
because if you overrun &amp;quot;buf&amp;quot;, you can overstore &amp;quot;fptr&amp;quot; without going outside the bounds of &amp;quot;struct&amp;quot;. Exploit for Ngnix found.&lt;p&gt;We&amp;#x27;ve got to get more code out of C and into something with subscript checking. None of the kludges for fixing C work.</text></item></parent_chain><comment><author>mirekrusin</author><text>I always thought this is example of basic buffer overflow in C - what&amp;#x27;s different with this example? If somebody asked me to write buffer overflow example in C I&amp;#x27;d write something that looks exactly like this, this must have been known for years, what am I missing here?</text></comment>