Pages

Friday, September 30, 2016

C, Solaris & SPARC M7 : Get Defensive with Few Techniques .. Part 1/3

This post is related to security defense (sort of).

C: Buffer Overflows

C programming language has no built-in protection against accessing or overwriting data in any part of memory. Also C doesn't check whether the data written to an array is within the boundaries of that array. Consequently erroneous C code can easily trigger buffer overflows/overruns by writing more data to a buffer than it can hold. In other words, by putting data in a memory area past a buffer. Writing beyond the bounds of a block of allocated memory (buffer) is a security vulnerability that can corrupt data, crash the application, or may cause the execution of malicious code.

Now let's have a look at few examples using some of the unbounded and bounded string functions.

strcpy vs strncpy vs strlcpy

strcpy()

strcpy() does not check buffer lengths (hence unbounded function) and may overwrite memory zone contiguous to the intended destination (buffer) if not careful.

strcpy() automatically includes the terminating null byte ('\0'). The programmer has to ensure that the copied string is within the bounds of the destination buffer.

eg.,
// no overflow
char word[5];
strcpy(word, "best");

// overflow
char word[5];
strcpy(word, "utopia");

PS:
strcpy(), strcat() and strcmp() functions in the same family are similarly vulnerable.
strncpy()

strncpy() is a bounded string function that prevents buffer overflows by accepting a buffer size argument and not writing past that boundary. This function copies at most bytes equal to the buffer size from source string to destination buffer. However unlike strcpy(), strncpy() does not guarantee null terminated string.

Initially all characters in the buffer are set to null bytes ('\0'). If the length of the source string is less than the buffer size argument, strncpy() overwrites the '\0' characters in the buffer only until the length of the source string. In this case, the copied string remains null terminated.

If the source string is equal to the size of buffer, all the '\0' characters in destination buffer will be overwritten and the copied string will be non-null terminated.

Similarly if the source string is longer than the size of buffer, all the '\0' characters in destination buffer will be overwritten and the copy will be non-null terminated and truncated resulting in data loss.

In all cases, it is the responsibility of the programmer to check for and include the terminating null byte if missing. Non-null terminated strings may exhibit undefined behavior that can potentially lead to incorrect program execution, and the hosting application is still vulnerable to attacks. For example, in case of non-null terminated strings, strlen() will keep searching memory until it finds a null character or hits an address that causes a memory protection fault of some sort.

eg.,
// ok. null terminated string
char word[6];
strncpy(word, "best", 6);

// not ok. non-null terminated string
char word[6];
strncpy(word, "utopia", 6);

// null terminated but truncated string
// atleast we avoid the undefined behavior
char word[6];
strncpy(word, "utopia", 5); // leave last byte for '\0'
    -or-
strncpy(word, "utopia", 6);
word[5] = '\0';
strlcpy()

strlcpy() is another bounded string function that prevents buffer overflows and avoids non-null terminated strings by copying at most bytes equal to the buffer size [argument] from source string to destination buffer, and by always adding a terminating null byte.

The programmer must still handle the possibility of data loss if the destination buffer size is too small. Data loss or string truncation can be detected by comparing the return value of the function (which is the length of the source string) to the destination buffer size.

eg.,
char word[6];
if (strlcpy(word, "utopia", 6) >= 6) {
        // handle data loss / string truncation
}
Note that strlcpy() is a non-standard string function. Therefore the resulting code may not be portable should the application making use of this function support a variety of operating platforms.

Solaris has this function implementation in C library.

To be continued ..

No comments:

Post a Comment