** Branch linked: lp:~ubuntu-core-dev/ubuntu/bionic/apport/ubuntu

-- 
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to apport in Ubuntu.
https://bugs.launchpad.net/bugs/1726372

Title:
  Multiple security issues in Apport

Status in apport package in Ubuntu:
  New
Status in apport source package in Trusty:
  Fix Released
Status in apport source package in Xenial:
  Fix Released
Status in apport source package in Zesty:
  Fix Released
Status in apport source package in Artful:
  Fix Released

Bug description:
  We have received the following advisory:

  Security vulnerability report: multiple vulnerabilies in Apport / Ubuntu
  ========================================================================

  OVERVIEW
  --------

  Author: Sander Bos
  Author's e-mail address: sbos _at_ sbosnet _dot_ nl
  Author's web site: www.sbosnet.nl
  CVE numbers: requested
  Date: 2017-10-23
  Version: 2

  SUMMARY
  -------

  Several security vulnerabilities were discovered by Sander Bos in the
  "Apport" crash handler program [1] affecting all currently supported
  releases of Ubuntu (12.04 LTS (ESM), 14.04 LTS, 16.04 LTS, 17.04, 17.10)
  and, likely, other distributions and Ubuntu derivatives using Apport
  as well.

  Exploitation types are privilege escalation (root exploitation), full
  disk DoS, and Linux container escaping.

  DESCRIPTION, WITH PROPOSED FIXES / WORKAROUNDS
  ----------------------------------------------

  Issue 1 (CVE-2017-14177): Incomplete fix for CVE-2015-1324
  -----------------------------------------

  Exploitation types: privilege escalation, full disk DoS.

  Ubuntu releases affected: 12.04 LTS (ESM), 14.04 LTS, 16.04 LTS, 17.04, 17.10
  (i.e., all currently supported releases).
  Note: default OS installations might need an extra package installed,
  or a system configuration setting changed, to be exploitable.

  Description:

  The Apport issue I reported in 2015 (CVE-2015-1324) [2], leading to
  privilege escalation, was not fixed properly.  The initial issue and
  vulnerability still apply, although to a lesser extent.

  Since the introduction of the fix [3] Apport detects setuid, unreadable,
  and other types of tainted / protected binaries / processes by
  comparing the real UID and real GID of the crashed process, read from
  /proc/<pid>/status and which Apport first sets its own UID and GID to,
  with the UID and GID file owner information of /proc/<pid>/stat.

  For non tainted processes, the file owner information of /proc/<pid>/stat
  is the UID and GID of the user that started the process.  For tainted
  processes, the file owner information is 0.

  If the comparison does not match, Apport assumes the process to be a
  tainted process, and disables writing a core dump file.  This on itself
  is correct.

  However, if the comparison _does_ match, it is not always correct to
  assume that the process is _not_ a tainted process (and, consequently,
  write a core dump file).  For example, some setuid programs run by users
  receive real UID 0 and real GID 0.  Also, some setuid processes started
  by root (partially) drop privileges at some point (after which users
  could crash them), for example after forking, but retain real UID 0 and
  real GID 0.

  In such cases, Apport writes a core dump file (as root) while in fact
  it should not do so.  This brings back the problem of CVE-2015-1324.

  It should also be noted that, for the same reason, Apport "dropping 
