Wednesday, November 15, 2006
Common Bugs in the scanf Family of Functions
The scanf function is an interesting one. It definately leaves a lot of room for a programmer to go wrong. The most commonly known bug is that scanf does not do any bound checks explicitly. This can however be solved with the proper format string.

The following is an example using sscanf which is used to read formatted input from a variable:

void split_input(char *buf)
{
char a[256], b[256];

sscanf(buf, "%s:%s", a, b);
printf("%s\t%s\n", a, b);

return;
}



In this example what happens if buf contains input which does not match the specified format? First we need to consider the state of the variables. In this example the variable a and b are not initialized. This fact leads us to our answer. The variable a will be assigned a value as long as buf contains data. However, if buf does not contain input in the format "somestring:someotherstring" the b variable will remain uninitialized. This can lead to some interesting vulnerabilities if the uninitialized data can be controlled prior to calling this function. Another thing to point out is that if buffer contains input larger than the allocated space for the variable a and b between the ":" delimiter a buffer overflow will occur because these functions do not check bounds.

Another typical bug occurs when programmers try to solve the issue of the scanf family of function not preforming bounds checks. Above I mentioned that this can be solved by using the proper format string. If you thought automatically that the format string I had intended was "%.NNs" NN being the value to restrict the size by, then you would be very wrong. The scanf family of function utilize a different form than the printf family of functions to limit the size of a format.

char buffer[256];
scanf("%256s", &buffer);


This example depicts the proper form of restricting the size of a format within the scanf family of functions. There is however a subtle flaw in the example which I added on purpose to show that even this is not always so easy to do properly. In this example we have an off-by-one condition. The last valid index of buffer is 255 the format which is specified will fill the entire buffer leaving no room for the null byte.

So using scanf functions can be very dangerous when they are not properly used. If you must use them try to read the manual page for them and test your code extensively.
 
posted by bannedit at Wednesday, November 15, 2006 | Permalink |


3 Comments:


At 11:40 PM, Blogger Isaac

Well i'll be damned,
if it isn't the bannedit ;). I was just browsing around milw0rm out of boredum today and came across a paper posted by you. Good work man ;) Glad to see the old phreaks are alive and kicking! send me a mail sometime sh0dan.org. peace!
-wirepair

 

At 10:09 AM, Blogger sk

Hey, saw your link posted on #innercircle, thought'd I check it out. Shit looks good. I code as well, not so much security related, but I'd love to make the jump.

Anyways, keep it going!

 

At 9:06 PM, Blogger Unknown

isn't the above alright? buf[256] is actually 257 bytes right?