Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Nov 2017 14:09:02 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 223732] mmap(2) causes unkillable denial of service with specific flags
Message-ID:  <bug-223732-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D223732

            Bug ID: 223732
           Summary: mmap(2) causes unkillable denial of service with
                    specific flags
           Product: Base System
           Version: 11.1-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: aksyom@gmail.com

Created attachment 188093
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D188093&action=
=3Dedit
mmap(2) local denial of service with MAP_STACK|MAP_ALIGNED(N) flags

I have found a set of flags that will cause a process to saturate an entire
execution unit at 100% median while the process becomes unkillable even with
kill -9. Sometimes the process might go under 100% CPU usage, but it gets b=
ack
too 100% after a while. The process state stays "running". This is effectiv=
ely
a perfect local denial of service, which cannot be undone by administrators=
 or
counter-intrusion software.

The only way to get out of this DoS is to reboot the entire system.

Furthermore, if you the process a number of times greater than the number of
physical CPU cores available to the system (at least on amd64), the system
becomes totally unresponsive, and then only a forced power down from a power
button is effective.

To reproduce this denial of service, compile the following source code with
clang and execute it:

#include <sys/mman.h>

int main(int argc, char** argv) {
    void *stack =3D mmap(0, 1<<12, PROT_READ|PROT_WRITE,
MAP_STACK|MAP_ALIGNED(12), -1, 0);
    /* Never reached.
     * Process will saturate one entire execution unit!
     * ALSO THIS PROCESS CANNOT BE KILLED!=20
     *=20
     * DoS manifests when the value of 2nd argument (len)=20
     * is less than or equal to 1<<N, where N is the argument
     * N to MAP_ALIGNED(N) macro=20
     *=20
     * MAP_STACK|MAP_ALIGNED(N) is the combination of flags
     * that seem to cause this DoS */
    return 0;
}

Like the above source code comments, the DoS manifests when flags
MAP_STACK|MAP_ALIGNED(N) are used together, and the value of 2nd argument (=
len)
is less than or equal to 1<<N where N is the argument N to MAP_ALIGNED(N) f=
lag
macro.

I have not tested if this affects jails, but I assume it does.

I marked this bug to affect all hardware, because I think this should be te=
sted
on all possible hardware, yet I have only amd64 boxes.

Source code to reproduce this bug also attached as a file for convenience.

Output of uname -a:
FreeBSD xxx.xxx 11.1-RELEASE-p4 FreeBSD 11.1-RELEASE-p4 #0: Tue Nov 14 06:1=
2:40
UTC 2017     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERI=
C=20
amd64

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-223732-8>