User to root privilege escalation (ab)using the crash forwarding feature of apport
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Apport |
Fix Released
|
Critical
|
Martin Pitt | ||
apport (Debian) |
Fix Released
|
Undecided
|
Ritesh Raj Sarraf | ||
apport (Ubuntu) |
Fix Released
|
Critical
|
Unassigned | ||
Trusty |
Fix Released
|
Critical
|
Unassigned | ||
Utopic |
Fix Released
|
Critical
|
Unassigned | ||
Vivid |
Fix Released
|
Critical
|
Unassigned |
Bug Description
Back in Ubuntu 14.04, I introduced an apport feature that will have it forward any crash to another apport running in the task's namespace (in the case where the pid of the task in its namespace isn't equal to that in the host namespace).
This feature simply checks for the presence of /usr/share/
The problem is that as apport is a coredump handler triggered by the kernel, it'll always run as real root, regardless of the crashed task's owner and namespace.
This therefore allows an unprivileged user to craft a specific filesystem structure, pivot_root to it, then crash a process inside it, causing apport outside of the namespace to execute a script as real root. By bind-mounting /proc from the host into that namespace, the unprivileged user can then access any file on the host as real root, causing the privilege escalation.
An exploit is attached to this bug. It's been confirmed to be runnable as a nobody user on a regular Ubuntu system and to successfully read any file on the host.
Related branches
CVE References
information type: | Private Security → Public Security |
Changed in apport (Ubuntu Trusty): | |
status: | Triaged → Fix Released |
Changed in apport (Ubuntu Utopic): | |
status: | Triaged → Fix Released |
tags: | added: patch |
The fix for this issue will be to have apport do the following tasks prior to executing the crash handler in the container:
- replicate the task's apparmor profile
- attach to all namespaces (setns)
- seteuid and setegid to 0 of that namespace
- sanitize the fd list (only 0, 1 and 2, all pointing to /dev/null)