Oct
14
2009

Calling legacy code with unknown output buffer size requirements

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 MAX_PATH should suffice. Which basically tells you that the library was ported from Windows (on Unix, we have PATH_MAX, which is undefined if there is no limit).

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.

On Unix systems you can use mprotect to protect the end of the buffer against overwriting. In fact, this is what memory debuggers as valgrind do. The following code will allocate a region with minimum size minsize and protect the next page in memory against any access:

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(&t, pagesize, size);
char *buf = t;
mprotect(buf + size - pagesize, pagesize, PROT_NONE);

After this, you can use buf just like it was allocated using buf = malloc(minsize). 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.

I wrote some code to test and illustrate my idea, you can find it in my mercurial repository. 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 this CERT secure coding rule).

posted in robustness by admin

Follow comments via the RSS Feed | Leave a comment | Trackback URL

Leave Your Comment

You must be logged in to post a comment.

 
Powered by Wordpress and MySQL. Theme by openark.org