Skip to content
Permalink
Browse files
NAX LSM: Add initial support
Add initial support for NAX (No Anonymous Execution), which is a Linux
Security Module that extends DAC by making impossible to make anonymous
and modified pages executable for privileged processes.

Intercepts anonymous executable pages created with mmap() and mprotect()
system calls.

Log violations (in non-quiet mode) and block the action or kill the
offending process, depending on the enabled settings.

See Documentation/admin-guide/LSM/NAX.rst.

Signed-off-by: Igor Zhbanov <izh1979@gmail.com>
  • Loading branch information
izh1979 authored and intel-lab-lkp committed Aug 20, 2021
1 parent 349a2d5 commit 6c93ee3871fae69975f9fc3c41c0f65743ea7ac8
Show file tree
Hide file tree
Showing 9 changed files with 703 additions and 5 deletions.
@@ -0,0 +1,72 @@
=======
NAX LSM
=======

:Author: Igor Zhbanov

NAX (No Anonymous Execution) is a Linux Security Module that extends DAC
by making impossible to make anonymous and modified pages executable for
processes. The module intercepts anonymous executable pages created with
mmap() and mprotect() system calls.

To select it at boot time, add ``nax`` to ``security`` kernel command-line
parameter.

The following sysctl parameters are available:

* ``kernel.nax.check_all``:
- 0: Check all processes.
- 1: Check only privileged processes. The privileged process is a process
for which any of the following is true:
- ``uid == 0``
- ``euid == 0``
- ``suid == 0``
- ``cap_effective`` has any capability except for the ones allowed
in ``kernel.nax.allowed_caps``
- ``cap_permitted`` has any capability except for the ones allowed
in ``kernel.nax.allowed_caps``

Checking of uid/euid/suid is important because a process may call seteuid(0)
to gain privileges (if SECURE_NO_SETUID_FIXUP secure bit is not set).

* ``kernel.nax.allowed_caps``:

Hexadecimal number representing the set of capabilities a non-root
process can possess without being considered "privileged" by NAX LSM.

For the meaning of the capabilities bits and their value, please check
``include/uapi/linux/capability.h`` and ``capabilities(7)`` manual page.

For example, ``CAP_SYS_PTRACE`` has a number 19. Therefore, to add it to
allowed capabilities list, we need to set 19'th bit (2^19 or 1 << 19)
or 80000 in hexadecimal form. Capabilities can be bitwise ORed.

* ``kernel.nax.mode``:

- 0: Only log errors (when enabled by ``kernel.nax.quiet``) (default mode)
- 1: Forbid unsafe pages mappings (and log when enabled)
- 2: Kill the violating process (and log when enabled)

* ``kernel.nax.quiet``:

- 0: Log violations (default)
- 1: Be quiet

* ``kernel.nax.locked``:

- 0: Changing of the module's sysctl parameters is allowed
- 1: Further changing of the module's sysctl parameters is forbidden

Setting this parameter to ``1`` after initial setup during the system boot
will prevent the module disabling at the later time.

There are matching kernel command-line parameters (with the same values):

- ``nax_allowed_caps``
- ``nax_check_all``
- ``nax_mode``
- ``nax_quiet``
- ``nax_locked``

The ``nax_locked`` command-line parameter must be specified last to avoid
premature setting locking.
@@ -42,6 +42,7 @@ subdirectories.

apparmor
LoadPin
NAX
SELinux
Smack
tomoyo
@@ -131,6 +131,7 @@ parameter is applicable::
MOUSE Appropriate mouse support is enabled.
MSI Message Signaled Interrupts (PCI).
MTD MTD (Memory Technology Device) support is enabled.
NAX NAX support is enabled.
NET Appropriate network support is enabled.
NUMA NUMA support is enabled.
NFS Appropriate NFS support is enabled.
@@ -3062,6 +3062,38 @@

n2= [NET] SDL Inc. RISCom/N2 synchronous serial card

nax_allowed_caps= [NAX] Hexadecimal number representing the set of
capabilities a non-root process can possess without
being considered "privileged" by NAX LSM.

For the meaning of the capabilities bits and their
value, please check include/uapi/linux/capability.h
and capabilities(7) manual page.

For example, `CAP_SYS_PTRACE` has a number 19.
Therefore, to add it to allowed capabilities list,
we need to set 19'th bit (2^19 or 1 << 19) or 80000
in hexadecimal form. Capabilities can be bitwise ORed.

nax_check_all= [NAX] NAX LSM processes checking mode:
0 - Check only privileged processes (default).
1 - Check all processes.

nax_locked= [NAX] NAX LSM settings' locking mode:
0 - Changing NAX sysctl parameters is allowed.
1 - Changing NAX sysctl parameters is forbidden until
reboot.

nax_mode= [NAX] NAX LSM violation reaction mode:
0 - Only log errors (when not in quiet mode; default).
1 - Forbid unsafe pages mappings (and log when
enabled).
2 - Kill the violating process (and log when enabled).

nax_quiet= [NAX] NAX LSM log verbosity:
0 - Log messages to syslog.
1 - Be quiet.

netdev= [NET] Network devices parameters
Format: <irq>,<io>,<mem_start>,<mem_end>,<name>
Note that mem_start is often overloaded to mean
@@ -239,6 +239,7 @@ source "security/yama/Kconfig"
source "security/safesetid/Kconfig"
source "security/lockdown/Kconfig"
source "security/landlock/Kconfig"
source "security/nax/Kconfig"

