<?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>Thu, 08 Jul 2010 10:43:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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?
1int describe_something&#40;const something_t *thing, char *buf&#41;;
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 MAX_PATH should [...]]]></description>
			<content:encoded><![CDATA[<p>Ever seen such a function in a C API?</p>
<div class="codecolorer-container c mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">int</span> describe_something<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> something_t <span style="color: #339933;">*</span>thing<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>buf<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<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>
<div class="codecolorer-container c mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">size_t pagesize <span style="color: #339933;">=</span> sysconf<span style="color: #009900;">&#40;</span>_SC_PAGESIZE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #808080; font-style: italic;">/* size = minsize + pagesize rounded up to next multiple of pagesize */</span><br />
size_t size <span style="color: #339933;">=</span> minsize <span style="color: #339933;">+</span> 2<span style="color: #339933;">*</span>pagesize <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span><br />
size <span style="color: #339933;">=</span> size <span style="color: #339933;">-</span> <span style="color: #009900;">&#40;</span>size <span style="color: #339933;">%</span> pagesize<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #993333;">void</span> <span style="color: #339933;">*</span>t<span style="color: #339933;">;</span><br />
posix_memalign<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>t<span style="color: #339933;">,</span> pagesize<span style="color: #339933;">,</span> size<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span>buf <span style="color: #339933;">=</span> t<span style="color: #339933;">;</span><br />
mprotect<span style="color: #009900;">&#40;</span>buf <span style="color: #339933;">+</span> size <span style="color: #339933;">-</span> pagesize<span style="color: #339933;">,</span> pagesize<span style="color: #339933;">,</span> PROT_NONE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<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>
