[PATCH v14 00/26] ima: Namespace IMA with audit support in IMA-ns

Stefan Berger
2022-09-15T19:33:02Z

The goal of this series of patches is to start with the namespacing of
IMA and support auditing within an IMA namespace (IMA-ns) as the first
step.

In this series the IMA namespace is piggybacking on the user namespace
and therefore an IMA namespace is created when a user namespace is
created, although this is done late when SecurityFS is mounted inside
a user namespace. The advantage of piggybacking on the user namespace
is that the user namespace can provide the keys infrastructure that IMA
appraisal support will need later on.

We chose the goal of supporting auditing within an IMA namespace since it
requires the least changes to IMA. Following this series, auditing within
an IMA namespace can be activated by a root running the following lines
that rely on a statically linked busybox to be installed on the host for
execution within the minimal container environment:

As root (since audit rules may now only be set by root):

mkdir -p rootfs/{bin,mnt,proc}
cp /sbin/busybox rootfs/bin
cp /sbin/busybox rootfs/bin/busybox2
echo >> rootfs/bin/busybox2
PATH=/bin unshare --user --map-root-user --mount-proc --pid --fork \
--root rootfs busybox sh -c \
"busybox mount -t securityfs /mnt /mnt; \
busybox echo 1 > /mnt/ima/active; \
busybox echo 'audit func=BPRM_CHECK mask=MAY_EXEC' > /mnt/ima/policy; \
busybox2 cat /mnt/ima/policy"

[busybox2 is used to demonstrate 2 audit messages; see below]

Following the audit log on the host the last line cat'ing the IMA policy
inside the namespace would have been audited. Unfortunately the auditing
line is not distinguishable from one stemming from actions on the host.
The hope here is that Richard Brigg's container id support for auditing
would help resolve the problem.

In the above the writing of '1' to the 'active' file is used to activate
the IMA namespace. Future extensions to IMA namespaces will make use of
the configuration stage after the mounting of securityfs and before the
activation to for example choose the measurement log template.

The following lines added to a suitable IMA policy on the host would
cause the execution of the commands inside the container (by uid 1000)
to be measured and audited as well on the host, thus leading to two
auditing messages for the 'busybox2 cat' above and log entries in IMA's
system log.

echo -e "measure func=BPRM_CHECK mask=MAY_EXEC uid=1000\n" \
"audit func=BPRM_CHECK mask=MAY_EXEC uid=1000\n" \
> /sys/kernel/security/ima/policy

The goal of supporting measurement and auditing by the host, of actions
occurring within IMA namespaces, is that users, particularly root,
should not be able to evade the host's IMA policy just by spawning
new IMA namespaces, running programs there, and discarding the namespaces
again. This is achieved through 'hierarchical processing' of file
accesses that are evaluated against the policy of the namespace where
the action occurred and against all namespaces' and their policies leading
back to the root IMA namespace (init_ima_ns).

The patch series adds support for a virtualized SecurityFS with a few
new API calls that are used by IMA namespacing. Only the data relevant
to the IMA namespace are shown. The files and directories of other
security subsystems (TPM, evm, Tomoyo, safesetid) are not showing
up when secruityfs is mounted inside a user namespace.

Much of the code following the virtualization of SecurityFS deals
with moving IMA's variables from various files into the IMA namespace
structure called 'ima_namespace'. When it comes to determining the
current IMA namespace I took the approach to get the current IMA
namespace (get_current_ns()) on the top level and pass the pointer all
the way down to those functions that now need access to the ima_namespace
to get to their variables. This later on comes in handy once hierarchical
processing is implemented in this series where we walk the list of
namespaces backwards and again need to pass the pointer into functions.

This patch also introduces usage of CAP_MAC_ADMIN to allow access to the
IMA policy via reduced capabilities. We would again later on use this
capability to allow users to set file extended attributes for IMA
appraisal support.

My tree with these patches is here:

git fetch https://github.com/stefanberger/linux-ima-namespaces v6.0-rc5+imans.v14.posted

Regards,
Stefan

Christian Brauner (1):
securityfs: rework dentry creation

Mehmet Kayaalp (2):
integrity/ima: Define ns_status for storing namespaced iint data
ima: Namespace audit status flags

Stefan Berger (23):
securityfs: Extend securityfs with namespacing support
ima: Define ima_namespace struct and start moving variables into it
ima: Move arch_policy_entry into ima_namespace
ima: Move ima_htable into ima_namespace
ima: Move measurement list related variables into ima_namespace
ima: Move some IMA policy and filesystem related variables into
ima_namespace
ima: Move IMA securityfs files into ima_namespace or onto stack
ima: Move ima_lsm_policy_notifier into ima_namespace
ima: Switch to lazy lsm policy updates for better performance
ima: Define mac_admin_ns_capable() as a wrapper for ns_capable()
ima: Only accept AUDIT rules for non-init_ima_ns namespaces for now
userns: Add pointer to ima_namespace to user_namespace
ima: Implement hierarchical processing of file accesses
ima: Implement ima_free_policy_rules() for freeing of an ima_namespace
ima: Add functions for creating and freeing of an ima_namespace
integrity: Add optional callback function to integrity_inode_free()
ima: Remove unused iints from the integrity_iint_cache
ima: Setup securityfs for IMA namespace
ima: Introduce securityfs file to activate an IMA namespace
ima: Show owning user namespace's uid and gid when displaying policy
ima: Limit number of policy rules in non-init_ima_ns
ima: Restrict informational audit messages to init_ima_ns
ima: Enable IMA namespaces

include/linux/capability.h | 6 +
include/linux/fs.h | 5 +
include/linux/ima.h | 36 ++
include/linux/integrity.h | 8 +-
include/linux/user_namespace.h | 9 +
init/Kconfig | 14 +
kernel/user.c | 4 +
kernel/user_namespace.c | 2 +
security/inode.c | 83 +++-
security/integrity/iint.c | 26 +-
security/integrity/ima/Makefile | 3 +-
security/integrity/ima/ima.h | 256 ++++++++++--
security/integrity/ima/ima_api.c | 44 ++-
security/integrity/ima/ima_appraise.c | 42 +-
security/integrity/ima/ima_asymmetric_keys.c | 8 +-
security/integrity/ima/ima_fs.c | 255 +++++++++---
security/integrity/ima/ima_init.c | 19 +-
security/integrity/ima/ima_init_ima_ns.c | 65 ++++
security/integrity/ima/ima_kexec.c | 15 +-
security/integrity/ima/ima_main.c | 238 +++++++++---
security/integrity/ima/ima_ns.c | 61 +++
security/integrity/ima/ima_ns_status.c | 385 +++++++++++++++++++
security/integrity/ima/ima_policy.c | 314 ++++++++++-----
security/integrity/ima/ima_queue.c | 63 ++-
security/integrity/ima/ima_queue_keys.c | 11 +-
security/integrity/ima/ima_template.c | 5 +-
security/integrity/integrity.h | 39 +-
security/security.c | 2 +-
28 files changed, 1659 insertions(+), 359 deletions(-)
create mode 100644 security/integrity/ima/ima_init_ima_ns.c
create mode 100644 security/integrity/ima/ima_ns.c
create mode 100644 security/integrity/ima/ima_ns_status.c

base-commit: 80e78fcce86de0288793a0ef0f6acf37656ee4cf
prerequisite-patch-id: 593c4930403a507f88e8cb15ecd32b592ff900b2
--
2.36.1