source "security/integrity/Kconfig"

@@ -278,11 +279,11 @@ endchoice

config LSM
string "Ordered list of enabled LSMs"
default "landlock,lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
default "landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
default "landlock,lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
default "landlock,lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
default "landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
default "nax,landlock,lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
default "nax,landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
default "nax,landlock,lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
default "nax,landlock,lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
default "nax,landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
help
A comma-separated list of LSMs, in initialization order.
Any LSMs left off this list will be ignored. This can be
@@ -14,6 +14,7 @@ subdir-$(CONFIG_SECURITY_SAFESETID) += safesetid
subdir-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown
subdir-$(CONFIG_BPF_LSM) += bpf
subdir-$(CONFIG_SECURITY_LANDLOCK) += landlock
subdir-$(CONFIG_SECURITY_NAX) += nax

# always enable default capabilities
obj-y += commoncap.o
@@ -34,6 +35,7 @@ obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown/
obj-$(CONFIG_CGROUPS) += device_cgroup.o
obj-$(CONFIG_BPF_LSM) += bpf/
obj-$(CONFIG_SECURITY_LANDLOCK) += landlock/
obj-$(CONFIG_SECURITY_NAX) += nax/

# Object integrity file lists
subdir-$(CONFIG_INTEGRITY) += integrity
@@ -0,0 +1,113 @@
# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_NAX
bool "NAX support"
depends on SECURITY
help
This selects NAX (No Anonymous Execution), which extends DAC
support with additional system-wide security settings beyond
regular Linux discretionary access controls. Currently, the only
available behavior is restricting the execution of anonymous and
modified pages.

The module can restrict either privileged or all processes,
depending on the settings. It is possible to configure action,
performed when the violation is detected (log, log + block,
log + kill).

Further information can be found in
Documentation/admin-guide/LSM/NAX.rst.

If you are unsure how to answer this question, answer N.

choice
prompt "NAX violation action mode"
default SECURITY_NAX_MODE_LOG
depends on SECURITY_NAX
help
Select the NAX violation action mode.

In the default permissive mode the violations are only logged
(if logging is not suppressed). In the enforcing mode the violations
are prohibited. And in the kill mode the process is terminated.

The value can be overridden at boot time with the kernel command-line
parameter "nax_mode=" (0, 1, 2) or "kernel.nax.mode=" (0, 1, 2)
sysctl parameter (if the settings are not locked).

config SECURITY_NAX_MODE_LOG
bool "Permissive mode"
help
In this mode violations are only logged (if logging is not
suppressed by the "kernel.nax.quiet" parameter). The
violating system call will not be prohibited.
config SECURITY_NAX_MODE_ENFORCING
bool "Enforcing mode"
help
In this mode violations are prohibited and logged (if
logging is not suppressed by the "kernel.nax.quiet"
parameter). The violating system call will return -EACCES
error.
config SECURITY_NAX_MODE_KILL
bool "Kill mode"
help
In this mode the violating process is terminated on the
first violation system call. The violation event is logged
(if logging is not suppressed by the "kernel.nax.quiet"
parameter).
endchoice

config SECURITY_NAX_MODE
int
depends on SECURITY_NAX
default 0 if SECURITY_NAX_MODE_LOG
default 1 if SECURITY_NAX_MODE_ENFORCING
default 2 if SECURITY_NAX_MODE_KILL

config SECURITY_NAX_CHECK_ALL
bool "Check all processes"
depends on SECURITY_NAX
help
If selected, NAX will check all processes. If not selected, NAX
will check only privileged processes (which is determined either
by having zero uid, euid, suid or fsuid; or by possessing
capabilities outside of allowed set).

The value can also be overridden at boot time with the kernel
command-line parameter "nax_check_all=" (0, 1) or
"kernel.nax.check_all=" (0, 1) sysctl parameter (if the settings
are not locked).

config SECURITY_NAX_ALLOWED_CAPS
hex "Process capabilities ignored by NAX"
default 0x0
range 0x0 0xffffffffffff
depends on SECURITY_NAX
help
Hexadecimal number representing the set of capabilities
a non-root process can possess without being considered
"privileged" by NAX LSM.

The value can be overridden at boot time with the command-line
parameter "nax_allowed_caps=" or "kernel.nax.allowed_caps=" sysctl
parameter (if the settings are not locked).

config SECURITY_NAX_QUIET
bool "Silence NAX messages"
depends on SECURITY_NAX
help
If selected, NAX will not print violations.

The value can be overridden at boot with the command-line
parameter "nax_quiet=" (0, 1) or "kernel.nax.quiet=" (0, 1) sysctl
parameter (if the settings are not locked).

config SECURITY_NAX_LOCKED
bool "Lock NAX settings"
depends on SECURITY_NAX
help
Prevent any update to the settings of the NAX LSM. This applies to
both sysctl writes and the kernel command line.

If not selected, it can be enabled at boot time with the kernel
command-line parameter "nax_locked=1" or "kernel.nax_locked=1"
sysctl parameter (if the settings are not locked).
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_SECURITY_NAX) := nax.o

nax-y := nax-lsm.o

0 comments on commit 6c93ee3

Please sign in to comment.