Patch Level Update: PICC-18 STD
Patch Level Update: HI-TECH C PRO for the PIC10/12/16 MCU Family
NEW - PRO Compiler supporting Microchip PIC32 microcontrollers
Omniscient Code Generation: as featured in EDN Hot 100 Products of 2007.
A Spotter's Guide.The phrase "buffer overflow" is almost making it into the mainstream press these days, but many people who write programs which exhibit these mythical beasts are even unaware of what they are or why they are a problem. #include <string.h>
main() {
const char greet[] = "hello";
char buffer[5];
char precious = 7;
strcpy(buffer, greet);
/* assume precious==7 */
}
Here's a buffer overflow. The constant array named greet actually contains 6 characters, which strcpy() tries to copy into buffer where there is only room for 5. What will probably happen is that the last character (the invisible '\0' that teminates the string "hello") will be copied into the space formerly known as precious, and the assumption that precious contains the 7 we put into it will be violated. #include <string.h>
main() {
const char greet[5] = "hello";
char buffer[6];
char precious = 7;
strcpy(buffer, greet);
memcpy(buffer, greet, sizeof buffer);
}
Now we've fixed the first problem by making buffer big enough to hold all of greet, but then broken the strcpy() by making greet smaller. "How?" you ask. By making greet into a char array that is not a string, i.e. a char array that has no terminating '\0'. The strcpy() now won't know where to stop, and will keep copying until it finds a zero byte, if that ever happens. The memcpy() is better, because it is guaranteed to stop, but it still does (possibly unquantifiable) Bad Things, as it tries to copy from one byte past the end of greet. A word of warning here: don't assume strncpy() will save you: it is, unfortunately, not simply a bounded version of strcpy(), and has its own set of fangs. Most significantly, unlike all the other str...() functions in the Standard Library, it won't necessarily give you back a NUL-terminated string even if you give it one to work with. If its source is a long but valid string, and its destination is a shorter buffer, it will fill the buffer with characters from the string but it will NOT terminate that buffer with a '\0'. #include <stdio.h>
main() {
char buffer[5];
gets(buffer);
fgets(buffer, sizeof buffer, stdin);
}
The line with gets() might not be a buffer overflow, if the user (or wherever gets() is getting its input from) enters at most 4 characters before a newline; gets() can't tell that it is not allowed to write past buffer[4]. The line with fgets() can never overflow its buffer. Note, though, that fgets() doesn't eat the '\n' like gets() does. There are many more possible ways to overflow a buffer, writing data in all sorts of places it was never meant to go. Sometimes the effect might not be noticeable, but you can never be sure. And while the humble string or character array is the most common target, buffer overflows are not type-bigots - they'll strike anything they can touch. To Slay the Monster.When hunting them, the first thing to look for is functions which write into arrays without any way to know the amount of space available. If you get to define the function, you can pass a length parameter in, or ensure that every array you ever pass to it is at least as big as the hard-coded maximum amount it will write. If you're using a function someone else (like, say, the compiler vendor) has provided then avoiding functions like gets(), which take some amount of data over which you have no control and stuff it into arrays they can never know the size of, is a good start. Make sure that functions like the str...() family which expect NUL-terminated strings actually get them - store a '\0' in the last element of each array involved just before you call the function, if necessary. Good hunting.
|
Copyright © 2008 HI-TECH Software • Trademarks • Forum
Site Map