"Fossies" - the Fresh Open Source Software Archive

Member "tmpreaper-1.6.17/debian/README.security" (17 Aug 2007, 19957 Bytes) of package /linux/misc/tmpreaper_1.6.17.tar.gz:

As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 Security implications of tmpreaper
    2 ----------------------------------
    4 Below is a message that was forwarded to me, concerning vulnerabilities in
    5 tmpwatch, of which tmpreaper is a fork and may thus share vulnerabilities
    6 with.
    8 IMO there are a couple of things wrong about the points in the text, which I
    9 could not resolve in discussion with Joey Hess (my direct questions were
   10 avoided by responding that I clearly didn't understand the issues -- which is
   11 (a) faulty argumentation leading me to believe that they themselves were
   12 incapable of explaining, and (b) wrong). For example, the text speaks of
   13 "creation time"; I responded that there is no such thing in POSIX, only the
   14 inode change time (which is also changed if you link the file, or rename it, or
   15 change the permissions, or even when you delete it).  I never got an answer on
   16 that.
   18 Here's one thing that was said by Joey:
   20    Suppose a victim program is setuid, and you want to attack it to
   21    get root. So you run it, let it open a temp file, and SIGSTOP it.
   22    Now let it sit, suspended, for x days. Tmpreaper then removes the
   23    temp file, since mtime, atime, and ctime are all x days. Now replace
   24    the tmp file with something crafted to buffer overflow or otherwise 
   25    exploit the program, and SIGCONT it so it runs, accesses the tmp file
   26    it thinks it just made, and is exploited.
   28    There is no known fix to this hole. You can play with fuser and
   29    limit it to a certain smaller class of victim programs, but not
   30    entirely close it. It's also pretty easy to exploit on any machine
   31    with a large uptime and lots of processes to hide in.
   33 This calls for the setuid program to close the file, and then open it again
   34 without checking the owner, inode number, etc.  This also means that fuser
   35 won't help a bit (the file must be closed, remember? So why mention it). That
   36 in my book is a problem of the setuid program, not of tmpreaper, as this is
   37 nothing that won't happen either if the admin does "rm -rf /tmp/*" now and
   38 again, despite following claim that that is a preferable alternative to
   39 tmpreaper:
   41    At least admins running rm -rf is something that happens
   42    unpredictably ...
   45 Another thing that was said:
   47    tmp{reaper,watch} use lstat() to look at file creation time. Then they
   48    use unlink() to delete it. Two system calls, therefore there is a
   49    time period between them in which an attacker may do the very unlikely
   50    trick described in the paper of removing its decoy file and letting
   51    mkstemp put in a file by the same name, which is then deleted.
   52    At this point the attacker can replace the temp file with their own
   53    creation, and mess with the program that expects its own temp file there.
   55 There's that mythical "file creation time" thing again...
   56 Besides that, he's right in saying that it's very unlikely to manage to squeeze
   57 inbetween those two system calls. Bookies will give you _very_ large odds on
   58 that...
   60 1. you need to be able to predict days in advance what pseudo-random name
   61    mkstemp will generate at that precise moment in time. From the message
   62    below:
   63      ... While mkstemp() names are guaranteed to be unique, they shouldn't be
   64      expected to be unpredictable - in most implementations, the name is a
   65      function of process ID and time - so it is possible for the attacker to
   66      guess it and create a decoy in advance. ...
   67    Guessing what process ID a victim process will have a number of days in
   68    advance on a multiuser system is a pretty neat trick.
   70 2. you then need to be able to remove that file at exactly the moment
   71    tmpreaper after tmpreaper has used lstat(), but before it does the unlink().
   73 3. mkstemp (in the daemon/whatever that you're trying to attack) will
   74    have to create the file with the correct name, still before tmpreaper's
   75    unlink() call.
   77 4. now tmpreaper has to execute the unlink() call, before the
   78    daemon/whatever has gone on and used the tmpfile for its intended purpose.
   80 5. you now have to create the file again, with the correct name and
   81    contents.
   83 6. the daemon/whatever has to close and reopen the file without checking
   84    its owner, permission, inode number, etc. and then use the data therein.
   86 This would be an incredible feat to accomplish, needing unbelievable amounts
   87 of luck in timing (skill is not an issue; timing is), requiring also an app
   88 running with sufficient privileges to do harm that uses its tempfiles
   89 insecurely in the first place.  In such a scenario, is the problem with
   90 tmpreaper? I don't think so.
   93 The scenario described is so inprobable that if you're worried about that, you
   94 should buy a lottery ticket every week: the chance that *someone* wins the
   95 lottery is 100% (well, with a lot of lotteries :-); the chance that this will
   96 ever happen is less.
   99 There's also a discussion below about the problems when two tmpwatch processes
  100 are running simultaneously (hence would also apply to tmpreaper as well).
  101 Tmpreaper avoids this by not allowing itself to run for more than one minute.
  102 There's also a random delay before processing (when invoked with --delay as is
  103 done in the default cron.daily script) to make it harder to determine when
  104 tmpreaper runs exactly.
  105 See also the tmpreaper manpage for other precautions taken.
  107 Of course, if you still are worried, you are of course free to purge tmpreaper
  108 from your system, and do a regular "rm -rf /tmp/*" if you think that's
  109 safer...
  112 Below is the message that started this discussion, and judge for yourself.
  116 Paul Slootman 2003-05-21, updated 2003-06-02
  119 From: Michal Zalewski <lcamtuf@ghettot.org>
  120 Date: Fri, 20 Dec 2002 09:30:30 -0800 (PST)
  121 To: bugtraq@securityfocus.com, <vulnwatch@vulnwatch.org>,
  122     <full-disclosure@netsys.com>
  123 Subject: [RAZOR] Problems with mkstemp()
  125   Common use of 'tmpwatch' utility and its counterparts triggers race
  126   conditions in many applications
  128   Michal Zalewski <lcamtuf@razor.bindview.com>, 12/05/2002
  129   Copyright (C) 2002 by Bindview Corporation
  132 1) Scope and exposure info
  133 --------------------------
  135   A common practice of installing 'tmpwatch' utility or similar software
  136   configured to sweep the /tmp directory on Linux and unix systems can
  137   compromise secure temporary file creation mechanisms in certain applications,
  138   creating a potential privilege escalation scenario. This document briefly
  139   discusses the exposure, providing some examples, and suggesting possible
  140   workarounds.
  142   It is believed that many unix operating systems using 'tmpwatch' or an
  143   equivalent are affected. Numerous Linux systems, such as Red Hat, that ship
  144   with cron daemon running and 'tmpwatch' configured to sweep /tmp are
  145   susceptible to the attack.
  148 2) Application details
  149 ----------------------
  151   'Tmpwatch' is a handy utility that removes files which haven't been
  152   accessed for a period of time. It was developed by Erik Troan and
  153   Preston Brown of Red Hat Software, and, with time, has become a
  154   component of many Linux distributions, also ported to platforms
  155   such as Solaris, *BSD or HP/UX. By default, it is installed with a
  156   crontab entry that sweeps /tmp directory on a daily basis, deleting
  157   files that have not been accessed for the past few days.
  159   An alternative program, called 'stmpclean' and authored by Stanislav
  160   Shalunov, is shipped with *BSD systems and some Linux distributions
  161   to perform the same task, and some administrators deploy other tools or
  162   scripts for this purpose.
  165 3) Vulnerability details
  166 ------------------------
  168   Numerous applications rely either on mkstemp() or custom O_EXCL file
  169   creation mechanisms to store temporary data in the /tmp directory
  170   in a secure manner. Of those, certain programs run with elevated
  171   privileges, or simply at a different privilege level than the caller.
  173   The exposure is a result of a common misconception, promoted by almost
  174   all secure programming tutorials and manpages, that /tmp files created
  175   with mkstemp(), granted that umask() settings were proper, are
  176   safe against hijacking and common races. The file, since it is created
  177   in a sticky-bit directory, indeed cannot be removed or replaced by
  178   the attacker running with different non-root privileges, but since
  179   many operating systems feature 'tmpwatch'-alike solutions, the only
  180   thing that can and should be considered safe in /tmp is the descriptor
  181   returned by mkstemp() - the filename should not be relied upon. There
  182   are two major reasons for this:
  184   1) unlink() races
  186      It is very difficult to remove a file without risking a potential
  187      race (see section 4). 'Tmpwatch' does not take any extra measures to
  188      prevent races, and probes file creation time using lstat(). Based on this
  189      data, it calls unlink() as root. Problem is, on a multitasking system,it
  190      is possible for the attacker to get some CPU time between those two system
  191      calls, remove the old "decoy" file that has been probed with lstat(), and
  192      let the application of his choice create its own temporary file under this
  193      name. While mkstemp() names are guaranteed to be unique, they shouldn't be
  194      expected to be unpredictable - in most implementations, the name is a
  195      function of process ID and time - so it is possible for the attacker to
  196      guess it and create a decoy in advance. Once the tmpwatch process is
  197      resumed, the file is immediately removed, based on the result of
  198      earlier lstat() on the old, no longer existing file.
  200      While this three-component race requires very precise timing, it
  201      is possible to try a number of times in a single 'tmpwatch' run if
  202      enough decoy files are created by the attacker. Additionally, since
  203      each step of the attack would result in a corresponding filesystem
  204      change, it is fairly easy to carefully measure timings and
  205      coordinate the attack.
  207      If the attacker cannot make the application run at the same time
  208      as 'tmpwatch' - for example, if the application is executed by
  209      hand by the administrator, or is running from cron - 'tmpwatch'
  210      itself can be artificially delayed for almost an arbitrary amount
  211      of time by creating and continuously expending an elaborate directory
  212      structure in /tmp using hard links (to preserve access times of
  213      files) and running other processes that demand disk access and
  214     cache space to slow down the process.
  216      'Stmpclean' offers additional protection against races by not removing
  217      root-owned files and temporarily dropping privileges when removing
  218      the file to match the owner of lstat()ed resource. Unfortunately,
  219      not removing root files is a considerable drawback, and there is still
  220      a potential for a race using carefully crafted hard links to a file
  221      owned by the victim and two concurrent 'stmpclean' processes:
  223        - the attacker links /tmp/foo to ~victim/.bash_profile
  224        - tmpwatch #1 does lstat() on /tmp/foo and setuid victim
  225        - tmpwatch #2 does lstat() on /tmp/foo and setuid victim
  226        - tmpwatch #1 does unlink("/tmp/foo")
  227        - victim application creates /tmp/foo at uid==victim
  228        - tmpwatch #2 does unlink("/tmp/foo") and succeeds
  229        - the attacker creates /tmp/foo
  230        - victim application proceeds
  232      On certain systems such as Owl Linux, the attack will be not possible
  233      due to hardlink limits imposed on sticky-bit directories.
  235   2) suspended processes and 'legitimate' file removal
  237      Here, all conventional measures that could be exercised by /tmp cleaners
  238      fail miserably. A vulnerable application can be often delayed or suspended
  239      after mkstemp() / open() - for example, a setuid program can be
  240      stopped with SIGSTOP and resumed with SIGCONT. If the application is
  241      suspended for long enough, its temporary files are likely to be
  242      removed. This method requires much less precision, but is also
  243      more time-consuming and has a more limited scope (interactive
  244      applications only).
  246      Note that it is sometimes possible to delay the execution of
  247      a daemon - client wait, considerable I/O or CPU loads, and subsequent
  248      mkstemp() calls can be all used to achieve the effect. The
  249      feasibility and efficiency is low, but the potential issue
  250      exists. Some client applications that are often left unattended
  251      and create temporary files - such as mail/news clients, web
  252      browsers, irc clients, etc - can also be used to compromise
  253      other accounts on the machine.
  255   Not all applications are prone to the problem just because mkstemp()
  256   is used to create files in /tmp; if the file name is not used to perform
  257   any sensitive operations with some extra privileges afterward (read,
  258   write, chown, chmod, link/rename, etc), and only the descriptor is
  259   being used, the application is safe. This practice is often exercised by
  260   programmers who want to avoid leaving dangling temporary files in case
  261   the program is aborted or crashes. Similarly, if the application uses
  262   temporary files improperly, but does not rely on their contents and does
  263   not attempt to access them with higher privileges, the application is
  264   secure in that regard.
  266   Applications that run with higher privileges and reopen their
  267   /tmp temporary files for reading or writing, call chown(), chmod() on
  268   them, rename or link the file to replace some sensitive information, and
  269   so on, are exposed. It is worth mentioning that a popular 'mktemp'
  270   utility coming from OpenBSD passes only the filename to the
  271   caller shell script, thus rendering almost all scripts using it
  272   fundamentally flawed. If the script is being run as a cron job or
  273   other administrative task, and mktemp is used, the system can be likely
  274   compromised by replacing the file after mktemp and prior to any write
  275   to the file. In the example quoted in the documentation for mktemp(1):
  277     TMPFILE=`mktemp /tmp/$0.XXXXXX` || exit 1
  278     echo "program output" >> $TMPFILE
  280   ...the attacker would want to replace temporary file right before
  281   'echo', causing the text "program output" to be appended to a target
  282   file of his choice using symlinks or hardlinks; or, if it is more
  283   desirable, he'd spoof file contents to cause the program to misbehave.
  285   Another example of the problem is a popular logrotate utility,
  286   coded - ironically - by Erik Troan, one of co-authors of 'tmpwatch'
  287   itself. The program suffered /tmp races in the past, but later
  288   switched to mkstemp(). The following sequence is used to handle
  289   post-rotation shell commands specified in config files:
  291   open("/tmp/logrotate.wvpNmP", O_WRONLY|O_CREAT|O_EXCL, 0700) = 6
  292   ...
  293   write(6, "#!/bin/sh\n\n", 11)     = 11
  294   write(6, "\n\t/bin/kill -HUP `cat /var/lock/"..., 79) = 79
  295   close(6)                          = 0
  296   ... fork, etc ...
  297   execve("/bin/sh", ["sh", "-c", "/bin/sh /tmp/logrotate.wvpNmP" ...
  299   Obviously, if the attacker can have /tmp/logrotate.* replaced in
  300   between mkstemp() (represented as open() syscall above) and the
  301   point where another process is spawned, a shell interpreter is invoked,
  302   then executes another copy of the shell interpreter (apparent
  303   programmer's mistake) and finally reads the input file - which is
  304   a considerable chunk of time - the shell will be called with
  305   attacker-supplied commands to be executed with root privileges.
  307   On Red Hat, logrotate is executed from crontab on a daily basis, in
  308   a sequence before 'tmpwatch', and the easiest option for the attacker
  309   is to maintain a still-running tmpwatch process from the previous day
  310   to exploit the condition. On systems where those programs are not
  311   executed sequentially - for example, when both programs are listed
  312   directly in /etc/crontab - the attack requires less precision.
  315 4) Workarounds and fixes:
  316 -------------------------
  318   Recommended immediate workaround is to discontinue the use of 'tmpwatch'
  319   or equivalent to sweep /tmp directory if this service is not necessary.
  321   For applications that rely on TMPDIR or a similar environment
  322   variable, setting it to a separate, not publicly writable directory
  323   is often a viable solution. Note that not all applications honor
  324   this setting.
  326   In terms of a permanent solution, two different attack vectors have
  327   to be addressed, as discussed in section 3:
  329   1) unlink() race
  331      The proper way to remove files in sticky-bit directories while
  332      minimizing the risk is as follows:
  334        a) lstat() the file to be removed
  335        b) if owned by root, do not remove
  336        c) if st_nlink > 1, do not remove
  337        d) if owned by user, temporarily change privileges to this user
  338        e) attempt unlink()
  339        f) if failed, warn about a possible race condition
  340        g) switch privileges back to root
  342      With the exception of step c, this is implemented in 'stmpclean'.
  343      Unfortunately, step c is crucial on systems that do not have
  344      restricted /tmp kernel patches from Openwall (http://www.openwall.com),
  345      otherwise, there is a potential for fooling the algorithm by supplying
  346      a hard link to a file owned by the victim, as discussed in section 3.
  347      This approach has several drawbacks - such as the fact root-owned files
  348      will not be removed. Other solution is to modify applications that
  349      generate filenames on their own, and to modify mkstemp(), to generate
  350      names that are not only unique, but not feasible to predict.
  352      Another suggestion is to implement a funlink() capability in the kernel
  353      of the operating system in question, to allow race-free file removal,
  354      thus removing the non-root ownership requirement for the method described
  355      above, and simplifying the approach. A skeleton patch to implement
  356      funlink() semantics and make sure the file being removed is the file
  357      opened and fstat()ed previously is available at:
  358      http://lcamtuf.coredump.cx/soft/linux-2.4-funlink.diff (this and
  359      other patches are not endorsed by RAZOR in any way).
  361   2) suspended process and 'legitimate' file removal
  363      This issue is fairly difficult to address. The most basic idea is
  364      to use a special naming scheme for temporary files to avoid deletion -
  365      unfortunately, this seems to defeat the purpose of using tmpwatch-alike
  366      solutions in the first place.
  368      An alternative approach, which is to enforce separate temporary
  369      directories for certain applications, either process-, session- or uid-
  370      based, is generally fairly controversial, and raises some concerns.
  371      Advisory separation is generally acceptable, but there are a number of
  372      applications that do not accept TMPDIR setting, and a widespread practice
  373      of using /tmp in in-house applications. Mandatory separation (kernel
  374      modification) raises compatibility concerns and is generally approached
  375      with skepticism - no implementation has become particularly popular.
  377   Ideally, implementators should carefully audit their sources. It is
  378   recommended for privileged applications to use private temporary
  379   directories for sensitive files, if possible; if using /tmp is necessary,
  380   extra caution has to be exercised to avoid referencing the file by name.
  381   Note that comparing the descriptor and a reopened file to verify inode
  382   numbers, creation times or file ownership is not sufficient - please refer
  383   to "Symlinks and Cryogenic Sleep" by Olaf Kirch, available at
  384   http://www.opennet.ru/base/audit/17.txt.html .
  386   It's worth noticing that 'tmpwatch' offers a -s option, which causes the
  387   program to run the 'fuser' command to prevent removal of files that are
  388   currently open. At first sight, this could be an effective way to solve the
  389   problem. Unfortunately, this is not true, since many applications close the
  390   file for a period of time before reopening (including logrotate and
  391   mktemp(1)).
  394 5) Credits and thanks
  395 ---------------------
  397   Thanks to Solar Designer for interesting discussions on the subject,
  398   to Matt Power for useful feedback, and to RAZOR team in general for making
  399   this publication possible.