privileges"
  to the real UID and real GID read from /proc/<pid>/status is at times
  incorrect and, thus, unsafe as well.

  Proposed fix:

  The proper fix is to really _never_ write a core dump file for processes
  where suid_dumpable=2 got effectuated.  This was probably what was
  intended with the fix for CVE-2015-1324, but the check that was created
  does not catch all cases of tainted processes.  A better approach would
  be to let Apport read out "%d" from core(5) through "kernel.core_pattern"
  and if it returns "2", not write a core dump file.  Note however that
  "%d" is only present since kernel version 3.7, and would thus not work
  on Ubuntu 12.04 LTS systems running a 3.2 "GA" (General Availability)
  kernel from earlier Ubuntu 12.04.x LTS releases (as opposed to such
  systems running a 3.13 "HWE" (Hardware Enablement Stack) kernel from
  later Ubuntu 12.04.x LTS releases).

  Issue 2 (CVE-2017-14179): Apport lacking container / PID namespace support
  and
  Issue 3 (CVE-2017-14180): Apport broken container / PID namespace support
  ---------------------------------------------------------

  Exploitation types: container escape, privilege escalation, full disk
  DoS.

  Ubuntu releases affected: 12.04 LTS (ESM), 16.04 LTS, 17.04, 17.10.
  Note: exploitable on default OS installations.

  Description:

  Issue 2 (CVE-2017-14179):
  Ubuntu 12.04 LTS: Apport does not recognize ("support")
  PID namespaces / containers.

  Issue 3 (CVE-2017-14180):
  Ubuntu 16.04 LTS, Ubuntu 17.04, and Ubuntu 17.10: Apport supports
  containers, but checks if a crashed program originated in a container
  only by checking for a mismatch of the global PID and the local PID of a
  crashed process.  This check will in fact be true in case of a process
  that originated in a container.  However, the check does not suffice
  because a second, nested, PID namespace can exist in the container
  (without itself being part of another "full" container).  In that case
  Apport (or, actually, a second Apport called by the host OS Apport,
  and running in the container) will incorrectly take information from
  the container /proc directory while in fact that /proc does not belong
  to the PID namespace from which the crashed process originated.

  (Ubuntu 14.04 LTS, the other supported Ubuntu release, does detect
  containers but not "support" them: it exits in case of a global / local
  PID mismatch.  Apport's container support was disabled in April 2015
  due to security vulnerabilities and re-implemented in February 2016,
  but the new container support implementation was not added to
  Ubuntu 14.04 LTS, probably because it uses sytemd features and
  Ubuntu 14.04 LTS does not run systemd.  Thus, Ubuntu 14.04 LTS is not
  vulnerable, although that is more or less by coincedence.)

  Apport misreading /proc for PID namespaces processes breaks Apport's
  functionality for applications that use "CLONE_NEWPID" (see the clone(2)
  and unshare(2) man pages), because /proc<pid>/ will either belong to
  a different (global) process with the same global PID as the local PID
  of the crashed proces, or it will not exist in case no global process
  with that PID exists.  This broken functionality is a bug on itself but,
  worse, introduces a security vulnerability.

  Simple demonstrational PoC:

  To demonstrate the above, the following C program could be run as a
  non-root user on for example an Ubuntu 17.10 (LXC) system container
  (called "container OS" in the rest of this report) on an Ubuntu 17.04
  host OS:

  ---
  #define _GNU_SOURCE
  #include <sched.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <sys/resource.h>
  #include <sys/time.h>

  int main(void) {
     int pid;
     struct rlimit corelimit;

     corelimit.rlim_cur = RLIM_INFINITY;
     corelimit.rlim_max = RLIM_INFINITY;
     setrlimit(RLIMIT_CORE, &corelimit);

     unshare(CLONE_NEWUSER|CLONE_NEWPID);

     chdir("/tmp/");

     pid = fork();
     if (pid == 0) {
        abort();
     }
  }
  ---

  Thus, there are three layers: host OS -> container OS -> PID namespace.
  The forked process in the program above will have PID 1 within the PID
  namespace, i.e., within the third layer.

  Running this program (in the container OS) will trigger Apport in the
  host OS, which will forward the crash to the Apport of the container OS.
  This second Apport instance will then actually handle the crash.  It will
  use PID 1 for this, since that's the PID that Apport from the host OS
  has told it to use: the local PID of the crashed process.

  This PID 1 is the local PID 1 from the PID namespace, but Apport from the
  container OS reads from /proc/1/ from the container OS.  This directory
  actually belongs to PID 1 within the container OS, _not_ PID 1 from
  within the PID namespace.

  Effectively, the Apport in the container will create
  a ".crash" crash report file in /var/crash/, for example
  /var/crash/_lib_systemd_systemd.0.crash or /var/crash/_sbin_init.0.crash,
  with UID root and GID root as file owner (although Apport may optionally
  change the GID of the crash report file later on).  Apport will also
  create the file "/core", with UID root and GID root as file owner as well.

  The files will contain /proc information belonging to (coming from),
  and for the crash report file the path name of, the _global_ PID 1
  within the container OS.  Also, the CWD of that global PID 1 is taken
  as the directory to write the core dump file in, not the CWD of the
  crashed program (which is set to /tmp/ to demonstrate that).  The core
  dump contents in the crash report file and the contents of the "/core"
  core dump file _are_ in fact coming from the crashed program, which is
  correct, although exactly this can be used for further exploitation.

  The above program also works on Ubuntu 12.04 LTS, when running as a host
  OS (as opposed to running it as a container OS).  The effect is similar,
  but the cause of the effect is different (it's a different bug / code
  issue): Apport in Ubuntu 12.04 LTS does not recognize at all that the
  crashed process originated in a PID namespace / container, and it will
  not see a global PID _and_ a local PID of the process, but only its
  local PID 1 which it will then use (which is wrong, as that local PID
  1 obviously is not the global PID 1).

  For Ubuntu 12.04 LTS with a 3.2 "GA" (General Availability) kernel (from
  earlier Ubuntu 12.04.x LTS releases), as opposed to such systems running
  a 3.13 "HWE" (Hardware Enablement Stack) kernel (from later Ubuntu
  12.04.x LTS releases), it should be noted that exploitation might be
  more difficult, and perhaps not possible on default OS installations.
  This is because user namespaces ("CLONE_NEWUSER", see the clone(2)
  and unshare(2) man pages) is not available in kernel version 3.2, i.e.,
  non-root users can not create PID namespaces ("CLONE_NEWPID" requires
  "CLONE_NEWUSER"), although for example setuid programs from packages
  installed by root could do this for them.

  It should also be noted that exploitability of this vulnerability does
  not only depend on what release of Ubuntu is running, but also if it is
  running as the host OS, as a containers OS, or as both of them.

  Below follows a, possibly incomplete but believed to be accurate,
  overview of host OS / container OS combinations and what can be achieved
  in exploitation in each combination.  Full disk DoS scenarios are also
  possible on either the host OS, the container OS, or both, but not
  included here.

  Host OS:                      12.04 LTS
  Container OS:                 not involved
  Simple exploit:               user on host OS creates "/core" on host OS
  Privilege escalation exploit: user host OS -> root host OS

  Host OS:                      12.04 LTS
  Container OS:                 any Linux distribution
  Simple exploit:               user in container OS creates "/core" on host OS
  Privilege escalation exploit: user container OS -> root host OS
  *** Note: effectively this means escaping a container, and is not limited to 
