<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>
<section id="sect-Defensive_Coding-C-Libc">
  <title>The C standard library</title>
  <para>
    Parts of the C standard library (and the UNIX and GNU extensions)
    are difficult to use, so you shoud avoid them.
  </para>
  <para>
    Please check the applicable documentation before using the
    recommended replacements.  Many of these functions allocate
    buffers using <function>malloc</function> which your code must
    deallocate explicitly using <function>free</function>.
  </para>
  <section id="sect-Defensive_Coding-C-Absolutely-Banned">
    <title>Absolutely banned interfaces</title>
    <para>
      The functions listed below must not be used because they are
      almost always unsafe.  Use the indicated replacements instead.
    </para>
    <itemizedlist>
      <listitem><para><function>gets</function>
      ⟶ <function>fgets</function></para></listitem>
      <listitem><para><function>getwd</function>
      ⟶ <function>getcwd</function>
      or <function>get_current_dir_name</function></para></listitem>
      <listitem>
	<para>
	  <function>readdir_r</function> ⟶ <function>readdir</function>
	  <!-- It is quite complicated to allocate a properly-sized
	       buffer for use with readdir_r, and readdir provides
	       sufficient thread safety guarantees. -->
	  <!-- ??? Add File_System cross-reference -->
	</para>
      </listitem>
      <listitem>
	<para>
	  <function>realpath</function> (with a non-NULL second parameter)
	  ⟶ <function>realpath</function> with NULL as the second parameter,
	  or <function>canonicalize_file_name</function>
	  <!-- It is complicated to allocate a properly-sized buffer
	       for use with realpath. -->
	  <!-- ??? Add File_System cross-reference -->
	</para>
      </listitem>
    </itemizedlist>
    <para>
      The constants listed below must not be used, either.  Instead,
      code must allocate memory dynamically and use interfaces with
      length checking.
    </para>
    <itemizedlist>
      <listitem>
	<para>
	  <literal>NAME_MAX</literal> (limit not actually enforced by
	  the kernel)
	</para>
      </listitem>
      <listitem>
	<para>
	  <literal>PATH_MAX</literal> (limit not actually enforced by
	  the kernel)
	</para>
      </listitem>
      <listitem>
	<para>
	  <literal>_PC_NAME_MAX</literal> (This limit, returned by the
	  <function>pathconf</function> function, is not enforced by
	  the kernel.)
	</para>
      </listitem>
      <listitem>
	<para>
	  <literal>_PC_PATH_MAX</literal> (This limit, returned by the
	  <function>pathconf</function> function, is not enforced by
	  the kernel.)
	</para>
      </listitem>
    </itemizedlist>
    <para>
      The following structure members must not be used.
    </para>
    <itemizedlist>
      <listitem>
	<para>
	  <literal>f_namemax</literal> in <literal>struct
	  statvfs</literal> (limit not actually enforced by the kernel,
	  see <literal>_PC_NAME_MAX</literal> above)
	</para>
      </listitem>
    </itemizedlist>
  </section>
  <section id="sect-Defensive_Coding-C-Avoid">
    <title>Functions to avoid</title>
    <para>
      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 <function>asprintf</function> or
      <function>vasprintf</function>.  (For non-GNU targets, these
      functions are available from Gnulib.)  In some cases, the
      <function>snprintf</function> function might be a suitable
      replacement, see <xref
      linkend="sect-Defensive_Coding-C-String-Functions-Length"/>.
    </para>
    <itemizedlist>
      <listitem><para><function>sprintf</function></para></listitem>
      <listitem><para><function>strcat</function></para></listitem>
      <listitem><para><function>strcpy</function></para></listitem>
      <listitem><para><function>vsprintf</function></para></listitem>
    </itemizedlist>
    <para>
      Use the indicated replacements for the functions below.
    </para>
    <itemizedlist>
      <listitem>
	<para>
	  <function>alloca</function> ⟶
	  <function>malloc</function> and <function>free</function>
	  (see <xref linkend="sect-Defensive_Coding-C-Allocators-alloca"/>)
	</para>
      </listitem>
      <listitem>
	<para>
	  <function>putenv</function> ⟶
	  explicit <varname>envp</varname> argument in process creation
	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-environ"/>)
	</para>
      </listitem>
      <listitem>
	<para>
	  <function>setenv</function> ⟶
	  explicit <varname>envp</varname> argument in process creation
	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-environ"/>)
	</para>
      </listitem>
      <listitem>
	<para>
	  <function>strdupa</function> ⟶
	  <function>strdup</function> and <function>free</function>
	  (see <xref linkend="sect-Defensive_Coding-C-Allocators-alloca"/>)
	</para>
      </listitem>
      <listitem>
	<para>
	  <function>strndupa</function> ⟶
	  <function>strndup</function> and <function>free</function>
	  (see <xref linkend="sect-Defensive_Coding-C-Allocators-alloca"/>)
	</para>
      </listitem>
      <listitem>
	<para>
	  <function>system</function> ⟶
	  <function>posix_spawn</function>
	  or <function>fork</function>/<function>execve</function>/
	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-execve"/>)
	</para>
      </listitem>
      <listitem>
	<para>
	  <function>unsetenv</function> ⟶
	  explicit <varname>envp</varname> argument in process creation
	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-environ"/>)
	</para>
      </listitem>
    </itemizedlist>
  </section>
  <section id="sect-Defensive_Coding-C-String-Functions-Length">
    <title>String Functions With Explicit Length Arguments</title>
    <para>
      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.
    </para>
    <section id="sect-Defensive_Coding-C-Libc-snprintf">
      <title><literal>snprintf</literal></title>
      <para>
	The <function>snprintf</function> function provides a way to
	construct a string in a statically-sized buffer.  (If the buffer
	size is allocated on the heap, consider use
	<function>asprintf</function> instead.)
      </para>
      <informalexample>
	<xi:include href="snippets/String-Functions-snprintf.xml"
		    xmlns:xi="http://www.w3.org/2001/XInclude" />
      </informalexample>
      <para>
	The second argument to the <function>snprintf</function> 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 <function>snprintf</function>.
      </para>
      <para>
	In particular, <literal>snprintf</literal> is not well-suited
	to constructing a string iteratively, by appending to an
	existing buffer.  <function>snprintf</function> returns one of
	two values, <literal>-1</literal> on errors, or the number of
	characters which <emphasis>would have been written to the
	buffer if the buffer were large enough</emphasis>.  This means
	that adding the result of <function>snprintf</function> 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 NUL-terminated. <xref
	linkend="ex-Defensive_Coding-C-String-Functions-snprintf-incremental"/>
	works because <literal>end -current &gt; 0</literal> is a loop
	invariant.  After the loop, the result string is in the
	<varname>buf</varname> variable.
      </para>
      <example id="ex-Defensive_Coding-C-String-Functions-snprintf-incremental">
	<title>Repeatedly writing to a buffer using <function>snprintf</function></title>
	<xi:include href="snippets/String-Functions-snprintf-incremental.xml"
		    xmlns:xi="http://www.w3.org/2001/XInclude" />
      </example>
      <para>
	If you want to avoid the call to <function>strlen</function>
	for performance reasons, you have to check for a negative
	return value from <function>snprintf</function> 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 <function>snprintf</function>.  However, this
	optimization is rarely worthwhile.
      </para>
      <para>
	Note that it is not permitted to use the same buffer both as
	the destination and as a source argument.
      </para>
    </section>
    <section id="sect-Defensive_Coding-C-Libc-vsnprintf">
      <title><literal>vsnprintf</literal> and format strings</title>
      <para>
	If you use <function>vsnprintf</function> (or
	<function>vasprintf</function> or even
	<function>snprintf</function>) with a format string which is
	not a constant, but a function argument, it is important to
	annotate the function with a <literal>format</literal>
	function attribute, so that GCC can warn about misuse of your
	function (see <xref
	linkend="ex-Defensive_Coding-C-String-Functions-format-Attribute"/>).
      </para>
      <example id="ex-Defensive_Coding-C-String-Functions-format-Attribute">
	<title>The <literal>format</literal> function attribute</title>
	<xi:include href="snippets/String-Functions-format.xml"
		    xmlns:xi="http://www.w3.org/2001/XInclude" />
      </example>
    </section>
    <section id="sect-Defensive_Coding-C-Libc-strncpy">
      <title><function>strncpy</function></title>
      <para>
	The <function>strncpy</function> function does not ensure that
	the target buffer is NUL-terminated.  A common idiom for
	ensuring NUL termination is:
      </para>
      <informalexample>
	<xi:include href="snippets/String-Functions-strncpy.xml"
		    xmlns:xi="http://www.w3.org/2001/XInclude" />
      </informalexample>
      <para>
	Another approach uses the <function>strncat</function>
	function for this purpose:
      </para>
      <informalexample>
	<xi:include href="snippets/String-Functions-strncat-as-strncpy.xml"
		    xmlns:xi="http://www.w3.org/2001/XInclude" />
      </informalexample>
    </section>
    <section id="sect-Defensive_Coding-C-Libc-strncat">
      <title><function>strncat</function></title>
      <para>
	The length argument of the <function>strncat</function>
	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 <function>strncat</function>
	call, plus one.  Consequently, this function is rarely
	appropriate for performing a length-checked string operation,
	with the notable exception of the <function>strcpy</function>
	emulation described in <xref
	linkend="sect-Defensive_Coding-C-Libc-strncpy"/>.
      </para>
      <para>
	To implement a length-checked string append, you can use an
	approach similar to <xref
	linkend="ex-Defensive_Coding-C-String-Functions-snprintf-incremental"/>:
      </para>
      <informalexample>
	<xi:include href="snippets/String-Functions-strncat-emulation.xml"
		    xmlns:xi="http://www.w3.org/2001/XInclude" />
      </informalexample>
      <para>
	In many cases, including this one, the string concatenation
	can be avoided by combining everything into a single format
	string:
      </para>
      <informalexample>
	<xi:include href="snippets/String-Functions-strncat-merged.xml"
		    xmlns:xi="http://www.w3.org/2001/XInclude" />
      </informalexample>
      <para>
	But you should must not dynamically construct format strings
	to avoid concatenation because this would prevent GCC from
	type-checking the argument lists.
      </para>
      <para>
	It is not possible to use format strings like
	<literal>"%s%s"</literal> to implement concatenation, unless
	you use separate buffers.  <function>snprintf</function> does
	not support overlapping source and target strings.
      </para>
    </section>
    <section>
      <title><function>strlcpy</function> and
      <function>strlcat</function></title>
      <para>
	Some systems support <function>strlcpy</function> and
	<function>strlcat</function> functions which behave this way,
	but these functions are not part of GNU libc.
	<function>strlcpy</function> is often replaced with
	<function>snprintf</function> with a <literal>"%s"</literal>
	format string.  See <xref
	linkend="sect-Defensive_Coding-C-Libc-strncpy"/> for a caveat
	related to the <function>snprintf</function> return value.
      </para>
      <para>
	To emulate <function>strlcat</function>, use the approach
	described in <xref
	linkend="sect-Defensive_Coding-C-Libc-strncat"/>.
      </para>
    </section>
    <section>
      <title>ISO C11 Annex K *<function>_s</function> functions</title>
      <para>
	ISO C11 adds another set of length-checking functions, but GNU
	libc currently does not implement them.
      </para>
    </section>
    <section>
      <title>Other <function>strn</function>* and
      <function>stpn</function>* functions</title>
      <para>
	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.
      </para>
    </section>
  </section>
</section>
