U.S. Flag Official website of the Department of Homeland Security

Note: This page is part of the us-cert.gov archive.This document is part of the US-CERT website archive. These documents are no longer updated and may contain outdated information. Links may also no longer function. Please contact info@us-cert.gov if you have any questions about the US-CERT website archive.

TLP:WHITE

strncpy() and strncat()

Published: September 27, 2005 | Last revised: May 14, 2013

Author(s): Daniel Plakosh SDLC Life Cycles: Implementation Copyright: Copyright © Carnegie Mellon University 2005-2012.

Abstract

The standard C library includes functions that are designed to prevent buffer overflows, particularly strncpy() and strncat(). These universally available functions discard data larger than the specified length, regardless of whether it fits into the buffer. These functions are deprecated for new Windows code because they are frequently used incorrectly.

Development Context

Copying and concatenating character strings

Technology Context

C, UNIX, Win32

Attacks

Attacker executes arbitrary code on machine with permissions of compromised process or changes the behavior of the program.

Risk

Improper use of the strncpy() and strncat() functions can result in buffer overflow vulnerabilities.

Description

The standard C library includes functions that are designed to prevent buffer overflows, particularly strncpy() and strncat(). These universally available functions take a static allocation approach and discard data that doesn't fit into the buffer.

The strncpy() library function performs a similar function to strcpy() but allows a maximum size to be specified:

strncpy(dest, source, dest_size - 1);
dest[dest_size - 1] = '�';

The strcat() function concatenates a string to the end of a buffer. Like strcpy(), strcat() has a more secure version, strncat(). Functions like strncpy() and strncat() restrict the number of bytes written and are generally more secure, but they are not foolproof. The following is an actual code example resulting from a simplistic transformation of existing code:

strncpy(record, user, MAX_STRING_LEN - 1);
strncat(record, cpw, MAX_STRING_LEN - 1);

The problem is that the last argument to strncat() should not be the total buffer length; it should be the space remaining after the call to strncpy(). Both functions require that you specify the remaining space and not the total size of the buffer. Because the remaining space changes every time data is added or removed, programmers must track or constantly recompute the remaining space. These processes are error prone and can lead to vulnerabilities. The following call correctly calculates the remaining space when concatenating a string using strncat():

strncat(dest, source, dest_size-strlen(dest)-1);

Another problem with strncpy() and strncat() is that neither function provides a status code or reports when the resulting string is truncated. Both functions return a pointer to the destination buffer, requiring significant effort by the programmer to determine whether the resulting string was truncated.

The strncpy() function doesn't null terminate the destination string if the source string is at least as long as the destination. (This behavior is defined by the C99 specification.) As a result, the destination string must be null terminated after calling strncpy().

There's also a performance problem with strncpy() in that it fills the entire destination buffer with null bytes after the source data has been exhausted. Although there is no good reason for this behavior, many programs now depend on it and as a result it is difficult to change.

References

[ISO/IEC 99]

ISO/IEC. ISO/IEC 9899 Second edition 1999-12-01 Programming languages — C. International Organization for Standardization, 1999.


Back to Top