From: John Wood <firstname.lastname@example.org>
To: Kees Cook <email@example.com>, Jann Horn <firstname.lastname@example.org>
Cc: John Wood <email@example.com>, Jonathan Corbet <firstname.lastname@example.org>,
James Morris <email@example.com>,
"Serge E. Hallyn" <firstname.lastname@example.org>,
Subject: [PATCH v2 0/8] Fork brute force attack mitigation
Date: Sun, 25 Oct 2020 14:45:32 +0100 [thread overview]
Message-ID: <email@example.com> (raw)
Attacks against vulnerable userspace applications with the purpose to break
ASLR or bypass canaries traditionaly use some level of brute force with the
help of the fork system call. This is possible since when creating a new
process using fork its memory contents are the same as those of the parent
process (the process that called the fork system call). So, the attacker
can test the memory infinite times to find the correct memory values or the
correct memory addresses without worrying about crashing the application.
Based on the above scenario it would be nice to have this detected and
mitigated, and this is the goal of this patch serie.
The public version of grsecurity, as a summary, is based on the idea of
delay the fork system call if a child died due to a fatal error. This has
1.- Bad practices: Add delays to the kernel is, in general, a bad idea.
2.- Weak points: This protection can be bypassed using two different
methods since it acts only when the fork is called after a child has
2.1.- Bypass 1: So, it would still be possible for an attacker to fork
a big amount of children (in the order of thousands), then probe
all of them, and finally wait the protection time before repeat
2.2.- Bypass 2: This method is based on the idea that the protection
doesn't act if the parent crashes. So, it would still be possible
for an attacker to fork a process and probe itself. Then, fork
the child process and probe itself again. This way, these steps
can be repeated infinite times without any mitigation.
The main idea behind this implementation is to improve the existing ones
focusing on the weak points annotated before. The solution for the first
bypass method is to detect a fast crash rate instead of only one simple
crash. For the second bypass method the solution is to detect both the
crash of parent and child processes. Moreover, as a mitigation method it is
better to kill all the offending tasks involve in the attack instead of use
So, the solution to the two bypass methods previously commented is to use
some statistical data shared across all the processes that can have the
same memory contents. Or in other words, a statistical data shared between
all the fork hierarchy processes after an execve system call.
The purpose of these statistics is to compute the application crash period
in order to detect an attack. This crash period is the time between the
execve system call and the first fault or the time between two consecutives
faults, but this has a drawback. If an application crashes once quickly
from the execve system call or crashes twice in a short period of time for
some reason, a false positive attack will be triggered. To avoid this
scenario the shared statistical data holds a list of the i last crashes
timestamps and the application crash period is computed as follows:
crash_period = (n_last_timestamp - n_minus_i_timestamp) / i;
This ways, the size of the last crashes timestamps list allows to fine
tuning the detection sensibility.
When this crash period falls under a certain threshold there is a clear
signal that something malicious is happening. Once detected, the mitigation
only kills the processes that share the same statistical data and so, all
the tasks that can have the same memory contents. This way, an attack is
1.- Per system enabling: This feature can be enabled at build time using
the CONFIG_SECURITY_FORK_BRUTE option or using the visual config
application under the following menu:
Security options ---> Fork brute force attack detection and mitigation
2.- Per process enabling/disabling: To allow that specific applications can
turn off or turn on the detection and mitigation of a fork brute force
attack when required, there are two new prctls.
prctl(PR_SECURITY_FORK_BRUTE_ENABLE, 0, 0, 0, 0)
prctl(PR_SECURITY_FORK_BRUTE_DISABLE, 0, 0, 0, 0)
3.- Fine tuning: To customize the detection's sensibility there are two new
sysctl attributes that allow to set the last crashes timestamps list
size and the application crash period threshold (in milliseconds). Both
are accessible through the following files respectively.
The list size allows to avoid false positives due to crashes unrelated
with a real attack. The period threshold sets the time limit to detect
an attack. And, since a fork brute force attack will be detected if the
application crash period falls under this threshold, the higher this
value, the more sensitive the detection will be.
So, knowing all this information I will explain now the different patches:
The 1/8 patch defines a new LSM hook to get the fatal signal of a task.
This will be useful during the attack detection phase.
The 2/8 patch defines a new LSM and manages the statistical data shared by
all the fork hierarchy processes.
The 3/8 patch adds the sysctl attributes to fine tuning the detection.
Patchs 4/8 and 5/8 detect and mitigate a fork brute force attack.
Patch 6/8 adds the prctls to allow per process enabling/disabling.
Patch 7/8 adds the documentation to explain this implementation.
Patch 8/8 updates the maintainers file.
This patch series is a task of the KSPP  and can also be accessed from
my github tree  in the "brute_v2" branch.
The first version can be found in:
Changelog RFC -> v2
- Rename this feature with a more appropiate name (Jann Horn, Kees Cook).
- Convert the code to an LSM (Kees Cook).
- Add locking to avoid data races (Jann Horn).
- Add a new LSM hook to get the fatal signal of a task (Jann Horn, Kees
- Add the last crashes timestamps list to avoid false positives in the
attack detection (Jann Horn).
- Use "period" instead of "rate" (Jann Horn).
- Other minor changes suggested (Jann Horn, Kees Cook).
John Wood (8):
security: Add LSM hook at the point where a task gets a fatal signal
security/brute: Define a LSM and manage statistical data
security/brute: Add sysctl attributes to allow detection fine tuning
security/brute: Detect a fork brute force attack
security/brute: Mitigate a fork brute force attack
security/brute: Add prctls to enable/disable the fork attack detection
Documentation: Add documentation for the Brute LSM
MAINTAINERS: Add a new entry for the Brute LSM
Documentation/admin-guide/LSM/Brute.rst | 118 ++++
Documentation/admin-guide/LSM/index.rst | 1 +
MAINTAINERS | 7 +
include/brute/brute.h | 16 +
include/linux/lsm_hook_defs.h | 1 +
include/linux/lsm_hooks.h | 4 +
include/linux/security.h | 4 +
include/uapi/linux/prctl.h | 4 +
kernel/signal.c | 1 +
kernel/sys.c | 8 +
security/Kconfig | 11 +-
security/Makefile | 4 +
security/brute/Kconfig | 13 +
security/brute/Makefile | 2 +
security/brute/brute.c | 749 ++++++++++++++++++++++++
security/security.c | 5 +
16 files changed, 943 insertions(+), 5 deletions(-)
create mode 100644 Documentation/admin-guide/LSM/Brute.rst
create mode 100644 include/brute/brute.h
create mode 100644 security/brute/Kconfig
create mode 100644 security/brute/Makefile
create mode 100644 security/brute/brute.c
next reply other threads:[~2020-10-25 13:47 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-25 13:45 John Wood [this message]
2020-10-25 13:45 ` [PATCH v2 1/8] security: Add LSM hook at the point where a task gets a fatal signal John Wood
2020-10-25 13:45 ` [PATCH v2 2/8] security/brute: Define a LSM and manage statistical data John Wood
2020-10-25 13:45 ` [PATCH v2 3/8] security/brute: Add sysctl attributes to allow detection fine tuning John Wood
2020-10-25 13:45 ` [PATCH v2 4/8] security/brute: Detect a fork brute force attack John Wood
2020-10-25 13:45 ` [PATCH v2 5/8] security/brute: Mitigate " John Wood
2020-10-25 13:45 ` [PATCH v2 6/8] security/brute: Add prctls to enable/disable the fork attack detection John Wood
2020-10-25 13:45 ` [PATCH v2 7/8] Documentation: Add documentation for the Brute LSM John Wood
2020-11-09 4:31 ` Randy Dunlap
2020-11-09 18:23 ` John Wood
2020-11-10 0:09 ` Randy Dunlap
2020-10-25 13:45 ` [PATCH v2 8/8] MAINTAINERS: Add a new entry " John Wood
2020-11-06 15:54 ` [PATCH v2 0/8] Fork brute force attack mitigation John Wood
2020-11-11 0:10 ` Kees Cook
2020-11-15 15:00 ` John Wood
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).