<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bluehorn's Blog &#187; robustness</title>
	<atom:link href="http://www.landschoff.net/blog/category/robustness/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.landschoff.net/blog</link>
	<description>Ramblings of Torsten Landschoff</description>
	<lastBuildDate>Sun, 07 Nov 2010 18:24:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Calling legacy code with unknown output buffer size requirements</title>
		<link>http://www.landschoff.net/blog/2009/10/calling-legacy-code-with-unknown-output-buffer-size-requirements/</link>
		<comments>http://www.landschoff.net/blog/2009/10/calling-legacy-code-with-unknown-output-buffer-size-requirements/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 21:29:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[robustness]]></category>

		<guid isPermaLink="false">http://www.landschoff.net/blog/?p=30</guid>
		<description><![CDATA[Ever seen such a function in a C API? int describe_something(const something_t *thing, char *buf); The documentation states that the function will write a description of thing into the given string buffer. Err, sure, but how big do I need to allocate buf? If you are lucky, there docs remark that a buffer size of [...]]]></description>
			<content:encoded><![CDATA[<p>Ever seen such a function in a C API?</p>
<pre lang="c">int describe_something(const something_t *thing, char *buf);</pre>
<p>The documentation states that the function will write a description of <tt>thing</tt> into the given string buffer. Err, sure, but how big do I need to allocate <tt>buf</tt>? If you are lucky, there docs remark that a buffer size of <tt>MAX_PATH</tt> should suffice. Which basically tells you that the library was ported from Windows (on Unix, we have <tt>PATH_MAX</tt>, which is undefined if there is no limit).</p>
<p>I ran across such a function lately. Originally, I had a remark in the source code and a huge buffer and be done with it. But I was curious if I can find a safe way to call such a function.</p>
<p>On Unix systems you can use <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/mprotect.2.html">mprotect</a> to protect the end of the buffer against overwriting. In fact, this is what memory debuggers as <a href="http://valgrind.org">valgrind</a> do. The following code will allocate a region with minimum size <tt>minsize</tt> and protect the next page in memory against any access:</p>
<pre lang="c">
size_t pagesize = sysconf(_SC_PAGESIZE);
/* size = minsize + pagesize rounded up to next multiple of pagesize */
size_t size = minsize + 2*pagesize - 1;
size = size - (size % pagesize);
void *t;
posix_memalign(&#038;t, pagesize, size);
char *buf = t;
mprotect(buf + size - pagesize, pagesize, PROT_NONE);
</pre>
<p>After this, you can use <tt>buf</tt> just like it was allocated using <code>buf = malloc(minsize)</code>. Overflowing the buffer into the next page of memory will cause a SIGSEGV. So the program will still crash, but at least you will notice immediately.</p>
<p>I wrote some code to test and illustrate my idea, you can find it in my <a href="http://landschoff.net/hg/strbuf_protect">mercurial repository</a>. I went a bit further to catch the SIGSEGV, but that is probably not a good idea. The only way to recover from SIGSEGV is to jump out of the signal handler using longjmp, which could leave the library in an invalid state (see <a href="https://www.securecoding.cert.org/confluence/display/seccode/SIG32-C.+Do+not+call+longjmp()+from+inside+a+signal+handler">this CERT secure coding rule</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.landschoff.net/blog/2009/10/calling-legacy-code-with-unknown-output-buffer-size-requirements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

