This required moving files around in the repository and shifting from a master.adoc structure to _topic_map.yml, etc. README and Makefile modified slightly to reflect new build process
1182 lines
No EOL
55 KiB
HTML
1182 lines
No EOL
55 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta content="IE=edge" http-equiv="X-UA-Compatible">
|
||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The C Programming Language</title>
|
||
|
||
<!-- Bootstrap -->
|
||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
|
||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
|
||
|
||
<!-- Overpass Font -->
|
||
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
|
||
|
||
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
|
||
|
||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||
<!--[if lt IE 9]>
|
||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||
<![endif]-->
|
||
|
||
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
|
||
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
|
||
<meta content="AsciiBinder" name="application-name">
|
||
</head>
|
||
<body>
|
||
<div class="navbar navbar-default" role="navigation">
|
||
<div class="container-fluid">
|
||
<div class="navbar-header">
|
||
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="container">
|
||
<p class="toggle-nav visible-xs pull-left">
|
||
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
|
||
</p>
|
||
<ol class="breadcrumb">
|
||
<li class="sitename">
|
||
<a href="../../../index.html">Home</a>
|
||
</li>
|
||
<li class="hidden-xs active">
|
||
<a href="../../en-US/index.html">Defensive Coding Guide </a>
|
||
</li>
|
||
<li class="hidden-xs active">
|
||
<a href="../../en-US/index.html">Defensive Coding Guide</a>
|
||
</li>
|
||
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
|
||
<li class="hidden-xs active">
|
||
The C Programming Language
|
||
</li>
|
||
</ol>
|
||
<div class="row row-offcanvas row-offcanvas-left">
|
||
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
|
||
<ul class="nav nav-sidebar">
|
||
<li class="nav-header">
|
||
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
|
||
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
|
||
</a>
|
||
<ul id="topicGroup0" class="collapse in list-unstyled">
|
||
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
|
||
<li class="nav-header">
|
||
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
|
||
<span id="sgSpan-0-1" class="fa fa-caret-down"></span> Programming Languages
|
||
</a>
|
||
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
|
||
<li><a class=" active" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
|
||
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming Language</a></li>
|
||
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
|
||
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
|
||
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
|
||
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
|
||
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-header">
|
||
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
|
||
<span id="sgSpan-0-2" class="fa fa-caret-right"></span> Specific Programming Tasks
|
||
</a>
|
||
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
|
||
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
|
||
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
|
||
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
|
||
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
|
||
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
|
||
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
|
||
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
|
||
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-header">
|
||
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
|
||
<span id="sgSpan-0-3" class="fa fa-caret-right"></span> Implementing Security Features
|
||
</a>
|
||
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
|
||
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
|
||
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
|
||
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="col-xs-12 col-sm-9 col-md-9 main">
|
||
<div class="page-header">
|
||
<h2>The C Programming Language</h2>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="sect-Defensive_Coding-C-Language"><a class="anchor" href="#sect-Defensive_Coding-C-Language"></a>The Core Language</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>C provides no memory safety. Most recommendations in this section
|
||
deal with this aspect of the language.</p>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Undefined"><a class="anchor" href="#sect-Defensive_Coding-C-Undefined"></a>Undefined Behavior</h3>
|
||
<div class="paragraph">
|
||
<p>Some C constructs are defined to be undefined by the C standard.
|
||
This does not only mean that the standard does not describe
|
||
what happens when the construct is executed. It also allows
|
||
optimizing compilers such as GCC to assume that this particular
|
||
construct is never reached. In some cases, this has caused
|
||
GCC to optimize security checks away. (This is not a flaw in GCC
|
||
or the C language. But C certainly has some areas which are more
|
||
difficult to use than others.)</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Common sources of undefined behavior are:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>out-of-bounds array accesses</p>
|
||
</li>
|
||
<li>
|
||
<p>null pointer dereferences</p>
|
||
</li>
|
||
<li>
|
||
<p>overflow in signed integer arithmetic</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Pointers"><a class="anchor" href="#sect-Defensive_Coding-C-Pointers"></a>Recommendations for Pointers and Array Handling</h3>
|
||
<div class="paragraph">
|
||
<p>Always keep track of the size of the array you are working with.
|
||
Often, code is more obviously correct when you keep a pointer
|
||
past the last element of the array, and calculate the number of
|
||
remaining elements by substracting the current position from
|
||
that pointer. The alternative, updating a separate variable
|
||
every time when the position is advanced, is usually less
|
||
obviously correct.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p><a href="#ex-Defensive_Coding-C-Pointers-remaining">Array processing in C</a>
|
||
shows how to extract Pascal-style strings from a character
|
||
buffer. The two pointers kept for length checks are
|
||
<code>inend</code> and <code>outend</code>.
|
||
<code>inp</code> and <code>outp</code> are the
|
||
respective positions.
|
||
The number of input bytes is checked using the expression
|
||
<code>len > (size_t)(inend - inp)</code>.
|
||
The cast silences a compiler warning;
|
||
<code>inend</code> is always larger than
|
||
<code>inp</code>.</p>
|
||
</div>
|
||
<div id="ex-Defensive_Coding-C-Pointers-remaining" class="exampleblock">
|
||
<div class="title">Example 1. Array processing in C</div>
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c">ssize_t
|
||
extract_strings(<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *in, size_t inlen, <span style="color:#0a8;font-weight:bold">char</span> **out, size_t outlen)
|
||
{
|
||
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *inp = in;
|
||
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *inend = in + inlen;
|
||
<span style="color:#0a8;font-weight:bold">char</span> **outp = out;
|
||
<span style="color:#0a8;font-weight:bold">char</span> **outend = out + outlen;
|
||
|
||
<span style="color:#080;font-weight:bold">while</span> (inp != inend) {
|
||
size_t len;
|
||
<span style="color:#0a8;font-weight:bold">char</span> *s;
|
||
<span style="color:#080;font-weight:bold">if</span> (outp == outend) {
|
||
errno = ENOSPC;
|
||
<span style="color:#080;font-weight:bold">goto</span> err;
|
||
}
|
||
len = (<span style="color:#0a8;font-weight:bold">unsigned</span> <span style="color:#0a8;font-weight:bold">char</span>)*inp;
|
||
++inp;
|
||
<span style="color:#080;font-weight:bold">if</span> (len > (size_t)(inend - inp)) {
|
||
errno = EINVAL;
|
||
<span style="color:#080;font-weight:bold">goto</span> err;
|
||
}
|
||
s = malloc(len + <span style="color:#00D">1</span>);
|
||
<span style="color:#080;font-weight:bold">if</span> (s == <span style="color:#069">NULL</span>) {
|
||
<span style="color:#080;font-weight:bold">goto</span> err;
|
||
}
|
||
memcpy(s, inp, len);
|
||
inp += len;
|
||
s[len] = <span style="color:#D20">'\0'</span>;
|
||
*outp = s;
|
||
++outp;
|
||
}
|
||
<span style="color:#080;font-weight:bold">return</span> outp - out;
|
||
<span style="color:#970;font-weight:bold">err:</span>
|
||
{
|
||
<span style="color:#0a8;font-weight:bold">int</span> errno_old = errno;
|
||
<span style="color:#080;font-weight:bold">while</span> (out != outp) {
|
||
free(*out);
|
||
++out;
|
||
}
|
||
errno = errno_old;
|
||
}
|
||
<span style="color:#080;font-weight:bold">return</span> -<span style="color:#00D">1</span>;
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is important that the length checks always have the form
|
||
<code>len > (size_t)(inend - inp)</code>, where
|
||
<code>len</code> is a variable of type
|
||
<code>size_t</code> which denotes the <strong>total</strong>
|
||
number of bytes which are about to be read or written next. In
|
||
general, it is not safe to fold multiple such checks into one,
|
||
as in <code>len1 + len2 > (size_t)(inend - inp)</code>,
|
||
because the expression on the left can overflow or wrap around
|
||
(see <a href="#sect-Defensive_Coding-C-Arithmetic">Recommendations for Integer Arithmetic</a>), and it
|
||
no longer reflects the number of bytes to be processed.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Arithmetic"><a class="anchor" href="#sect-Defensive_Coding-C-Arithmetic"></a>Recommendations for Integer Arithmetic</h3>
|
||
<div class="paragraph">
|
||
<p>Overflow in signed integer arithmetic is undefined. This means
|
||
that it is not possible to check for overflow after it happened,
|
||
see <a href="#ex-Defensive_Coding-C-Arithmetic-bad">Incorrect overflow detection in C</a>.</p>
|
||
</div>
|
||
<div id="ex-Defensive_Coding-C-Arithmetic-bad" class="exampleblock">
|
||
<div class="title">Example 2. Incorrect overflow detection in C</div>
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#088;font-weight:bold">void</span> report_overflow(<span style="color:#088;font-weight:bold">void</span>);
|
||
|
||
<span style="color:#0a8;font-weight:bold">int</span>
|
||
add(<span style="color:#0a8;font-weight:bold">int</span> a, <span style="color:#0a8;font-weight:bold">int</span> b)
|
||
{
|
||
<span style="color:#0a8;font-weight:bold">int</span> result = a + b;
|
||
<span style="color:#080;font-weight:bold">if</span> (a < <span style="color:#00D">0</span> || b < <span style="color:#00D">0</span>) {
|
||
<span style="color:#080;font-weight:bold">return</span> -<span style="color:#00D">1</span>;
|
||
}
|
||
<span style="color:#777">// The compiler can optimize away the following if statement.</span>
|
||
<span style="color:#080;font-weight:bold">if</span> (result < <span style="color:#00D">0</span>) {
|
||
report_overflow();
|
||
}
|
||
<span style="color:#080;font-weight:bold">return</span> result;
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The following approaches can be used to check for overflow,
|
||
without actually causing it.</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Use a wider type to perform the calculation, check that the
|
||
result is within bounds, and convert the result to the
|
||
original type. All intermediate results must be checked in
|
||
this way.</p>
|
||
</li>
|
||
<li>
|
||
<p>Perform the calculation in the corresponding unsigned type
|
||
and use bit fiddling to detect the overflow.
|
||
<a href="#ex-Defensive_Coding-C-Arithmetic-add_unsigned">Overflow checking for unsigned addition</a>
|
||
shows how to perform an overflow check for unsigned integer
|
||
addition. For three or more terms, all the intermediate
|
||
additions have to be checked in this way.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div id="ex-Defensive_Coding-C-Arithmetic-add_unsigned" class="exampleblock">
|
||
<div class="title">Example 3. Overflow checking for unsigned addition</div>
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#088;font-weight:bold">void</span> report_overflow(<span style="color:#088;font-weight:bold">void</span>);
|
||
|
||
<span style="color:#0a8;font-weight:bold">unsigned</span>
|
||
add_unsigned(<span style="color:#0a8;font-weight:bold">unsigned</span> a, <span style="color:#0a8;font-weight:bold">unsigned</span> b)
|
||
{
|
||
<span style="color:#0a8;font-weight:bold">unsigned</span> sum = a + b;
|
||
<span style="color:#080;font-weight:bold">if</span> (sum < a) { <span style="color:#777">// or sum < b</span>
|
||
report_overflow();
|
||
}
|
||
<span style="color:#080;font-weight:bold">return</span> sum;
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>Compute bounds for acceptable input values which are known
|
||
to avoid overflow, and reject other values. This is the
|
||
preferred way for overflow checking on multiplications,
|
||
see <a href="#ex-Defensive_Coding-C-Arithmetic-mult">Overflow checking for unsigned multiplication</a>.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div id="ex-Defensive_Coding-C-Arithmetic-mult" class="exampleblock">
|
||
<div class="title">Example 4. Overflow checking for unsigned multiplication</div>
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">unsigned</span>
|
||
mul(<span style="color:#0a8;font-weight:bold">unsigned</span> a, <span style="color:#0a8;font-weight:bold">unsigned</span> b)
|
||
{
|
||
<span style="color:#080;font-weight:bold">if</span> (b && a > ((<span style="color:#0a8;font-weight:bold">unsigned</span>)-<span style="color:#00D">1</span>) / b) {
|
||
report_overflow();
|
||
}
|
||
<span style="color:#080;font-weight:bold">return</span> a * b;
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Basic arithmetic operations are commutative, so for bounds checks,
|
||
there are two different but mathematically equivalent
|
||
expressions. Sometimes, one of the expressions results in
|
||
better code because parts of it can be reduced to a constant.
|
||
This applies to overflow checks for multiplication <code>a *
|
||
b</code> involving a constant <code>a</code>, where the
|
||
expression is reduced to <code>b > C</code> for some
|
||
constant <code>C</code> determined at compile time. The
|
||
other expression, <code>b && a > ((unsigned)-1) /
|
||
b</code>, is more difficult to optimize at compile time.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>When a value is converted to a signed integer, GCC always
|
||
chooses the result based on 2’s complement arithmetic. This GCC
|
||
extension (which is also implemented by other compilers) helps a
|
||
lot when implementing overflow checks.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Sometimes, it is necessary to compare unsigned and signed
|
||
integer variables. This results in a compiler warning,
|
||
<strong>comparison between signed and unsigned integer
|
||
expressions</strong>, because the comparison often gives
|
||
unexpected results for negative values. When adding a cast,
|
||
make sure that negative values are covered properly. If the
|
||
bound is unsigned and the checked quantity is signed, you should
|
||
cast the checked quantity to an unsigned type as least as wide
|
||
as either operand type. As a result, negative values will fail
|
||
the bounds check. (You can still check for negative values
|
||
separately for clarity, and the compiler will optimize away this
|
||
redundant check.)</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Legacy code should be compiled with the <code class="option">-fwrapv</code>
|
||
GCC option. As a result, GCC will provide 2’s complement
|
||
semantics for integer arithmetic, including defined behavior on
|
||
integer overflow.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Globals"><a class="anchor" href="#sect-Defensive_Coding-C-Globals"></a>Global Variables</h3>
|
||
<div class="paragraph">
|
||
<p>Global variables should be avoided because they usually lead to
|
||
thread safety hazards. In any case, they should be declared
|
||
<code>static</code>, so that access is restricted to a
|
||
single translation unit.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Global constants are not a problem, but declaring them can be
|
||
tricky. <a href="#ex-Defensive_Coding-C-Globals-String_Array">Declaring a constant array of constant strings</a>
|
||
shows how to declare a constant array of constant strings.
|
||
The second <code>const</code> is needed to make the
|
||
array constant, and not just the strings. It must be placed
|
||
after the <code>*</code>, and not before it.</p>
|
||
</div>
|
||
<div id="ex-Defensive_Coding-C-Globals-String_Array" class="exampleblock">
|
||
<div class="title">Example 5. Declaring a constant array of constant strings</div>
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#088;font-weight:bold">static</span> <span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *<span style="color:#088;font-weight:bold">const</span> string_list[] = {
|
||
<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">first</span><span style="color:#710">"</span></span>,
|
||
<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">second</span><span style="color:#710">"</span></span>,
|
||
<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">third</span><span style="color:#710">"</span></span>,
|
||
<span style="color:#069">NULL</span>
|
||
};</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Sometimes, static variables local to functions are used as a
|
||
replacement for proper memory management. Unlike non-static
|
||
local variables, it is possible to return a pointer to static
|
||
local variables to the caller. But such variables are
|
||
well-hidden, but effectively global (just as static variables at
|
||
file scope). It is difficult to add thread safety afterwards if
|
||
such interfaces are used. Merely dropping the
|
||
<code>static</code> keyword in such cases leads to
|
||
undefined behavior.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Another source for static local variables is a desire to reduce
|
||
stack space usage on embedded platforms, where the stack may
|
||
span only a few hundred bytes. If this is the only reason why
|
||
the <code>static</code> keyword is used, it can just be
|
||
dropped, unless the object is very large (larger than
|
||
128 kilobytes on 32-bit platforms). In the latter case, it is
|
||
recommended to allocate the object using
|
||
<code>malloc</code>, to obtain proper array checking, for
|
||
the same reasons outlined in <a href="#sect-Defensive_Coding-C-Allocators-alloca"><code>alloca</code> and Other Forms of Stack-based Allocation</a>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Unresolved directive in en-US/programming-languages/C-Libc.adoc - include::en-US/entities.adoc[]</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="sect-Defensive_Coding-C-Libc"><a class="anchor" href="#sect-Defensive_Coding-C-Libc"></a>The C Standard Library</h2>
|
||
<div class="sectionbody">
|
||
<div class="paragraph">
|
||
<p>Parts of the C standard library (and the UNIX and GNU extensions)
|
||
are difficult to use, so you should avoid them.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Please check the applicable documentation before using the
|
||
recommended replacements. Many of these functions allocate
|
||
buffers using <code>malloc</code> which your code must
|
||
deallocate explicitly using <code>free</code>.</p>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Absolutely-Banned"><a class="anchor" href="#sect-Defensive_Coding-C-Absolutely-Banned"></a>Absolutely Banned Interfaces</h3>
|
||
<div class="paragraph">
|
||
<p>The functions listed below must not be used because they are
|
||
almost always unsafe. Use the indicated replacements instead.</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>gets</code>
|
||
⟶ <code>fgets</code></p>
|
||
</li>
|
||
<li>
|
||
<p><code>getwd</code>
|
||
⟶ <code>getcwd</code>
|
||
or <code>get_current_dir_name</code></p>
|
||
</li>
|
||
<li>
|
||
<p><code>readdir_r</code> ⟶ <code>readdir</code></p>
|
||
</li>
|
||
<li>
|
||
<p><code>realpath</code> (with a non-NULL second parameter)
|
||
⟶ <code>realpath</code> with NULL as the second parameter,
|
||
or <code>canonicalize_file_name</code></p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The constants listed below must not be used, either. Instead,
|
||
code must allocate memory dynamically and use interfaces with
|
||
length checking.</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>NAME_MAX</code> (limit not actually enforced by
|
||
the kernel)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>PATH_MAX</code> (limit not actually enforced by
|
||
the kernel)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>_PC_NAME_MAX</code> (This limit, returned by the
|
||
<code>pathconf</code> function, is not enforced by
|
||
the kernel.)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>_PC_PATH_MAX</code> (This limit, returned by the
|
||
<code>pathconf</code> function, is not enforced by
|
||
the kernel.)</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The following structure members must not be used.</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>f_namemax</code> in <code>struct
|
||
statvfs</code> (limit not actually enforced by the kernel,
|
||
see <code>_PC_NAME_MAX</code> above)</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Avoid"><a class="anchor" href="#sect-Defensive_Coding-C-Avoid"></a>Functions to Avoid</h3>
|
||
<div class="paragraph">
|
||
<p>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 <code>asprintf</code> or
|
||
<code>vasprintf</code>. (For non-GNU targets, these
|
||
functions are available from Gnulib.) In some cases, the
|
||
<code>snprintf</code> function might be a suitable
|
||
replacement, see <a href="#sect-Defensive_Coding-C-String-Functions-Length">String Functions with Explicit Length Arguments</a>.</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>sprintf</code></p>
|
||
</li>
|
||
<li>
|
||
<p><code>strcat</code></p>
|
||
</li>
|
||
<li>
|
||
<p><code>strcpy</code></p>
|
||
</li>
|
||
<li>
|
||
<p><code>vsprintf</code></p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Use the indicated replacements for the functions below.</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p><code>alloca</code> ⟶
|
||
<code>malloc</code> and <code>free</code>
|
||
(see <a href="#sect-Defensive_Coding-C-Allocators-alloca"><code>alloca</code> and Other Forms of Stack-based Allocation</a>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>putenv</code> ⟶
|
||
explicit <code>envp</code> argument in process creation
|
||
(see <a href="#sect-Defensive_Coding-Tasks-Processes-environ">[sect-Defensive_Coding-Tasks-Processes-environ]</a>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>setenv</code> ⟶
|
||
explicit <code>envp</code> argument in process creation
|
||
(see <a href="#sect-Defensive_Coding-Tasks-Processes-environ">[sect-Defensive_Coding-Tasks-Processes-environ]</a>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>strdupa</code> ⟶
|
||
<code>strdup</code> and <code>free</code>
|
||
(see <a href="#sect-Defensive_Coding-C-Allocators-alloca"><code>alloca</code> and Other Forms of Stack-based Allocation</a>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>strndupa</code> ⟶
|
||
<code>strndup</code> and <code>free</code>
|
||
(see <a href="#sect-Defensive_Coding-C-Allocators-alloca"><code>alloca</code> and Other Forms of Stack-based Allocation</a>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>system</code> ⟶
|
||
<code>posix_spawn</code>
|
||
or <code>fork</code>/<code>execve</code>/
|
||
(see <a href="#sect-Defensive_Coding-Tasks-Processes-execve">[sect-Defensive_Coding-Tasks-Processes-execve]</a>)</p>
|
||
</li>
|
||
<li>
|
||
<p><code>unsetenv</code> ⟶
|
||
explicit <code>envp</code> argument in process creation
|
||
(see <a href="#sect-Defensive_Coding-Tasks-Processes-environ">[sect-Defensive_Coding-Tasks-Processes-environ]</a>)</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-String-Functions-Length"><a class="anchor" href="#sect-Defensive_Coding-C-String-Functions-Length"></a>String Functions with Explicit Length Arguments</h3>
|
||
<div class="paragraph">
|
||
<p>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.</p>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="sect-Defensive_Coding-C-Libc-snprintf"><a class="anchor" href="#sect-Defensive_Coding-C-Libc-snprintf"></a><code>snprintf</code></h4>
|
||
<div class="paragraph">
|
||
<p>The <code>snprintf</code> function provides a way to
|
||
construct a string in a statically-sized buffer. (If the buffer
|
||
size is allocated on the heap, consider use
|
||
<code>asprintf</code> instead.)</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">char</span> fraction[<span style="color:#00D">30</span>];
|
||
snprintf(fraction, <span style="color:#080;font-weight:bold">sizeof</span>(fraction), <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">%d/%d</span><span style="color:#710">"</span></span>, numerator, denominator);</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The second argument to the <code>snprintf</code> 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 <code>snprintf</code>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In particular, <code>snprintf</code> is not well-suited
|
||
to constructing a string iteratively, by appending to an
|
||
existing buffer. <code>snprintf</code> returns one of
|
||
two values, <code>-1</code> on errors, or the number of
|
||
characters which <strong>would have been written to the
|
||
buffer if the buffer were large enough</strong>. This means
|
||
that adding the result of <code>snprintf</code> 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. <a href="#ex-Defensive_Coding-C-String-Functions-snprintf-incremental">Repeatedly writing to a buffer using <code>snprintf</code></a>
|
||
works because <code>end -current > 0</code> is a loop
|
||
invariant. After the loop, the result string is in the
|
||
<code>buf</code> variable.</p>
|
||
</div>
|
||
<div id="ex-Defensive_Coding-C-String-Functions-snprintf-incremental" class="exampleblock">
|
||
<div class="title">Example 6. Repeatedly writing to a buffer using <code>snprintf</code></div>
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">char</span> buf[<span style="color:#00D">512</span>];
|
||
<span style="color:#0a8;font-weight:bold">char</span> *current = buf;
|
||
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *<span style="color:#088;font-weight:bold">const</span> end = buf + <span style="color:#080;font-weight:bold">sizeof</span>(buf);
|
||
<span style="color:#080;font-weight:bold">for</span> (<span style="color:#080;font-weight:bold">struct</span> item *it = data; it->key; ++it) {
|
||
snprintf(current, end - current, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">%s%s=%d</span><span style="color:#710">"</span></span>,
|
||
current == buf ? <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#710">"</span></span> : <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">, </span><span style="color:#710">"</span></span>, it->key, it->value);
|
||
current += strlen(current);
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>If you want to avoid the call to <code>strlen</code>
|
||
for performance reasons, you have to check for a negative
|
||
return value from <code>snprintf</code> 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 <code>snprintf</code>. However, this
|
||
optimization is rarely worthwhile.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Note that it is not permitted to use the same buffer both as
|
||
the destination and as a source argument.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="sect-Defensive_Coding-C-Libc-vsnprintf"><a class="anchor" href="#sect-Defensive_Coding-C-Libc-vsnprintf"></a><code>vsnprintf</code> and Format Strings</h4>
|
||
<div class="paragraph">
|
||
<p>If you use <code>vsnprintf</code> (or
|
||
<code>vasprintf</code> or even
|
||
<code>snprintf</code>) with a format string which is
|
||
not a constant, but a function argument, it is important to
|
||
annotate the function with a <code>format</code>
|
||
function attribute, so that GCC can warn about misuse of your
|
||
function (see <a href="#ex-Defensive_Coding-C-String-Functions-format-Attribute">The <code>format</code> function attribute</a>).</p>
|
||
</div>
|
||
<div id="ex-Defensive_Coding-C-String-Functions-format-Attribute" class="exampleblock">
|
||
<div class="title">Example 7. The <code>format</code> function attribute</div>
|
||
<div class="content">
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#088;font-weight:bold">void</span> log_format(<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *format, ...) __attribute__((format(printf, <span style="color:#00D">1</span>, <span style="color:#00D">2</span>)));
|
||
|
||
<span style="color:#088;font-weight:bold">void</span>
|
||
log_format(<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *format, ...)
|
||
{
|
||
<span style="color:#0a8;font-weight:bold">char</span> buf[<span style="color:#00D">1000</span>];
|
||
va_list ap;
|
||
va_start(ap, format);
|
||
vsnprintf(buf, <span style="color:#080;font-weight:bold">sizeof</span>(buf), format, ap);
|
||
va_end(ap);
|
||
log_string(buf);
|
||
}</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="sect-Defensive_Coding-C-Libc-strncpy"><a class="anchor" href="#sect-Defensive_Coding-C-Libc-strncpy"></a><code>strncpy</code></h4>
|
||
<div class="paragraph">
|
||
<p>The <code>strncpy</code> function does not ensure that
|
||
the target buffer is null-terminated. A common idiom for
|
||
ensuring NUL termination is:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">char</span> buf[<span style="color:#00D">10</span>];
|
||
strncpy(buf, data, <span style="color:#080;font-weight:bold">sizeof</span>(buf));
|
||
buf[<span style="color:#080;font-weight:bold">sizeof</span>(buf) - <span style="color:#00D">1</span>] = <span style="color:#D20">'\0'</span>;</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Another approach uses the <code>strncat</code>
|
||
function for this purpose:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c">buf[<span style="color:#00D">0</span>] = <span style="color:#D20">'\0'</span>;
|
||
strncat(buf, data, <span style="color:#080;font-weight:bold">sizeof</span>(buf) - <span style="color:#00D">1</span>);</code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="sect-Defensive_Coding-C-Libc-strncat"><a class="anchor" href="#sect-Defensive_Coding-C-Libc-strncat"></a><code>strncat</code></h4>
|
||
<div class="paragraph">
|
||
<p>The length argument of the <code>strncat</code>
|
||
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 <code>strncat</code>
|
||
call, plus one. Consequently, this function is rarely
|
||
appropriate for performing a length-checked string operation,
|
||
with the notable exception of the <code>strcpy</code>
|
||
emulation described in <a href="#sect-Defensive_Coding-C-Libc-strncpy"><code>strncpy</code></a>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>To implement a length-checked string append, you can use an
|
||
approach similar to <a href="#ex-Defensive_Coding-C-String-Functions-snprintf-incremental">Repeatedly writing to a buffer using <code>snprintf</code></a>:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">char</span> buf[<span style="color:#00D">10</span>];
|
||
snprintf(buf, <span style="color:#080;font-weight:bold">sizeof</span>(buf), <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">%s</span><span style="color:#710">"</span></span>, prefix);
|
||
snprintf(buf + strlen(buf), <span style="color:#080;font-weight:bold">sizeof</span>(buf) - strlen(buf), <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">%s</span><span style="color:#710">"</span></span>, data);</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In many cases, including this one, the string concatenation
|
||
can be avoided by combining everything into a single format
|
||
string:</p>
|
||
</div>
|
||
<div class="listingblock">
|
||
<div class="content">
|
||
<pre class="CodeRay highlight"><code data-lang="c">snprintf(buf, <span style="color:#080;font-weight:bold">sizeof</span>(buf), <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">%s%s</span><span style="color:#710">"</span></span>, prefix, data);</code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>But you should must not dynamically construct format strings
|
||
to avoid concatenation because this would prevent GCC from
|
||
type-checking the argument lists.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>It is not possible to use format strings like
|
||
<code>"%s%s"</code> to implement concatenation, unless
|
||
you use separate buffers. <code>snprintf</code> does
|
||
not support overlapping source and target strings.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="code-strlcpy-code-and-code-strlcat-code"><a class="anchor" href="#code-strlcpy-code-and-code-strlcat-code"></a><code>strlcpy</code> and <code>strlcat</code></h4>
|
||
<div class="paragraph">
|
||
<p>Some systems support <code>strlcpy</code> and
|
||
<code>strlcat</code> functions which behave this way,
|
||
but these functions are not part of GNU libc.
|
||
<code>strlcpy</code> is often replaced with
|
||
<code>snprintf</code> with a <code>"%s"</code>
|
||
format string. See <a href="#sect-Defensive_Coding-C-Libc-strncpy"><code>strncpy</code></a> for a caveat
|
||
related to the <code>snprintf</code> return value.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>To emulate <code>strlcat</code>, use the approach
|
||
described in <a href="#sect-Defensive_Coding-C-Libc-strncat"><code>strncat</code></a>.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="iso-c11-annex-k-code-_s-code-functions"><a class="anchor" href="#iso-c11-annex-k-code-_s-code-functions"></a>ISO C11 Annex K *<code>_s</code> functions</h4>
|
||
<div class="paragraph">
|
||
<p>ISO C11 adds another set of length-checking functions, but GNU
|
||
libc currently does not implement them.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="other-code-strn-code-and-code-stpn-code-functions"><a class="anchor" href="#other-code-strn-code-and-code-stpn-code-functions"></a>Other <code>strn*</code> and <code>stpn*</code> functions</h4>
|
||
<div class="paragraph">
|
||
<p>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.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="sect-Defensive_Coding-C-Allocators"><a class="anchor" href="#sect-Defensive_Coding-C-Allocators"></a>Memory Allocators</h2>
|
||
<div class="sectionbody">
|
||
<div class="sect2">
|
||
<h3 id="code-malloc-code-and-related-functions"><a class="anchor" href="#code-malloc-code-and-related-functions"></a><code>malloc</code> and Related Functions</h3>
|
||
<div class="paragraph">
|
||
<p>The C library interfaces for memory allocation are provided by
|
||
<code>malloc</code>, <code>free</code> and
|
||
<code>realloc</code>, and the
|
||
<code>calloc</code> function. In addition to these
|
||
generic functions, there are derived functions such as
|
||
<code>strdup</code> which perform allocation using
|
||
<code>malloc</code> internally, but do not return
|
||
untyped heap memory (which could be used for any object).</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The C compiler knows about these functions and can use their
|
||
expected behavior for optimizations. For instance, the compiler
|
||
assumes that an existing pointer (or a pointer derived from an
|
||
existing pointer by arithmetic) will not point into the memory
|
||
area returned by <code>malloc</code>.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>If the allocation fails, <code>realloc</code> does not
|
||
free the old pointer. Therefore, the idiom <code>ptr =
|
||
realloc(ptr, size);</code> is wrong because the memory
|
||
pointed to by <code>ptr</code> leaks in case of an error.</p>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="sect-Defensive_Coding-C-Use-After-Free"><a class="anchor" href="#sect-Defensive_Coding-C-Use-After-Free"></a>Use-after-free errors</h4>
|
||
<div class="paragraph">
|
||
<p>After <code>free</code>, the pointer is invalid.
|
||
Further pointer dereferences are not allowed (and are usually
|
||
detected by <strong class="application">valgrind</strong>). Less obvious
|
||
is that any <strong>use</strong> of the old pointer value is
|
||
not allowed, either. In particular, comparisons with any other
|
||
pointer (or the null pointer) are undefined according to the C
|
||
standard.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>The same rules apply to <code>realloc</code> if the
|
||
memory area cannot be enlarged in-place. For instance, the
|
||
compiler may assume that a comparison between the old and new
|
||
pointer will always return false, so it is impossible to detect
|
||
movement this way.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect3">
|
||
<h4 id="handling-memory-allocation-errors"><a class="anchor" href="#handling-memory-allocation-errors"></a>Handling Memory Allocation Errors</h4>
|
||
<div class="paragraph">
|
||
<p>Recovering from out-of-memory errors is often difficult or even
|
||
impossible. In these cases, <code>malloc</code> and
|
||
other allocation functions return a null pointer. Dereferencing
|
||
this pointer lead to a crash. Such dereferences can even be
|
||
exploitable for code execution if the dereference is combined
|
||
with an array subscript.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In general, if you cannot check all allocation calls and
|
||
handle failure, you should abort the program on allocation
|
||
failure, and not rely on the null pointer dereference to
|
||
terminate the process. See
|
||
<a href="#sect-Defensive_Coding-Tasks-Serialization-Decoders">[sect-Defensive_Coding-Tasks-Serialization-Decoders]</a>
|
||
for related memory allocation concerns.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Allocators-alloca"><a class="anchor" href="#sect-Defensive_Coding-C-Allocators-alloca"></a><code>alloca</code> and Other Forms of Stack-based Allocation</h3>
|
||
<div class="paragraph">
|
||
<p>Allocation on the stack is risky because stack overflow checking
|
||
is implicit. There is a guard page at the end of the memory
|
||
area reserved for the stack. If the program attempts to read
|
||
from or write to this guard page, a <code>SIGSEGV</code>
|
||
signal is generated and the program typically terminates.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>This is sufficient for detecting typical stack overflow
|
||
situations such as unbounded recursion, but it fails when the
|
||
stack grows in increments larger than the size of the guard
|
||
page. In this case, it is possible that the stack pointer ends
|
||
up pointing into a memory area which has been allocated for a
|
||
different purposes. Such misbehavior can be exploitable.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>A common source for large stack growth are calls to
|
||
<code>alloca</code> and related functions such as
|
||
<code>strdupa</code>. These functions should be avoided
|
||
because of the lack of error checking. (They can be used safely
|
||
if the allocated size is less than the page size (typically,
|
||
4096 bytes), but this case is relatively rare.) Additionally,
|
||
relying on <code>alloca</code> makes it more difficult
|
||
to reorganize the code because it is not allowed to use the
|
||
pointer after the function calling <code>alloca</code>
|
||
has returned, even if this function has been inlined into its
|
||
caller.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Similar concerns apply to <strong>variable-length
|
||
arrays</strong> (VLAs), a feature of the C99 standard which
|
||
started as a GNU extension. For large objects exceeding the
|
||
page size, there is no error checking, either.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In both cases, negative or very large sizes can trigger a
|
||
stack-pointer wraparound, and the stack pointer and end up
|
||
pointing into caller stack frames, which is fatal and can be
|
||
exploitable.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>If you want to use <code>alloca</code> or VLAs for
|
||
performance reasons, consider using a small on-stack array (less
|
||
than the page size, large enough to fulfill most requests). If
|
||
the requested size is small enough, use the on-stack array.
|
||
Otherwise, call <code>malloc</code>. When exiting the
|
||
function, check if <code>malloc</code> had been called,
|
||
and free the buffer as needed.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Allocators-Arrays"><a class="anchor" href="#sect-Defensive_Coding-C-Allocators-Arrays"></a>Array Allocation</h3>
|
||
<div class="paragraph">
|
||
<p>When allocating arrays, it is important to check for overflows.
|
||
The <code>calloc</code> function performs such checks.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>If <code>malloc</code> or <code>realloc</code>
|
||
is used, the size check must be written manually. For instance,
|
||
to allocate an array of <code>n</code> elements of type
|
||
<code>T</code>, check that the requested size is not
|
||
greater than <code>((size_t) -1) / sizeof(T)</code>. See
|
||
<a href="#sect-Defensive_Coding-C-Arithmetic">Recommendations for Integer Arithmetic</a>.</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Allocators-Custom"><a class="anchor" href="#sect-Defensive_Coding-C-Allocators-Custom"></a>Custom Memory Allocators</h3>
|
||
<div class="paragraph">
|
||
<p>Custom memory allocates come in two forms: replacements for
|
||
<code>malloc</code>, and completely different interfaces
|
||
for memory management. Both approaches can reduce the
|
||
effectiveness of <strong class="application">valgrind</strong> and similar
|
||
tools, and the heap corruption detection provided by GNU libc, so
|
||
they should be avoided.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>Memory allocators are difficult to write and contain many
|
||
performance and security pitfalls.</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>When computing array sizes or rounding up allocation
|
||
requests (to the next allocation granularity, or for
|
||
alignment purposes), checks for arithmetic overflow are
|
||
required.</p>
|
||
</li>
|
||
<li>
|
||
<p>Size computations for array allocations need overflow
|
||
checking. See <a href="#sect-Defensive_Coding-C-Allocators-Arrays">Array Allocation</a>.</p>
|
||
</li>
|
||
<li>
|
||
<p>It can be difficult to beat well-tuned general-purpose
|
||
allocators. In micro benchmarks, pool allocators can show
|
||
huge wins, and size-specific pools can reduce internal
|
||
fragmentation. But often, utilization of individual pools
|
||
is poor, and external fragmentation increases the overall
|
||
memory usage.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="sect2">
|
||
<h3 id="conservative-garbage-collection"><a class="anchor" href="#conservative-garbage-collection"></a>Conservative Garbage Collection</h3>
|
||
<div class="paragraph">
|
||
<p>Garbage collection can be an alternative to explicit memory
|
||
management using <code>malloc</code> and
|
||
<code>free</code>. The Boehm-Dehmers-Weiser allocator
|
||
can be used from C programs, with minimal type annotations.
|
||
Performance is competitive with <code>malloc</code> on
|
||
64-bit architectures, especially for multi-threaded programs.
|
||
The stop-the-world pauses may be problematic for some real-time
|
||
applications, though.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>However, using a conservative garbage collector may reduce
|
||
opportunities for code reduce because once one library in a
|
||
program uses garbage collection, the whole process memory needs
|
||
to be subject to it, so that no pointers are missed. The
|
||
Boehm-Dehmers-Weiser collector also reserves certain signals for
|
||
internal use, so it is not fully transparent to the rest of the
|
||
program.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sect1">
|
||
<h2 id="sect-Defensive_Coding-C-Other"><a class="anchor" href="#sect-Defensive_Coding-C-Other"></a>Other C-related Topics</h2>
|
||
<div class="sectionbody">
|
||
<div class="sect2">
|
||
<h3 id="sect-Defensive_Coding-C-Wrapper-Functions"><a class="anchor" href="#sect-Defensive_Coding-C-Wrapper-Functions"></a>Wrapper Functions</h3>
|
||
<div class="paragraph">
|
||
<p>Some libraries provide wrappers for standard library functions.
|
||
Common cases include allocation functions such as
|
||
<code>xmalloc</code> which abort the process on
|
||
allocation failure (instead of returning a
|
||
<code>NULL</code> pointer), or alternatives to relatively
|
||
recent library additions such as <code>snprintf</code>
|
||
(along with implementations for systems which lack them).</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>In general, such wrappers are a bad idea, particularly if they
|
||
are not implemented as inline functions or preprocessor macros.
|
||
The compiler lacks knowledge of such wrappers outside the
|
||
translation unit which defines them, which means that some
|
||
optimizations and security checks are not performed. Adding
|
||
<code><em>attribute</em></code> annotations to function
|
||
declarations can remedy this to some extent, but these
|
||
annotations have to be maintained carefully for feature parity
|
||
with the standard implementation.</p>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>At the minimum, you should apply these attributes:</p>
|
||
</div>
|
||
<div class="ulist">
|
||
<ul>
|
||
<li>
|
||
<p>If you wrap function which accepts are GCC-recognized format
|
||
string (for example, a <code>printf</code>-style
|
||
function used for logging), you should add a suitable
|
||
<code>format</code> attribute, as in <a href="#ex-Defensive_Coding-C-String-Functions-format-Attribute">The <code>format</code> function attribute</a>.</p>
|
||
</li>
|
||
<li>
|
||
<p>If you wrap a function which carries a
|
||
<code>warn_unused_result</code> attribute and you
|
||
propagate its return value, your wrapper should be declared
|
||
with <code>warn_unused_result</code> as well.</p>
|
||
</li>
|
||
<li>
|
||
<p>Duplicating the buffer length checks based on the
|
||
<code>__builtin_object_size</code> GCC builtin is
|
||
desirable if the wrapper processes arrays. (This
|
||
functionality is used by the
|
||
<code>-D_FORTIFY_SOURCE=2</code> checks to guard
|
||
against static buffer overflows.) However, designing
|
||
appropriate interfaces and implementing the checks may not
|
||
be entirely straightforward.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="paragraph">
|
||
<p>For other attributes (such as <code>malloc</code>),
|
||
careful analysis and comparison with the compiler documentation
|
||
is required to check if propagating the attribute is
|
||
appropriate. Incorrectly applied attributes can result in
|
||
undesired behavioral changes in the compiled code.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="bottom" class="text-muted py-3" >
|
||
<div class="foot">
|
||
<div class="container">
|
||
<div class="row footerlinks">
|
||
<div class="col-sm-3 col-xs-6 widget">
|
||
<h3 class="widget-title">About</h3>
|
||
<div class="widget-body">
|
||
<dl>
|
||
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
|
||
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
|
||
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
|
||
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
|
||
</dl>
|
||
<ul class="list-inline">
|
||
<li>
|
||
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
|
||
</li>
|
||
<li>
|
||
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
|
||
</li>
|
||
<li>
|
||
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-sm-3 col-xs-6 widget">
|
||
<h3 class="widget-title uppercase">Download</h3>
|
||
<div class="widget-body">
|
||
<dl>
|
||
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
|
||
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
|
||
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
|
||
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
|
||
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
|
||
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">®</span></a></dd>
|
||
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
|
||
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-sm-3 col-xs-6 widget">
|
||
<h3 class="widget-title">Support</h3>
|
||
<div class="widget-body">
|
||
<dl>
|
||
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
|
||
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
|
||
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
|
||
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
|
||
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-sm-3 col-xs-6 widget">
|
||
<h3 class="widget-title">Join</h3>
|
||
<div class="widget-body">
|
||
<dl>
|
||
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
|
||
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
|
||
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
|
||
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
|
||
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
</div> <!-- /row of widgets -->
|
||
|
||
<div class="row">
|
||
<div class="col-md-2">
|
||
<div class="widget-body">
|
||
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-7">
|
||
<div class="widget-body">
|
||
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
|
||
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora »</a></p>
|
||
<p class="copy">© 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
|
||
</div>
|
||
</div>
|
||
</div> <!-- /row of widgets -->
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
||
<!-- Latest compiled and minified JavaScript -->
|
||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
||
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
|
||
<script type="text/javascript">
|
||
/*<![CDATA[*/
|
||
$(document).ready(function() {
|
||
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
|
||
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
|
||
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
|
||
}
|
||
});
|
||
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
|
||
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
|
||
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
|
||
}
|
||
});
|
||
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
|
||
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
|
||
});
|
||
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
|
||
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
|
||
});
|
||
});
|
||
/*]]>*/
|
||
</script>
|
||
</body>
|
||
</html> |