Beware of Buffer Overruns

Beware of buffer overruns (overflows), where an input value or copied string exceeds the allocated buffer space. Never use gets(), and employ functions such as scanf(), sprintf(), strcpy(), and strcat() with caution (e.g., guarding their use with if statements that prevent buffer overruns).

Buffer overruns allow techniques such as stack crashing (also known as stack smashing), whereby a malicious user employs a buffer overrun to place carefully coded bytes into a stack frame in order to force the privileged program to execute arbitrary code. (Several online sources explain the details of stack crashing; see also [Erickson, 2008] and [Anley, 2007].) Buffer overruns are probably the single most common source of security breaches on computer systems, as evidenced by the frequency of advisories posted by CERT (http://www.cert.org/) and to Bugtraq (http://www.securityfocus.com/). Buffer overruns are particularly dangerous in network servers, since they leave a system open to remote attack from anywhere on a network.

Note

In order to make stack crashing more difficult—in particular, to make such attacks much more time-consuming when conducted remotely against network servers—from kernel 2.6.12 onward, Linux implements address-space randomization. This technique randomly varies the location of the stack over an 8 MB range at the top of virtual memory. In addition, the locations of memory mappings may also be randomized, if the soft RLIMIT_STACK limit is not infinite and the Linux-specific /proc/sys/vm/legacy_va_layout file contains the value 0.

More recent x86-32 architectures provide hardware support for marking page tables as NX (“no execute”). This feature is used to prevent execution of program code on the stack, thus making stack crashing more difficult.

There are safe alternatives to many of the functions mentioned above—for example, snprintf(), strncpy(), and strncat()—that allow the caller to specify the maximum number of characters that should be copied. These functions take the specified maximum into account in order to avoid overrunning the target buffer. In general, these alternatives are preferable, but must still be handled with care. In particular, note the following points:

Note

Some UNIX implementations provide the strlcpy() function, which, given a length argument n, copies at most n - 1 bytes to the destination buffer and always appends a null character at the end of the buffer. However, this function is not specified in SUSv3 and is not implemented in glibc. Furthermore, in cases where the caller is not carefully checking string lengths, this function only substitutes one problem (buffer overflows) for another (silently discarding data).