defensive-coding-guide/_package/main/master/en-US/tasks/Tasks-Temporary_Files.html
Brian (bex) Exelbierd 2e8934be40 Converted to AsciiBinder
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
2018-02-08 13:08:40 +01:00

472 lines
No EOL
22 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 | Specific Programming Tasks | Temporary Files</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/tasks/Tasks-Library_Design.html">Specific Programming Tasks</a></li>
<li class="hidden-xs active">
Temporary Files
</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-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<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="" 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-down"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse in">
<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=" active" 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>Temporary Files</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>In this chapter, we describe how to create temporary files and
directories, how to remove them, and how to work with programs
which do not create files in ways that are safe with a shared
directory for temporary files. General file system manipulation
is treated in a separate chapter, <a href="#chap-Defensive_Coding-Tasks-File_System">[chap-Defensive_Coding-Tasks-File_System]</a>.</p>
</div>
<div class="paragraph">
<p>Secure creation of temporary files has four different aspects.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The location of the directory for temporary files must be
obtained in a secure manner (that is, untrusted environment
variables must be ignored, see <a href="#sect-Defensive_Coding-Tasks-secure_getenv">[sect-Defensive_Coding-Tasks-secure_getenv]</a>).</p>
</li>
<li>
<p>A new file must be created. Reusing an existing file must be
avoided (the <code>/tmp</code> race
condition). This is tricky because traditionally, system-wide
temporary directories shared by all users are used.</p>
</li>
<li>
<p>The file must be created in a way that makes it impossible for
other users to open it.</p>
</li>
<li>
<p>The descriptor for the temporary file should not leak to
subprocesses.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>All functions mentioned below will take care of these aspects.</p>
</div>
<div class="paragraph">
<p>Traditionally, temporary files are often used to reduce memory
usage of programs. More and more systems use RAM-based file
systems such as <code>tmpfs</code> for storing temporary
files, to increase performance and decrease wear on Flash storage.
As a result, spooling data to temporary files does not result in
any memory savings, and the related complexity can be avoided if
the data is kept in process memory.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Tasks-Temporary_Files-Location"><a class="anchor" href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location"></a>Obtaining the Location of Temporary Directory</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Some functions below need the location of a directory which
stores temporary files. For C/C++ programs, use the following
steps to obtain that directory:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Use <code>secure_getenv</code> to obtain the value
of the <code>TMPDIR</code> environment variable. If
it is set, convert the path to a fully-resolved absolute
path, using <code>realpath(path, NULL)</code>. Check
if the new path refers to a directory and is writeable. In
this case, use it as the temporary directory.</p>
</li>
<li>
<p>Fall back to <code>/tmp</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In Python, you can use the <code>tempfile.tempdir</code>
variable.</p>
</div>
<div class="paragraph">
<p>Java does not support SUID/SGID programs, so you can use the
<code>java.lang.System.getenv(String)</code> method to
obtain the value of the <code>TMPDIR</code> environment
variable, and follow the two steps described above. (Java&#8217;s
default directory selection does not honor
<code>TMPDIR</code>.)</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="named-temporary-files"><a class="anchor" href="#named-temporary-files"></a>Named Temporary Files</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>mkostemp</code> function creates a named
temporary file. You should specify the
<code>O_CLOEXEC</code> flag to avoid file descriptor leaks
to subprocesses. (Applications which do not use multiple threads
can also use <code>mkstemp</code>, but libraries should
use <code>mkostemp</code>.) For determining the
directory part of the file name pattern, see <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.</p>
</div>
<div class="paragraph">
<p>The file is not removed automatically. It is not safe to rename
or delete the file before processing, or transform the name in
any way (for example, by adding a file extension). If you need
multiple temporary files, call <code>mkostemp</code>
multiple times. Do not create additional file names derived
from the name provided by a previous
<code>mkostemp</code> call. However, it is safe to close
the descriptor returned by <code>mkostemp</code> and
reopen the file using the generated name.</p>
</div>
<div class="paragraph">
<p>The Python class <code>tempfile.NamedTemporaryFile</code>
provides similar functionality, except that the file is deleted
automatically by default. Note that you may have to use the
<code>file</code> attribute to obtain the actual file
object because some programming interfaces cannot deal with
file-like objects. The C function <code>mkostemp</code>
is also available as <code>tempfile.mkstemp</code>.</p>
</div>
<div class="paragraph">
<p>In Java, you can use the
<code>java.io.File.createTempFile(String, String,
File)</code> function, using the temporary file location
determined according to <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.
Do not use <code>java.io.File.deleteOnExit()</code> to
delete temporary files, and do not register a shutdown hook for
each temporary file you create. In both cases, the deletion
hint cannot be removed from the system if you delete the
temporary file prior to termination of the VM, causing a memory
leak.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="temporary-files-without-names"><a class="anchor" href="#temporary-files-without-names"></a>Temporary Files without Names</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>tmpfile</code> function creates a temporary
file and immediately deletes it, while keeping the file open.
As a result, the file lacks a name and its space is deallocated
as soon as the file descriptor is closed (including the implicit
close when the process terminates). This avoids cluttering the
temporary directory with orphaned files.</p>
</div>
<div class="paragraph">
<p>Alternatively, if the maximum size of the temporary file is
known beforehand, the <code>fmemopen</code> function can
be used to create a <code>FILE *</code> object which is
backed by memory.</p>
</div>
<div class="paragraph">
<p>In Python, unnamed temporary files are provided by the
<code>tempfile.TemporaryFile</code> class, and the
<code>tempfile.SpooledTemporaryFile</code> class provides
a way to avoid creation of small temporary files.</p>
</div>
<div class="paragraph">
<p>Java does not support unnamed temporary files.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="chap-Defensive_Coding-Tasks-Temporary_Directory"><a class="anchor" href="#chap-Defensive_Coding-Tasks-Temporary_Directory"></a>Temporary Directories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>mkdtemp</code> function can be used to create
a temporary directory. (For determining the directory part of
the file name pattern, see <a href="#chap-Defensive_Coding-Tasks-Temporary_Files-Location">Obtaining the Location of Temporary Directory</a>.)
The directory is not automatically removed. In Python, this
function is available as <code>tempfile.mkdtemp</code>.
In Java 7, temporary directories can be created using the
<code>java.nio.file.Files.createTempDirectory(Path, String,
FileAttribute&#8230;&#8203;)</code> function.</p>
</div>
<div class="paragraph">
<p>When creating files in the temporary directory, use
automatically generated names, e.g., derived from a sequential
counter. Files with externally provided names could be picked
up in unexpected contexts, and crafted names could actually
point outside of the tempoary directory (due to
<strong>directory traversal</strong>).</p>
</div>
<div class="paragraph">
<p>Removing a directory tree in a completely safe manner is
complicated. Unless there are overriding performance concerns,
the <strong class="application">rm</strong> program should be used, with
the <code class="option">-rf</code> and <code class="option">--</code> options.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="compensating-for-unsafe-file-creation"><a class="anchor" href="#compensating-for-unsafe-file-creation"></a>Compensating for Unsafe File Creation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are two ways to make a function or program which excepts a
file name safe for use with temporary files. See
<a href="#sect-Defensive_Coding-Tasks-Processes-Creation">[sect-Defensive_Coding-Tasks-Processes-Creation]</a>,
for details on subprocess creation.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Create a temporary directory and place the file there. If
possible, run the program in a subprocess which uses the
temporary directory as its current directory, with a
restricted environment.
Use generated names for all files in that temporary
directory. (See <a href="#chap-Defensive_Coding-Tasks-Temporary_Directory">Temporary Directories</a>.)</p>
</li>
<li>
<p>Create the temporary file and pass the generated file name
to the function or program. This only works if the function
or program can cope with a zero-length existing file. It is
safe only under additional assumptions:</p>
<div class="ulist">
<ul>
<li>
<p>The function or program must not create additional files
whose name is derived from the specified file name or
are otherwise predictable.</p>
</li>
<li>
<p>The function or program must not delete the file before
processing it.</p>
</li>
<li>
<p>It must not access any existing files in the same
directory.</p>
<div class="paragraph">
<p>It is often difficult to check whether these additional
assumptions are matched, therefore this approach is not
recommended.</p>
</div>
</li>
</ul>
</div>
</li>
</ul>
</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>