From: Paul Moore <paul@paul-moore.com>
To: Fan Wu <wufan@linux.microsoft.com>,
corbet@lwn.net, zohar@linux.ibm.com, jmorris@namei.org,
serge@hallyn.com, tytso@mit.edu, ebiggers@kernel.org,
axboe@kernel.dk, agk@redhat.com, snitzer@kernel.org,
eparis@redhat.com
Cc: linux-doc@vger.kernel.org, linux-integrity@vger.kernel.org,
linux-security-module@vger.kernel.org,
linux-fscrypt@vger.kernel.org, linux-block@vger.kernel.org,
dm-devel@lists.linux.dev, audit@vger.kernel.org,
linux-kernel@vger.kernel.org,
Deven Bowers <deven.desai@linux.microsoft.com>,
Fan Wu <wufan@linux.microsoft.com>
Subject: Re: [PATCH RFC v12 9/20] uapi|audit|ipe: add ipe auditing support
Date: Sat, 03 Feb 2024 17:25:11 -0500 [thread overview]
Message-ID: <16ecd49f9528749e288c8a4cc73c4425@paul-moore.com> (raw)
In-Reply-To: <1706654228-17180-10-git-send-email-wufan@linux.microsoft.com>
On Jan 30, 2024 Fan Wu <wufan@linux.microsoft.com> wrote:
>
> Users of IPE require a way to identify when and why an operation fails,
> allowing them to both respond to violations of policy and be notified
> of potentially malicious actions on their systems with respect to IPE
> itself.
>
> This patch introduces 3 new audit events.
>
> AUDIT_IPE_ACCESS(1420) indicates the result of an IPE policy evaluation
> of a resource.
> AUDIT_IPE_CONFIG_CHANGE(1421) indicates the current active IPE policy
> has been changed to another loaded policy.
> AUDIT_IPE_POLICY_LOAD(1422) indicates a new IPE policy has been loaded
> into the kernel.
>
> This patch also adds support for success auditing, allowing users to
> identify why an allow decision was made for a resource. However, it is
> recommended to use this option with caution, as it is quite noisy.
>
> Here are some examples of the new audit record types:
>
> AUDIT_IPE_ACCESS(1420):
>
> audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
> pid=297 comm="sh" path="/root/vol/bin/hello" dev="tmpfs"
> ino=3897 rule="op=EXECUTE boot_verified=TRUE action=ALLOW"
>
> audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
> pid=299 comm="sh" path="/mnt/ipe/bin/hello" dev="dm-0"
> ino=2 rule="DEFAULT action=DENY"
>
> audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
> pid=300 path="/tmp/tmpdp2h1lub/deny/bin/hello" dev="tmpfs"
> ino=131 rule="DEFAULT action=DENY"
>
> The above three records were generated when the active IPE policy only
> allows binaries from the initramfs to run. The three identical `hello`
> binary were placed at different locations, only the first hello from
> the rootfs(initramfs) was allowed.
>
> Field ipe_op followed by the IPE operation name associated with the log.
>
> Field ipe_hook followed by the name of the LSM hook that triggered the IPE
> event.
>
> Field enforcing followed by the enforcement state of IPE. (it will be
> introduced in the next commit)
>
> Field pid followed by the pid of the process that triggered the IPE
> event.
>
> Field comm followed by the command line program name of the process that
> triggered the IPE event.
>
> Field path followed by the file's path name.
>
> Field dev followed by the device name as found in /dev where the file is
> from.
> Note that for device mappers it will use the name `dm-X` instead of
> the name in /dev/mapper.
> For a file in a temp file system, which is not from a device, it will use
> `tmpfs` for the field.
> The implementation of this part is following another existing use case
> LSM_AUDIT_DATA_INODE in security/lsm_audit.c
>
> Field ino followed by the file's inode number.
>
> Field rule followed by the IPE rule made the access decision. The whole
> rule must be audited because the decision is based on the combination of
> all property conditions in the rule.
>
> Along with the syscall audit event, user can know why a blocked
> happened. For example:
>
> audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
> pid=2138 comm="bash" path="/mnt/ipe/bin/hello" dev="dm-0"
> ino=2 rule="DEFAULT action=DENY"
> audit[1956]: SYSCALL arch=c000003e syscall=59
> success=no exit=-13 a0=556790138df0 a1=556790135390 a2=5567901338b0
> a3=ab2a41a67f4f1f4e items=1 ppid=147 pid=1956 auid=4294967295 uid=0
> gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0
> ses=4294967295 comm="bash" exe="/usr/bin/bash" key=(null)
>
> The above two records showed bash used execve to run "hello" and got
> blocked by IPE. Note that the IPE records are always prior to a SYSCALL
> record.
>
> AUDIT_IPE_CONFIG_CHANGE(1421):
>
> audit: AUDIT1421
> old_active_pol_name="Allow_All" old_active_pol_version=0.0.0
> old_policy_digest=sha256:E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649
> new_active_pol_name="boot_verified" new_active_pol_version=0.0.0
> new_policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F
> auid=4294967295 ses=4294967295 lsm=ipe res=1
>
> The above record showed the current IPE active policy switch from
> `Allow_All` to `boot_verified` along with the version and the hash
> digest of the two policies. Note IPE can only have one policy active
> at a time, all access decision evaluation is based on the current active
> policy.
> The normal procedure to deploy a policy is loading the policy to deploy
> into the kernel first, then switch the active policy to it.
>
> AUDIT_IPE_POLICY_LOAD(1422):
>
> audit: AUDIT1422 policy_name="boot_verified" policy_version=0.0.0
> policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F2676
> auid=4294967295 ses=4294967295 lsm=ipe res=1
>
> The above record showed a new policy has been loaded into the kernel
> with the policy name, policy version and policy hash.
>
> Signed-off-by: Deven Bowers <deven.desai@linux.microsoft.com>
> Signed-off-by: Fan Wu <wufan@linux.microsoft.com>
> ---
> v2:
> + Split evaluation loop, access control hooks,
> and evaluation loop from policy parser and userspace
> interface to pass mailing list character limit
>
> v3:
> + Move ipe_load_properties to patch 04.
> + Remove useless 0-initializations
> + Prefix extern variables with ipe_
> + Remove kernel module parameters, as these are
> exposed through sysctls.
> + Add more prose to the IPE base config option
> help text.
> + Use GFP_KERNEL for audit_log_start.
> + Remove unnecessary caching system.
> + Remove comments from headers
> + Use rcu_access_pointer for rcu-pointer null check
> + Remove usage of reqprot; use prot only.
> + Move policy load and activation audit event to 03/12
>
> v4:
> + Remove sysctls in favor of securityfs nodes
> + Re-add kernel module parameters, as these are now
> exposed through securityfs.
> + Refactor property audit loop to a separate function.
>
> v5:
> + fix minor grammatical errors
> + do not group rule by curly-brace in audit record,
> reconstruct the exact rule.
>
> v6:
> + No changes
>
> v7:
> + Further split lsm creation, the audit system, the evaluation loop,
> and access control hooks into separate patches.
> + Further split audit system patch into two separate patches; one
> for include/uapi, and the usage of the new defines.
> + Split out the permissive functionality into another separate patch,
> for easier review.
> + Correct misuse of audit_log_n_untrusted string to audit_log_format
> + Use get_task_comm instead of comm directly.
> + Quote certain audit values
> + Remove unnecessary help text on choice options - these were
> previously indented at the wrong level
> + Correct a stale string constant (ctx_ns_enforce to ctx_enforce)
>
> v8:
>
> + Change dependency for CONFIG_AUDIT to CONFIG_AUDITSYSCALL
> + Drop ctx_* prefix
> + Reuse, where appropriate, the audit fields from the field
> dictionary. This transforms:
> ctx_pathname -> path
> ctx_ino -> ino
> ctx_dev -> dev
>
> + Add audit records and event examples to commit description.
> + Remove new_audit_ctx, replace with audit_log_start. All data that
> would provided by new_audit_ctx is already present in the syscall
> audit record, that is always emitted on these actions. The audit
> records should be correlated as such.
> + Change audit types:
> + AUDIT_TRUST_RESULT -> AUDIT_IPE_ACCESS
> + This prevents overloading of the AVC type.
> + AUDIT_TRUST_POLICY_ACTIVATE -> AUDIT_MAC_CONFIG_CHANGE
> + AUDIT_TRUST_POLICY_LOAD -> AUDIT_MAC_POLICY_LOAD
> + There were no significant difference in meaning between
> these types.
>
> + Remove enforcing parameter passed from the context structure
> for AUDIT_IPE_ACCESS.
> + This field can be inferred from the SYSCALL audit event,
> based on the success field.
>
> + Remove all fields already captured in the syscall record. "hook",
> an IPE specific field, can be determined via the syscall field in
> the syscall record itself, so it has been removed.
> + ino, path, and dev in IPE's record refer to the subject of the
> syscall, while the syscall record refers to the calling process.
>
> + remove IPE prefix from policy load/policy activation events
> + fix a bug wherein a policy change audit record was not fired when
> updating a policy
>
> v9:
> + Merge the AUDIT_IPE_ACCESS definition with the audit support commit
> + Change the audit format of policy load and switch
> + Remove the ipe audit kernel switch
>
> v10:
> + Create AUDIT_IPE_CONFIG_CHANGE and AUDIT_IPE_POLICY_LOAD
> + Change field names per upstream feedback
>
> v11:
> + Fix style issues
>
> v12:
> + Add ipe_op, ipe_hook, and enforcing fields to AUDIT_IPE_ACCESS
> ---
> include/uapi/linux/audit.h | 3 +
> security/ipe/Kconfig | 2 +-
> security/ipe/Makefile | 1 +
> security/ipe/audit.c | 212 +++++++++++++++++++++++++++++++++++++
> security/ipe/audit.h | 18 ++++
> security/ipe/eval.c | 44 ++++++--
> security/ipe/eval.h | 13 ++-
> security/ipe/fs.c | 70 ++++++++++++
> security/ipe/hooks.c | 10 +-
> security/ipe/hooks.h | 11 ++
> security/ipe/policy.c | 5 +
> 11 files changed, 372 insertions(+), 17 deletions(-)
> create mode 100644 security/ipe/audit.c
> create mode 100644 security/ipe/audit.h
...
> diff --git a/security/ipe/audit.c b/security/ipe/audit.c
> new file mode 100644
> index 000000000000..79b7af25085c
> --- /dev/null
> +++ b/security/ipe/audit.c
> @@ -0,0 +1,212 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) Microsoft Corporation. All rights reserved.
> + */
> +
> +#include <linux/slab.h>
> +#include <linux/audit.h>
> +#include <linux/types.h>
> +#include <crypto/hash.h>
> +
> +#include "ipe.h"
> +#include "eval.h"
> +#include "hooks.h"
> +#include "policy.h"
> +#include "audit.h"
> +
> +#define ACTSTR(x) ((x) == IPE_ACTION_ALLOW ? "ALLOW" : "DENY")
> +
> +#define IPE_AUDIT_HASH_ALG "sha256"
> +
> +#define AUDIT_POLICY_LOAD_FMT "policy_name=\"%s\" policy_version=%hu.%hu.%hu "\
> + "policy_digest=" IPE_AUDIT_HASH_ALG ":"
> +#define AUDIT_OLD_ACTIVE_POLICY_FMT "old_active_pol_name=\"%s\" "\
> + "old_active_pol_version=%hu.%hu.%hu "\
> + "old_policy_digest=" IPE_AUDIT_HASH_ALG ":"
> +#define AUDIT_NEW_ACTIVE_POLICY_FMT "new_active_pol_name=\"%s\" "\
> + "new_active_pol_version=%hu.%hu.%hu "\
> + "new_policy_digest=" IPE_AUDIT_HASH_ALG ":"
> +
> +static const char *const audit_op_names[__IPE_OP_MAX + 1] = {
> + "EXECUTE",
> + "FIRMWARE",
> + "KMODULE",
> + "KEXEC_IMAGE",
> + "KEXEC_INITRAMFS",
> + "POLICY",
> + "X509_CERT",
> + "UNKNOWN",
> +};
> +
> +static const char *const audit_hook_names[__IPE_HOOK_MAX] = {
> + "BPRM_CHECK",
> + "MMAP",
> + "MPROTECT",
> + "KERNEL_READ",
> + "KERNEL_LOAD",
> +};
> +
> +static const char *const audit_prop_names[__IPE_PROP_MAX] = {
> +#ifdef CONFIG_BLK_DEV_INITRD
> + "boot_verified=FALSE",
> + "boot_verified=TRUE",
> +#endif /* CONFIG_BLK_DEV_INITRD */
> +};
I think we can get rid of the preprocessor checks here.
--
paul-moore.com
next prev parent reply other threads:[~2024-02-03 22:25 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-30 22:36 [RFC PATCH v12 00/20] Integrity Policy Enforcement LSM (IPE) Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 01/20] security: add ipe lsm Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 02/20] ipe: add policy parser Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 03/20] ipe: add evaluation loop Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 04/20] ipe: add LSM hooks on execution and kernel read Fan Wu
2024-02-02 14:47 ` kernel test robot
2024-01-30 22:36 ` [RFC PATCH v12 05/20] initramfs|security: Add security hook to initramfs unpack Fan Wu
2024-02-03 22:25 ` [PATCH RFC v12 5/20] " Paul Moore
2024-02-05 21:18 ` Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 06/20] ipe: introduce 'boot_verified' as a trust provider Fan Wu
2024-02-03 22:25 ` [PATCH RFC v12 6/20] " Paul Moore
2024-02-05 22:39 ` Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 07/20] security: add new securityfs delete function Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 08/20] ipe: add userspace interface Fan Wu
2024-02-03 22:25 ` [PATCH RFC v12 8/20] " Paul Moore
2024-02-05 23:01 ` Fan Wu
2024-02-05 23:10 ` Paul Moore
2024-02-05 23:21 ` Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 09/20] uapi|audit|ipe: add ipe auditing support Fan Wu
2024-02-03 22:25 ` Paul Moore [this message]
2024-01-30 22:36 ` [RFC PATCH v12 10/20] ipe: add permissive toggle Fan Wu
2024-02-03 22:25 ` [PATCH RFC " Paul Moore
2024-01-30 22:36 ` [RFC PATCH v12 11/20] block|security: add LSM blob to block_device Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 12/20] dm verity: set DM_TARGET_SINGLETON feature flag Fan Wu
2024-02-02 18:51 ` Mike Snitzer
2024-02-03 3:56 ` Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 13/20] dm: add finalize hook to target_type Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 14/20] dm verity: consume root hash digest and signature data via LSM hook Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 15/20] ipe: add support for dm-verity as a trust provider Fan Wu
2024-02-03 22:25 ` [PATCH RFC " Paul Moore
2024-02-05 23:11 ` Fan Wu
2024-02-06 21:53 ` Paul Moore
2024-01-30 22:37 ` [RFC PATCH v12 16/20] fsverity: consume builtin signature via LSM hook Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 17/20] ipe: enable support for fs-verity as a trust provider Fan Wu
2024-02-03 22:25 ` [PATCH RFC " Paul Moore
2024-01-30 22:37 ` [RFC PATCH v12 18/20] scripts: add boot policy generation program Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 19/20] ipe: kunit test for parser Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 20/20] documentation: add ipe documentation Fan Wu
Reply instructions:
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:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=16ecd49f9528749e288c8a4cc73c4425@paul-moore.com \
--to=paul@paul-moore.com \
--cc=agk@redhat.com \
--cc=audit@vger.kernel.org \
--cc=axboe@kernel.dk \
--cc=corbet@lwn.net \
--cc=deven.desai@linux.microsoft.com \
--cc=dm-devel@lists.linux.dev \
--cc=ebiggers@kernel.org \
--cc=eparis@redhat.com \
--cc=jmorris@namei.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=serge@hallyn.com \
--cc=snitzer@kernel.org \
--cc=tytso@mit.edu \
--cc=wufan@linux.microsoft.com \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.