Ubuntu ***

  Host OS:                      16.04 LTS / 17.04 / 17.10
  Container OS:                 16.04 LTS / 17.04 / 17.10
  Simple exploit:               user on container OS creates "/core" on 
container OS
  Privilege escalation exploit: user container OS -> root container OS

  Note: escaping a container as mentioned in the
  user container OS -> root host OS scenario above does not refer to a
  general container escape technique using for example a bug in LXC, Linux
  namespaces, or the fact that the kernel is shared between the container
  and host OS; instead, it refers to a Apport specific, newly found, but
  "indirect" method of escaping a container.  The end effect is however
  equal, thus it is mentioned as a way of escaping a container.

  Note: the user container OS -> root container OS scenario could from
  that point on lead to privilege escalation to root on the host OS, for
  example by exploiting the fact that the container OS and the host OS
  share the same kernel.  Known, general techniques could be used for that.
  This would require the container OS to be running in a "privileged"
  container, i.e., a container created by and running as the root user on
  the host OS, as opposed to be running in an "unprivileged" container,
  i.e., a container created by but not running as root on the host OS,
  or created by a non-root user on the host OS.  This could for example
  be the case when user namespaces are disabled or otherwise not available
  on the host OS,

  Proposed fix:

  For Apport without container support (Ubuntu 12.04 LTS), a fix could be to
  have Apport detect containers by comparing the global PID and the local
  PID of a crashed process and if they don't match, exit (this is exactly
  what is currently done in Ubuntu LTS 14.04).  Note however that the "%P"
  global PID template specifier from core(5) is only available and can
  thus be only used in "kernel.core_pattern" since kernel version 3.12,
  so this fix will be problematic to implement on Ubuntu 12.04 LTS systems
  running a 3.2 "GA" (General Availability) kernel (from earlier Ubuntu
  12.04.x LTS releases) (as opposed to Ubuntu 12.04 LTS systems running a
  3.13 "HWE" (Hardware Enablement Stack) kernel from later Ubuntu 12.04.x
  LTS releases).

  For Apport with container support (Ubuntu 16.04 LTS, 17.04, 17.10),
  a short term fix (workaround) could be to (again) disable container
  support in Apport (this is what is currently done in Ubuntu 14.04 LTS).
  A long term fix would probably be to have Apport do a proper container
  check instead of only relying on PID number information.  In any case,
  it should be made sure not to read from the wrong /proc directory
  (if that can be avoided with certainty at all, e.g., a "container" /
  collection of namespaces might not have its own mount namespace or /proc,
  in which case things might get difficult).

  REFERENCES
  ----------

  [1] <https://launchpad.net/apport>, <https://wiki.ubuntu.com/Apport>
  [2] <https://bugs.launchpad.net/ubuntu/+source/apport/+bug/1452239>
  [3] <https://bazaar.launchpad.net/~apport-hackers/apport/trunk/revision/2957>

  REVISION HISTORY
  ----------------

  2017-10-21: Version 1: initial version
  2017-10-23: Version 2: fix minor errors, improve text, better explain
                         issue 1 (and explicitly mention that Apport
                         "drops privileges" unsafely), add references
                         section, add revision history section.

  CREDITS
  -------

  Please credit "Sander Bos (www.sbosnet.nl)" (without the quotes) in all
  documentation related to this issue including commit messages, releases,
  patches, and security advisories; thank you.

  EOF

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/apport/+bug/1726372/+subscriptions

-- 
Mailing list: https://launchpad.net/~touch-packages
Post to     : touch-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~touch-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to