The C Standard Library
Parts of the C standard library (and the UNIX and GNU extensions)
are difficult to use, so you should avoid them.
Please check the applicable documentation before using the
recommended replacements. Many of these functions allocate
buffers using malloc which your code must
deallocate explicitly using free.
Absolutely Banned Interfaces
The functions listed below must not be used because they are
almost always unsafe. Use the indicated replacements instead.
gets
⟶ fgets
getwd
⟶ getcwd
or get_current_dir_name
readdir_r ⟶ readdir
realpath (with a non-NULL second parameter)
⟶ realpath with NULL as the second parameter,
or canonicalize_file_name
The constants listed below must not be used, either. Instead,
code must allocate memory dynamically and use interfaces with
length checking.
NAME_MAX (limit not actually enforced by
the kernel)
PATH_MAX (limit not actually enforced by
the kernel)
_PC_NAME_MAX (This limit, returned by the
pathconf function, is not enforced by
the kernel.)
_PC_PATH_MAX (This limit, returned by the
pathconf function, is not enforced by
the kernel.)
The following structure members must not be used.
f_namemax in struct
statvfs (limit not actually enforced by the kernel,
see _PC_NAME_MAX above)
Functions to Avoid
The following string manipulation functions can be used securely
in principle, but their use should be avoided because they are
difficult to use correctly. Calls to these functions can be
replaced with asprintf or
vasprintf. (For non-GNU targets, these
functions are available from Gnulib.) In some cases, the
snprintf function might be a suitable
replacement, see .
sprintf
strcat
strcpy
vsprintf
Use the indicated replacements for the functions below.
alloca ⟶
malloc and free
(see )
putenv ⟶
explicit envp argument in process creation
(see )
setenv ⟶
explicit envp argument in process creation
(see )
strdupa ⟶
strdup and free
(see )
strndupa ⟶
strndup and free
(see )
system ⟶
posix_spawn
or fork/execve/
(see )
unsetenv ⟶
explicit envp argument in process creation
(see )
String Functions with Explicit Length Arguments
The C run-time library provides string manipulation functions
which not just look for NUL characters for string termination,
but also honor explicit lengths provided by the caller.
However, these functions evolved over a long period of time, and
the lengths mean different things depending on the function.
snprintf
The snprintf function provides a way to
construct a string in a statically-sized buffer. (If the buffer
size is allocated on the heap, consider use
asprintf instead.)
The second argument to the snprintf call
should always be the size of the buffer in the first argument
(which should be a character array). Elaborate pointer and
length arithmetic can introduce errors and nullify the
security benefits of snprintf.
In particular, snprintf is not well-suited
to constructing a string iteratively, by appending to an
existing buffer. snprintf returns one of
two values, -1 on errors, or the number of
characters which would have been written to the
buffer if the buffer were large enough. This means
that adding the result of snprintf to the
buffer pointer to skip over the characters just written is
incorrect and risky. However, as long as the length argument
is not zero, the buffer will remain null-terminated.
works because end -current > 0 is a loop
invariant. After the loop, the result string is in the
buf variable.
Repeatedly writing to a buffer using snprintf
If you want to avoid the call to strlen
for performance reasons, you have to check for a negative
return value from snprintf and also check
if the return value is equal to the specified buffer length or
larger. Only if neither condition applies, you may advance
the pointer to the start of the write buffer by the number
return by snprintf. However, this
optimization is rarely worthwhile.
Note that it is not permitted to use the same buffer both as
the destination and as a source argument.
vsnprintf and Format Strings
If you use vsnprintf (or
vasprintf or even
snprintf) with a format string which is
not a constant, but a function argument, it is important to
annotate the function with a format
function attribute, so that GCC can warn about misuse of your
function (see ).
The format function attribute
strncpy
The strncpy function does not ensure that
the target buffer is null-terminated. A common idiom for
ensuring NUL termination is:
Another approach uses the strncat
function for this purpose:
strncat
The length argument of the strncat
function specifies the maximum number of characters copied
from the source buffer, excluding the terminating NUL
character. This means that the required number of bytes in
the destination buffer is the length of the original string,
plus the length argument in the strncat
call, plus one. Consequently, this function is rarely
appropriate for performing a length-checked string operation,
with the notable exception of the strcpy
emulation described in .
To implement a length-checked string append, you can use an
approach similar to :
In many cases, including this one, the string concatenation
can be avoided by combining everything into a single format
string:
But you should must not dynamically construct format strings
to avoid concatenation because this would prevent GCC from
type-checking the argument lists.
It is not possible to use format strings like
"%s%s" to implement concatenation, unless
you use separate buffers. snprintf does
not support overlapping source and target strings.
strlcpy and
strlcat
Some systems support strlcpy and
strlcat functions which behave this way,
but these functions are not part of GNU libc.
strlcpy is often replaced with
snprintf with a "%s"
format string. See for a caveat
related to the snprintf return value.
To emulate strlcat, use the approach
described in .
ISO C11 Annex K *_s functions
ISO C11 adds another set of length-checking functions, but GNU
libc currently does not implement them.
Other strn* and
stpn* functions
GNU libc contains additional functions with different variants
of length checking. Consult the documentation before using
them to find out what the length actually means.