defensive-coding-guide/_package/main/master/en-US/programming-languages/Java.html

1109 lines
58 KiB
HTML
Raw Normal View History

<!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 Java 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 Java 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>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
<li><a class="" 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&nbsp;Language</a></li>
<li><a class=" active" 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>&nbsp;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>&nbsp;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 Java Programming Language</h2>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Java-Language"><a class="anchor" href="#sect-Defensive_Coding-Java-Language"></a>The Core Language</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Implementations of the Java programming language provide strong
memory safety, even in the presence of data races in concurrent
code. This prevents a large range of security vulnerabilities
from occurring, unless certain low-level features are used; see
<a href="#sect-Defensive_Coding-Java-LowLevel">Low-level Features of the Virtual Machine</a>.</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-Language-ReadArray"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-ReadArray"></a>Increasing Robustness when Reading Arrays</h3>
<div class="paragraph">
<p>External data formats often include arrays, and the data is
stored as an integer indicating the number of array elements,
followed by this number of elements in the file or protocol data
unit. This length specified can be much larger than what is
actually available in the data source.</p>
</div>
<div class="paragraph">
<p>To avoid allocating extremely large amounts of data, you can
allocate a small array initially and grow it as you read more
data, implementing an exponential growth policy. See the
<code>readBytes(InputStream, int)</code> function in
<a href="#ex-Defensive_Coding-Java-Language-ReadArray">Incrementally reading a byte array</a>.</p>
</div>
<div id="ex-Defensive_Coding-Java-Language-ReadArray" class="exampleblock">
<div class="title">Example 1. Incrementally reading a byte array</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#088;font-weight:bold">static</span> <span style="color:#339;font-weight:bold">byte</span><span style="color:#339;font-weight:bold">[]</span> readBytes(<span style="color:#0a8;font-weight:bold">InputStream</span> in, <span style="color:#339;font-weight:bold">int</span> length) <span style="color:#088;font-weight:bold">throws</span> <span style="color:#C00;font-weight:bold">IOException</span> {
<span style="color:#088;font-weight:bold">final</span> <span style="color:#339;font-weight:bold">int</span> startSize = <span style="color:#00D">65536</span>;
<span style="color:#339;font-weight:bold">byte</span><span style="color:#339;font-weight:bold">[]</span> b = <span style="color:#080;font-weight:bold">new</span> <span style="color:#339;font-weight:bold">byte</span>[<span style="color:#0a8;font-weight:bold">Math</span>.min(length, startSize)];
<span style="color:#339;font-weight:bold">int</span> filled = <span style="color:#00D">0</span>;
<span style="color:#080;font-weight:bold">while</span> (<span style="color:#069">true</span>) {
<span style="color:#339;font-weight:bold">int</span> remaining = b.length - filled;
readFully(in, b, filled, remaining);
<span style="color:#080;font-weight:bold">if</span> (b.length == length) {
<span style="color:#080;font-weight:bold">break</span>;
}
filled = b.length;
<span style="color:#080;font-weight:bold">if</span> (length - b.length &lt;= b.length) {
<span style="color:#777">// Allocate final length. Condition avoids overflow.</span>
b = <span style="color:#0a8;font-weight:bold">Arrays</span>.copyOf(b, length);
} <span style="color:#080;font-weight:bold">else</span> {
b = <span style="color:#0a8;font-weight:bold">Arrays</span>.copyOf(b, b.length * <span style="color:#00D">2</span>);
}
}
<span style="color:#080;font-weight:bold">return</span> b;
}
<span style="color:#088;font-weight:bold">static</span> <span style="color:#339;font-weight:bold">void</span> readFully(<span style="color:#0a8;font-weight:bold">InputStream</span> in,<span style="color:#339;font-weight:bold">byte</span><span style="color:#339;font-weight:bold">[]</span> b, <span style="color:#339;font-weight:bold">int</span> off, <span style="color:#339;font-weight:bold">int</span> len)
<span style="color:#088;font-weight:bold">throws</span> <span style="color:#C00;font-weight:bold">IOException</span> {
<span style="color:#339;font-weight:bold">int</span> startlen = len;
<span style="color:#080;font-weight:bold">while</span> (len &gt; <span style="color:#00D">0</span>) {
<span style="color:#339;font-weight:bold">int</span> count = in.read(b, off, len);
<span style="color:#080;font-weight:bold">if</span> (count &lt; <span style="color:#00D">0</span>) {
<span style="color:#080;font-weight:bold">throw</span> <span style="color:#080;font-weight:bold">new</span> <span style="color:#C00;font-weight:bold">EOFException</span>();
}
off += count;
len -= count;
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>When reading data into arrays, hash maps or hash sets, use the
default constructor and do not specify a size hint. You can
simply add the elements to the collection as you read them.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-Language-Resources"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Resources"></a>Resource Management</h3>
<div class="paragraph">
<p>Unlike C++, Java does not offer destructors which can deallocate
resources in a predictable fashion. All resource management has
to be manual, at the usage site. (Finalizers are generally not
usable for resource management, especially in high-performance
code; see <a href="#sect-Defensive_Coding-Java-Language-Finalizers">Finalizers</a>.)</p>
</div>
<div class="paragraph">
<p>The first option is the
<code>try</code>-<code>finally</code> construct, as
shown in <a href="#ex-Defensive_Coding-Java-Language-Finally">Resource management with a <code>try</code>-<code>finally</code> block</a>.
The code in the <code>finally</code> block should be as short as
possible and should not throw any exceptions.</p>
</div>
<div id="ex-Defensive_Coding-Java-Language-Finally" class="exampleblock">
<div class="title">Example 2. Resource management with a <code>try</code>-<code>finally</code> block</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#0a8;font-weight:bold">InputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">BufferedInputStream</span>(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path));
<span style="color:#080;font-weight:bold">try</span> {
readFile(in);
} <span style="color:#080;font-weight:bold">finally</span> {
in.close();
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Note that the resource allocation happens
<strong>outside</strong> the <code>try</code> block,
and that there is no <code>null</code> check in the
<code>finally</code> block. (Both are common artifacts
stemming from IDE code templates.)</p>
</div>
<div class="paragraph">
<p>If the resource object is created freshly and implements the
<code>java.lang.AutoCloseable</code> interface, the code
in <a href="#ex-Defensive_Coding-Java-Language-TryWithResource">Resource management using the <code>try</code>-with-resource construct</a> can be
used instead. The Java compiler will automatically insert the
<code>close()</code> method call in a synthetic
<code>finally</code> block.</p>
</div>
<div id="ex-Defensive_Coding-Java-Language-TryWithResource" class="exampleblock">
<div class="title">Example 3. Resource management using the <code>try</code>-with-resource construct</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#080;font-weight:bold">try</span> (<span style="color:#0a8;font-weight:bold">InputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">BufferedInputStream</span>(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path))) {
readFile(in);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To be compatible with the <code>try</code>-with-resource
construct, new classes should name the resource deallocation
method <code>close()</code>, and implement the
<code>AutoCloseable</code> interface (the latter breaking
backwards compatibility with Java 6). However, using the
<code>try</code>-with-resource construct with objects that
are not freshly allocated is at best awkward, and an explicit
<code>finally</code> block is usually the better approach.</p>
</div>
<div class="paragraph">
<p>In general, it is best to design the programming interface in
such a way that resource deallocation methods like
<code>close()</code> cannot throw any (checked or
unchecked) exceptions, but this should not be a reason to ignore
any actual error conditions.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-Language-Finalizers"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Finalizers"></a>Finalizers</h3>
<div class="paragraph">
<p>Finalizers can be used a last-resort approach to free resources
which would otherwise leak. Finalization is unpredictable,
costly, and there can be a considerable delay between the last
reference to an object going away and the execution of the
finalizer. Generally, manual resource management is required;
see <a href="#sect-Defensive_Coding-Java-Language-Resources">Resource Management</a>.</p>
</div>
<div class="paragraph">
<p>Finalizers should be very short and should only deallocate
native or other external resources held directly by the object
being finalized. In general, they must use synchronization:
Finalization necessarily happens on a separate thread because it is
inherently concurrent. There can be multiple finalization
threads, and despite each object being finalized at most once,
the finalizer must not assume that it has exclusive access to
the object being finalized (in the <code>this</code>
pointer).</p>
</div>
<div class="paragraph">
<p>Finalizers should not deallocate resources held by other
objects, especially if those objects have finalizers on their
own. In particular, it is a very bad idea to define a finalizer
just to invoke the resource deallocation method of another object,
or overwrite some pointer fields.</p>
</div>
<div class="paragraph">
<p>Finalizers are not guaranteed to run at all. For instance, the
virtual machine (or the machine underneath) might crash,
preventing their execution.</p>
</div>
<div class="paragraph">
<p>Objects with finalizers are garbage-collected much later than
objects without them, so using finalizers to zero out key
material (to reduce its undecrypted lifetime in memory) may have
the opposite effect, keeping objects around for much longer and
prevent them from being overwritten in the normal course of
program execution.</p>
</div>
<div class="paragraph">
<p>For the same reason, code which allocates objects with
finalizers at a high rate will eventually fail (likely with a
<code>java.lang.OutOfMemoryError</code> exception) because
the virtual machine has finite resources for keeping track of
objects pending finalization. To deal with that, it may be
necessary to recycle objects with finalizers.</p>
</div>
<div class="paragraph">
<p>The remarks in this section apply to finalizers which are
implemented by overriding the <code>finalize()</code>
method, and to custom finalization using reference queues.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-Language-Exceptions"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Exceptions"></a>Recovering from Exceptions and Errors</h3>
<div class="paragraph">
<p>Java exceptions come in three kinds, all ultimately deriving
from <code>java.lang.Throwable</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Run-time exceptions</strong> do not have to be
declared explicitly and can be explicitly thrown from any
code, by calling code which throws them, or by triggering an
error condition at run time, like division by zero, or an
attempt at an out-of-bounds array access. These exceptions
derive from from the
<code>java.lang.RuntimeException</code> class (perhaps
indirectly).</p>
</li>
<li>
<p><strong>Checked exceptions</strong> have to be declared
explicitly by functions that throw or propagate them. They
are similar to run-time exceptions in other regards, except
that there is no language construct to throw them (except
the <code>throw</code> statement itself). Checked
exceptions are only present at the Java language level and
are only enforced at compile time. At run time, the virtual
machine does not know about them and permits throwing
exceptions from any code. Checked exceptions must derive
(perhaps indirectly) from the
<code>java.lang.Exception</code> class, but not from
<code>java.lang.RuntimeException</code>.</p>
</li>
<li>
<p><strong>Errors</strong> are exceptions which typically
reflect serious error conditions. They can be thrown at any
point in the program, and do not have to be declared (unlike
checked exceptions). In general, it is not possible to
recover from such errors; more on that below, in <a href="#sect-Defensive_Coding-Java-Language-Exceptions-Errors">The Difficulty of Catching Errors</a>.
Error classes derive (perhaps indirectly) from
<code>java.lang.Error</code>, or from
<code>java.lang.Throwable</code>, but not from
<code>java.lang.Exception</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The general expection is that run-time errors are avoided by
careful programming (e.g., not dividing by zero). Checked
exception are expected to be caught as they happen (e.g., when
an input file is unexpectedly missing). Errors are impossible
to predict and can happen at any point and reflect that
something went wrong beyond all expectations.</p>
</div>
<div class="sect3">
<h4 id="sect-Defensive_Coding-Java-Language-Exceptions-Errors"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Exceptions-Errors"></a>The Difficulty of Catching Errors</h4>
<div class="paragraph">
<p>Errors (that is, exceptions which do not (indirectly) derive
from <code>java.lang.Exception</code>), have the
peculiar property that catching them is problematic. There
are several reasons for this:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The error reflects a failed consistenty check, for example,
<code>java.lang.AssertionError</code>.</p>
</li>
<li>
<p>The error can happen at any point, resulting in
inconsistencies due to half-updated objects. Examples are
<code>java.lang.ThreadDeath</code>,
<code>java.lang.OutOfMemoryError</code> and
<code>java.lang.StackOverflowError</code>.</p>
</li>
<li>
<p>The error indicates that virtual machine failed to provide
some semantic guarantees by the Java programming language.
<code>java.lang.ExceptionInInitializerError</code>
is an example—it can leave behind a half-initialized
class.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In general, if an error is thrown, the virtual machine should
be restarted as soon as possible because it is in an
inconsistent state. Continuing running as before can have
unexpected consequences. However, there are legitimate
reasons for catching errors because not doing so leads to even
greater problems.</p>
</div>
<div class="paragraph">
<p>Code should be written in a way that avoids triggering errors.
See <a href="#sect-Defensive_Coding-Java-Language-ReadArray">Increasing Robustness when Reading Arrays</a>
for an example.</p>
</div>
<div class="paragraph">
<p>It is usually necessary to log errors. Otherwise, no trace of
the problem might be left anywhere, making it very difficult
to diagnose realted failures. Consequently, if you catch
<code>java.lang.Exception</code> to log and suppress all
unexpected exceptions (for example, in a request dispatching
loop), you should consider switching to
<code>java.lang.Throwable</code> instead, to also cover
errors.</p>
</div>
<div class="paragraph">
<p>The other reason mainly applies to such request dispatching
loops: If you do not catch errors, the loop stops looping,
resulting in a denial of service.</p>
</div>
<div class="paragraph">
<p>However, if possible, catching errors should be coupled with a
way to signal the requirement of a virtual machine restart.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Java-LowLevel"><a class="anchor" href="#sect-Defensive_Coding-Java-LowLevel"></a>Low-level Features of the Virtual Machine</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-Reflection"><a class="anchor" href="#sect-Defensive_Coding-Java-Reflection"></a>Reflection and Private Parts</h3>
<div class="paragraph">
<p>The <code>setAccessible(boolean)</code> method of the
<code>java.lang.reflect.AccessibleObject</code> class
allows a program to disable language-defined access rules for
specific constructors, methods, or fields. Once the access
checks are disabled, any code can use the
<code>java.lang.reflect.Constructor</code>,
<code>java.lang.reflect.Method</code>, or
<code>java.lang.reflect.Field</code> object to access the
underlying Java entity, without further permission checks. This
breaks encapsulation and can undermine the stability of the
virtual machine. (In contrast, without using the
<code>setAccessible(boolean)</code> method, this should
not happen because all the language-defined checks still apply.)</p>
</div>
<div class="paragraph">
<p>This feature should be avoided if possible.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-JNI"><a class="anchor" href="#sect-Defensive_Coding-Java-JNI"></a>Java Native Interface (JNI)</h3>
<div class="paragraph">
<p>The Java Native Interface allows calling from Java code
functions specifically written for this purpose, usually in C or
C++.</p>
</div>
<div class="paragraph">
<p>The transition between the Java world and the C world is not
fully type-checked, and the C code can easily break the Java
virtual machine semantics. Therefore, extra care is needed when
using this functionality.</p>
</div>
<div class="paragraph">
<p>To provide a moderate amount of type safety, it is recommended
to recreate the class-specific header file using
<strong class="application">javah</strong> during the build process,
include it in the implementation, and use the
<code class="option">-Wmissing-declarations</code> option.</p>
</div>
<div class="paragraph">
<p>Ideally, the required data is directly passed to static JNI
methods and returned from them, and the code and the C side does
not have to deal with accessing Java fields (or even methods).</p>
</div>
<div class="paragraph">
<p>When using <code>GetPrimitiveArrayCritical</code> or
<code>GetStringCritical</code>, make sure that you only
perform very little processing between the get and release
operations. Do not access the file system or the network, and
not perform locking, because that might introduce blocking.
When processing large strings or arrays, consider splitting the
computation into multiple sub-chunks, so that you do not prevent
the JVM from reaching a safepoint for extended periods of time.</p>
</div>
<div class="paragraph">
<p>If necessary, you can use the Java <code>long</code> type
to store a C pointer in a field of a Java class. On the C side,
when casting between the <code>jlong</code> value and the
pointer on the C side,</p>
</div>
<div class="paragraph">
<p>You should not try to perform pointer arithmetic on the Java
side (that is, you should treat pointer-carrying
<code>long</code> values as opaque). When passing a slice
of an array to the native code, follow the Java convention and
pass it as the base array, the integer offset of the start of
the slice, and the integer length of the slice. On the native
side, check the offset/length combination against the actual
array length, and use the offset to compute the pointer to the
beginning of the array.</p>
</div>
<div id="ex-Defensive_Coding-Java-JNI-Pointers" class="exampleblock">
<div class="title">Example 4. Array length checking in JNI code</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JNIEXPORT jint JNICALL Java_sum
(JNIEnv *jEnv, jclass clazz, jbyteArray buffer, jint offset, jint length)
{
<span style="color:#080;font-weight:bold">assert</span>(sizeof(jint) == sizeof(unsigned));
<span style="color:#080;font-weight:bold">if</span> (offset &lt; <span style="color:#00D">0</span> || length &lt; <span style="color:#00D">0</span>) {
(*jEnv)-&gt;ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,
<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">negative offset/length</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
}
unsigned uoffset = offset;
unsigned ulength = length;
<span style="color:#777">// This cannot overflow because of the check above.</span>
unsigned totallength = uoffset + ulength;
unsigned actuallength = (*jEnv)-&gt;GetArrayLength(jEnv, buffer);
<span style="color:#080;font-weight:bold">if</span> (totallength &gt; actuallength) {
(*jEnv)-&gt;ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,
<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">offset + length too large</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
}
unsigned <span style="color:#339;font-weight:bold">char</span> *ptr = (*jEnv)-&gt;GetPrimitiveArrayCritical(jEnv, buffer, <span style="color:#00D">0</span>);
<span style="color:#080;font-weight:bold">if</span> (ptr == NULL) {
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
}
unsigned <span style="color:#339;font-weight:bold">long</span> <span style="color:#339;font-weight:bold">long</span> sum = <span style="color:#00D">0</span>;
<span style="color:#080;font-weight:bold">for</span> (unsigned <span style="color:#339;font-weight:bold">char</span> *p = ptr + uoffset, *end = p + ulength; p != end; ++p) {
sum += *p;
}
(*jEnv)-&gt;ReleasePrimitiveArrayCritical(jEnv, buffer, ptr, <span style="color:#00D">0</span>);
<span style="color:#080;font-weight:bold">return</span> sum;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In any case, classes referring to native resources must be
declared <code>final</code>, and must not be serializeable
or cloneable. Initialization and mutation of the state used by
the native side must be controlled carefully. Otherwise, it
might be possible to create an object with inconsistent native
state which results in a crash (or worse) when used (or perhaps
only finalized) later. If you need both Java inheritance and
native resources, you should consider moving the native state to
a separate class, and only keep a reference to objects of that
class. This way, cloning and serialization issues can be
avoided in most cases.</p>
</div>
<div class="paragraph">
<p>If there are native resources associated with an object, the
class should have an explicit resource deallocation method
(<a href="#sect-Defensive_Coding-Java-Language-Resources">Resource Management</a>) and a
finalizer (<a href="#sect-Defensive_Coding-Java-Language-Finalizers">Finalizers</a>) as a
last resort. The need for finalization means that a minimum
amount of synchronization is needed. Code on the native side
should check that the object is not in a closed/freed state.</p>
</div>
<div class="paragraph">
<p>Many JNI functions create local references. By default, these
persist until the JNI-implemented method returns. If you create
many such references (e.g., in a loop), you may have to free
them using <code>DeleteLocalRef</code>, or start using
<code>PushLocalFrame</code> and
<code>PopLocalFrame</code>. Global references must be
deallocated with <code>DeleteGlobalRef</code>, otherwise
there will be a memory leak, just as with
<code>malloc</code> and <code>free</code>.</p>
</div>
<div class="paragraph">
<p>When throwing exceptions using <code>Throw</code> or
<code>ThrowNew</code>, be aware that these functions
return regularly. You have to return control manually to the
JVM.</p>
</div>
<div class="paragraph">
<p>Technically, the <code>JNIEnv</code> pointer is not
necessarily constant during the lifetime of your JNI module.
Storing it in a global variable is therefore incorrect.
Particularly if you are dealing with callbacks, you may have to
store the pointer in a thread-local variable (defined with
<code>__thread</code>). It is, however, best to avoid the
complexity of calling back into Java code.</p>
</div>
<div class="paragraph">
<p>Keep in mind that C/C and Java are different languages,
despite very similar syntax for expressions. The Java memory
model is much more strict than the C or C memory models, and
native code needs more synchronization, usually using JVM
facilities or POSIX threads mutexes. Integer overflow in Java
is defined, but in C/C++ it is not (for the
<code>jint</code> and <code>jlong</code> types).</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-MiscUnsafe"><a class="anchor" href="#sect-Defensive_Coding-Java-MiscUnsafe"></a><code>sun.misc.Unsafe</code></h3>
<div class="paragraph">
<p>The <code>sun.misc.Unsafe</code> class is unportable and
contains many functions explicitly designed to break Java memory
safety (for performance and debugging). If possible, avoid
using this class.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-Java-SecurityManager"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager"></a>Interacting with the Security Manager</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Java platform is largely implemented in the Java language
itself. Therefore, within the same JVM, code runs which is part
of the Java installation and which is trusted, but there might
also be code which comes from untrusted sources and is restricted
by the Java sandbox (to varying degrees). The <strong>security
manager</strong> draws a line between fully trusted, partially
trusted and untrusted code.</p>
</div>
<div class="paragraph">
<p>The type safety and accessibility checks provided by the Java
language and JVM would be sufficient to implement a sandbox.
However, only some Java APIs employ such a capabilities-based
approach. (The Java SE library contains many public classes with
public constructors which can break any security policy, such as
<code>java.io.FileOutputStream</code>.) Instead, critical
functionality is protected by <strong>stack
inspection</strong>: At a security check, the stack is walked
from top (most-nested) to bottom. The security check fails if a
stack frame for a method is encountered whose class lacks the
permission which the security check requires.</p>
</div>
<div class="paragraph">
<p>This simple approach would not allow untrusted code (which lacks
certain permissions) to call into trusted code while the latter
retains trust. Such trust transitions are desirable because they
enable Java as an implementation language for most parts of the
Java platform, including security-relevant code. Therefore, there
is a mechanism to mark certain stack frames as trusted (<a href="#sect-Defensive_Coding-Java-SecurityManager-Privileged">Re-gaining Privileges</a>).</p>
</div>
<div class="paragraph">
<p>In theory, it is possible to run a Java virtual machine with a
security manager that acts very differently from this approach,
but a lot of code expects behavior very close to the platform
default (including many classes which are part of the OpenJDK
implementation).</p>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Compatible"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Compatible"></a>Security Manager Compatibility</h3>
<div class="paragraph">
<p>A lot of code can run without any additional permissions at all,
with little changes. The following guidelines should help to
increase compatibility with a restrictive security manager.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>When retrieving system properties using
<code>System.getProperty(String)</code> or similar
methods, catch <code>SecurityException</code>
exceptions and treat the property as unset.</p>
</li>
<li>
<p>Avoid unnecessary file system or network access.</p>
</li>
<li>
<p>Avoid explicit class loading. Access to a suitable class
loader might not be available when executing as untrusted
code.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the functionality you are implementing absolutely requires
privileged access and this functionality has to be used from
untrusted code (hopefully in a restricted and secure manner),
see <a href="#sect-Defensive_Coding-Java-SecurityManager-Privileged">Re-gaining Privileges</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Activate"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Activate"></a>Activating the Security Manager</h3>
<div class="paragraph">
<p>The usual command to launch a Java application,
<code class="command">java</code>, does not activate the security manager.
Therefore, the virtual machine does not enforce any sandboxing
restrictions, even if explicitly requested by the code (for
example, as described in <a href="#sect-Defensive_Coding-Java-SecurityManager-Unprivileged">Reducing Trust in Code</a>).</p>
</div>
<div class="paragraph">
<p>The <code class="option">-Djava.security.manager</code> option activates
the security manager, with the fairly restrictive default
policy. With a very permissive policy, most Java code will run
unchanged. Assuming the policy in <a href="#ex-Defensive_Coding-Java-SecurityManager-GrantAll">Most permissve OpenJDK policy file</a>
has been saved in a file <code>grant-all.policy</code>,
this policy can be activated using the option
<code class="option">-Djava.security.policy=grant-all.policy</code> (in
addition to the <code class="option">-Djava.security.manager</code>
option).</p>
</div>
<div id="ex-Defensive_Coding-Java-SecurityManager-GrantAll" class="exampleblock">
<div class="title">Example 5. Most permissve OpenJDK policy file</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">grant {
permission java.security.AllPermission;
};</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>With this most permissive policy, the security manager is still
active, and explicit requests to drop privileges will be
honored.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Unprivileged"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Unprivileged"></a>Reducing Trust in Code</h3>
<div class="paragraph">
<p>The <a href="#ex-Defensive_Coding-Java-SecurityManager-Unprivileged">Using the security manager to run code with reduced privileges</a> example
shows how to run a piece code of with reduced privileges.</p>
</div>
<div id="ex-Defensive_Coding-Java-SecurityManager-Unprivileged" class="exampleblock">
<div class="title">Example 6. Using the security manager to run code with reduced privileges</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#0a8;font-weight:bold">Permissions</span> permissions = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">Permissions</span>();
<span style="color:#0a8;font-weight:bold">ProtectionDomain</span> protectionDomain =
<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">ProtectionDomain</span>(<span style="color:#069">null</span>, permissions);
<span style="color:#0a8;font-weight:bold">AccessControlContext</span> context = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">AccessControlContext</span>(
<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">ProtectionDomain</span><span style="color:#339;font-weight:bold">[]</span> { protectionDomain });
<span style="color:#777">// This is expected to succeed.</span>
<span style="color:#080;font-weight:bold">try</span> (<span style="color:#0a8;font-weight:bold">FileInputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path)) {
<span style="color:#0a8;font-weight:bold">System</span>.out.format(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">FileInputStream: %s%n</span><span style="color:#710">&quot;</span></span>, in);
}
<span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedExceptionAction</span>&lt;<span style="color:#0a8;font-weight:bold">Void</span>&gt;() {
<span style="color:#007">@Override</span>
<span style="color:#088;font-weight:bold">public</span> <span style="color:#0a8;font-weight:bold">Void</span> run() <span style="color:#088;font-weight:bold">throws</span> <span style="color:#C00;font-weight:bold">Exception</span> {
<span style="color:#777">// This code runs with reduced privileges and is</span>
<span style="color:#777">// expected to fail.</span>
<span style="color:#080;font-weight:bold">try</span> (<span style="color:#0a8;font-weight:bold">FileInputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path)) {
<span style="color:#0a8;font-weight:bold">System</span>.out.format(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">FileInputStream: %s%n</span><span style="color:#710">&quot;</span></span>, in);
}
<span style="color:#080;font-weight:bold">return</span> <span style="color:#069">null</span>;
}
}, context);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The example above does not add any additional permissions to the
<code>permissions</code> object. If such permissions are
necessary, code like the following (which grants read permission
on all files in the current directory) can be used:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">permissions.add(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FilePermission</span>(
<span style="color:#0a8;font-weight:bold">System</span>.getProperty(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">user.dir</span><span style="color:#710">&quot;</span></span>) + <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">/-</span><span style="color:#710">&quot;</span></span>, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">read</span><span style="color:#710">&quot;</span></span>));</code></pre>
</div>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Calls to the
<code>java.security.AccessController.doPrivileged()</code>
methods do not enforce any additional restriction if no
security manager has been set. Except for a few special
exceptions, the restrictions no longer apply if the
<code>doPrivileged()</code> has returned, even to
objects created by the code which ran with reduced privileges.
(This applies to object finalization in particular.)</p>
</div>
<div class="paragraph">
<p>The example code above does not prevent the called code from
calling the
<code>java.security.AccessController.doPrivileged()</code>
methods. This mechanism should be considered an additional
safety net, but it still can be used to prevent unexpected
behavior of trusted code. As long as the executed code is not
dynamic and came with the original application or library, the
sandbox is fairly effective.</p>
</div>
<div class="paragraph">
<p>The <code>context</code> argument in <a href="#ex-Defensive_Coding-Java-SecurityManager-Unprivileged">Using the security manager to run code with reduced privileges</a>
is extremely important—otherwise, this code would increase
privileges instead of reducing them.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>For activating the security manager, see <a href="#sect-Defensive_Coding-Java-SecurityManager-Activate">Activating the Security Manager</a>.
Unfortunately, this affects the virtual machine as a whole, so
it is not possible to do this from a library.</p>
</div>
</div>
<div class="sect2">
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Privileged"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Privileged"></a>Re-gaining Privileges</h3>
<div class="paragraph">
<p>Ordinarily, when trusted code is called from untrusted code, it
loses its privileges (because of the untrusted stack frames
visible to stack inspection). The
<code>java.security.AccessController.doPrivileged()</code>
family of methods provides a controlled backdoor from untrusted
to trusted code.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>By design, this feature can undermine the Java security model
and the sandbox. It has to be used very carefully. Most
sandbox vulnerabilities can be traced back to its misuse.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>In essence, the <code>doPrivileged()</code> methods
cause the stack inspection to end at their call site. Untrusted
code further down the call stack becomes invisible to security
checks.</p>
</div>
<div class="paragraph">
<p>The following operations are common and safe to perform with
elevated privileges.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Reading custom system properties with fixed names,
especially if the value is not propagated to untrusted code.
(File system paths including installation paths, host names
and user names are sometimes considered private information
and need to be protected.)</p>
</li>
<li>
<p>Reading from the file system at fixed paths, either
determined at compile time or by a system property. Again,
leaking the file contents to the caller can be problematic.</p>
</li>
<li>
<p>Accessing network resources under a fixed address, name or
URL, derived from a system property or configuration file,
information leaks not withstanding.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <a href="#ex-Defensive_Coding-Java-SecurityManager-Privileged">Using the security manager to run code with increased privileges</a> example
shows how to request additional privileges.</p>
</div>
<div id="ex-Defensive_Coding-Java-SecurityManager-Privileged" class="exampleblock">
<div class="title">Example 7. Using the security manager to run code with increased privileges</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#777">// This is expected to fail.</span>
<span style="color:#080;font-weight:bold">try</span> {
<span style="color:#0a8;font-weight:bold">System</span>.out.println(<span style="color:#0a8;font-weight:bold">System</span>.getProperty(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">user.home</span><span style="color:#710">&quot;</span></span>));
} <span style="color:#080;font-weight:bold">catch</span> (<span style="color:#C00;font-weight:bold">SecurityException</span> e) {
e.printStackTrace(<span style="color:#0a8;font-weight:bold">System</span>.err);
}
<span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedAction</span>&lt;<span style="color:#0a8;font-weight:bold">Void</span>&gt;() {
<span style="color:#088;font-weight:bold">public</span> <span style="color:#0a8;font-weight:bold">Void</span> run() {
<span style="color:#777">// This should work.</span>
<span style="color:#0a8;font-weight:bold">System</span>.out.println(<span style="color:#0a8;font-weight:bold">System</span>.getProperty(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">user.home</span><span style="color:#710">&quot;</span></span>));
<span style="color:#080;font-weight:bold">return</span> <span style="color:#069">null</span>;
}
});</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Obviously, this only works if the class containing the call to
<code>doPrivileged()</code> is marked trusted (usually
because it is loaded from a trusted class loader).</p>
</div>
<div class="paragraph">
<p>When writing code that runs with elevated privileges, make sure
that you follow the rules below.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Make the privileged code as small as possible. Perform as
many computations as possible before and after the
privileged code section, even if it means that you have to
define a new class to pass the data around.</p>
</li>
<li>
<p>Make sure that you either control the inputs to the
privileged code, or that the inputs are harmless and cannot
affect security properties of the privileged code.</p>
</li>
<li>
<p>Data that is returned from or written by the privileged code
must either be restricted (that is, it cannot be accessed by
untrusted code), or must be harmless. Otherwise, privacy
leaks or information disclosures which affect security
properties can be the result.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the code calls back into untrusted code at a later stage (or
performs other actions under control from the untrusted caller),
you must obtain the original security context and restore it
before performing the callback, as in <a href="#ex-Defensive_Coding-Java-SecurityManager-Callback">Restoring privileges when invoking callbacks</a>.
(In this example, it would be much better to move the callback
invocation out of the privileged code section, of course.)</p>
</div>
<div id="ex-Defensive_Coding-Java-SecurityManager-Callback" class="exampleblock">
<div class="title">Example 8. Restoring privileges when invoking callbacks</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#339;font-weight:bold">interface</span> <span style="color:#B06;font-weight:bold">Callback</span>&lt;T&gt; {
T call(<span style="color:#339;font-weight:bold">boolean</span> flag);
}
<span style="color:#339;font-weight:bold">class</span> <span style="color:#B06;font-weight:bold">CallbackInvoker</span>&lt;T&gt; {
<span style="color:#088;font-weight:bold">private</span> <span style="color:#088;font-weight:bold">final</span> <span style="color:#0a8;font-weight:bold">AccessControlContext</span> context;
<span style="color:#0a8;font-weight:bold">Callback</span>&lt;T&gt; callback;
CallbackInvoker(<span style="color:#0a8;font-weight:bold">Callback</span>&lt;T&gt; callback) {
context = <span style="color:#0a8;font-weight:bold">AccessController</span>.getContext();
<span style="color:#950">this</span>.callback = callback;
}
<span style="color:#088;font-weight:bold">public</span> T invoke() {
<span style="color:#777">// Obtain increased privileges.</span>
<span style="color:#080;font-weight:bold">return</span> <span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedAction</span>&lt;T&gt;() {
<span style="color:#007">@Override</span>
<span style="color:#088;font-weight:bold">public</span> T run() {
<span style="color:#777">// This operation would fail without</span>
<span style="color:#777">// additional privileges.</span>
<span style="color:#088;font-weight:bold">final</span> <span style="color:#339;font-weight:bold">boolean</span> flag = <span style="color:#0a8;font-weight:bold">Boolean</span>.getBoolean(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">some.property</span><span style="color:#710">&quot;</span></span>);
<span style="color:#777">// Restore the original privileges.</span>
<span style="color:#080;font-weight:bold">return</span> <span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(
<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedAction</span>&lt;T&gt;() {
<span style="color:#007">@Override</span>
<span style="color:#088;font-weight:bold">public</span> T run() {
<span style="color:#080;font-weight:bold">return</span> callback.call(flag);
}
}, context);
}
});
}
}</code></pre>
</div>
</div>
</div>
</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">&reg;</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 &raquo;</a></p>
<p class="copy">&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>