...
The below example uses strncpy, which will copy, at most, 10 bytes but will stop copying after it encounters a null-byte. Because wide-characters can contain null-bytes, the code can stop copying prematurely. It is important to recognize that many narrow-string functions are byte functions and, thus, can terminate prematurely.
| Code Block | ||
|---|---|---|
| ||
wchar_t *wide_str1[] = L"0123456789"; wchar_t *wide_str2[] = L"0000000000"; strncpy(wide_str2, wide_str1, 10); |
...
It should be noted that wcsncpy does not perform null-termination if the source string contains more wide-characters than the destination. As a result, it is possible for an attacker to exploit such a vulnerability by passing a maliciously crafted string to wcsncpy. If the code is intended to copy a certain number of bytes, it can overflow the buffer by writing multiple bytes as wcsncpy measures copying by wide-characters, not by bytes.
| Code Block | ||
|---|---|---|
| ||
char *narrow_str1[] = "0123456789"; char *narrow_str2[] = "0000000000"; wcsncpy(narrow_str2, narrow_str1, 10); |
Implementation Details
C99 recognizes wchar_t *[] and char *[] as distinct types. As a result, many compilers will yield a warning if the inappropriate function is used. For example, the following warnings were generated when the second non-compliant example was compiled with no flags in GCC on a Linux i686 platform:
...
The below example uses the appropriate-width function versions. Using wcsncpy for wide-char strings and strncpy for narrow-char strings will ensure that data is not truncated or overwriting extra memory.
| Code Block | ||
|---|---|---|
| ||
wchar_t *wide_str1[] = L"0123456789"; wchar_t *wide_str2[] = L"0000000000"; wcsncpy(wide_str2, wide_str1, 10); /* Use of proper-width function */ char *narrow_str1[] = "0123456789"; char *narrow_str2[] = "0000000000"; strncpy(narrow_str2, narrow_str1, 10); /* Use of proper-width function */ |
...