linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Fan Wu <wufan@linux.microsoft.com>
To: Paul Moore <paul@paul-moore.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@redhat.com, audit@vger.kernel.org,
	roberto.sassu@huawei.com, linux-kernel@vger.kernel.org,
	Deven Bowers <deven.desai@linux.microsoft.com>
Subject: Re: [PATCH RFC v11 8/19] uapi|audit|ipe: add ipe auditing support
Date: Thu, 2 Nov 2023 15:55:11 -0700	[thread overview]
Message-ID: <d2a51f1e-14eb-4757-a1b8-1dcfb4635002@linux.microsoft.com> (raw)
In-Reply-To: <9217384a1f58c5d3431b90f100c7de85.paul@paul-moore.com>



On 10/23/2023 8:52 PM, Paul Moore wrote:
> On Oct  4, 2023 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 path="/root/vol/bin/hello" dev="sda"
>>        ino=3897 rule="op=EXECUTE boot_verified=TRUE action=ALLOW"
>>
>>      audit: AUDIT1420 path="/mnt/ipe/bin/hello" dev="dm-0"
>>        ino=2 rule="DEFAULT action=DENY"
>>
>>      audit: AUDIT1420 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 initial booted drive(sda) to run. The three
>> identical `hello` binary were placed at different locations, only the
>> first hello from sda was allowed.
>>
>> 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 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:820EEA5B40CA42B51F68962354BA083122A20BB846F26765076DD
>> 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>
...
>> ---
>>   include/uapi/linux/audit.h |   3 +
>>   security/ipe/Kconfig       |   2 +-
>>   security/ipe/Makefile      |   1 +
>>   security/ipe/audit.c       | 195 +++++++++++++++++++++++++++++++++++++
>>   security/ipe/audit.h       |  18 ++++
>>   security/ipe/eval.c        |  32 ++++--
>>   security/ipe/eval.h        |   8 ++
>>   security/ipe/fs.c          |  70 +++++++++++++
>>   security/ipe/policy.c      |   5 +
>>   9 files changed, 327 insertions(+), 7 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..e123701d5e3b
>> --- /dev/null
>> +++ b/security/ipe/audit.c
>> @@ -0,0 +1,195 @@
>> +// 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] = {
>> +	"EXECUTE",
>> +	"FIRMWARE",
>> +	"KMODULE",
>> +	"KEXEC_IMAGE",
>> +	"KEXEC_INITRAMFS",
>> +	"IMA_POLICY",
>> +	"IMA_X509_CERT",
>> +};
>> +
>> +static const char *const audit_prop_names[__IPE_PROP_MAX] = {
>> +	"boot_verified=FALSE",
>> +	"boot_verified=TRUE",
>> +};
> 
> I would suggest taking the same approach for both @audit_op_names and
> @audit_prop_names; either include the field name in the string array
> for both or leave it out of both.
>
Yes sure, I will move the "op=" into audit_op_names.

>> +/**
>> + * audit_rule - audit an IPE policy rule approximation.
>> + * @ab: Supplies a pointer to the audit_buffer to append to.
>> + * @r: Supplies a pointer to the ipe_rule to approximate a string form for.
>> + */
>> +static void audit_rule(struct audit_buffer *ab, const struct ipe_rule *r)
>> +{
>> +	const struct ipe_prop *ptr;
>> +
>> +	audit_log_format(ab, "rule=\"op=%s ", audit_op_names[r->op]);
>> +
>> +	list_for_each_entry(ptr, &r->props, next)
>> +		audit_log_format(ab, "%s ", audit_prop_names[ptr->type]);
>> +
>> +	audit_log_format(ab, "action=%s\"", ACTSTR(r->action));
>> +}
>> +
>> +/**
>> + * ipe_audit_match - audit a match for IPE policy.
>> + * @ctx: Supplies a pointer to the evaluation context that was used in the
>> + *	 evaluation.
>> + * @match_type: Supplies the scope of the match: rule, operation default,
>> + *		global default.
>> + * @act: Supplies the IPE's evaluation decision, deny or allow.
>> + * @r: Supplies a pointer to the rule that was matched, if possible.
>> + * @enforce: Supplies the enforcement/permissive state at the point
>> + *	     the enforcement decision was made.
>> + */
> 
> Does it make sense to move @match_type into the ipe_eval_ctx struct?
> 
I feel the @match_type is part of the evaluation result information, 
which is the result of the context against the active policy. So I 
prefer keeping it as a local variable in the evaluation loop.

-Fan
>> +void ipe_audit_match(const struct ipe_eval_ctx *const ctx,
>> +		     enum ipe_match match_type,
>> +		     enum ipe_action_type act, const struct ipe_rule *const r)
>> +{
>> +	struct inode *inode;
>> +	struct audit_buffer *ab;
>> +	const char *op = audit_op_names[ctx->op];
>> +
>> +	if (act != IPE_ACTION_DENY && !READ_ONCE(success_audit))
>> +		return;
>> +
>> +	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_IPE_ACCESS);
>> +	if (!ab)
>> +		return;
>> +
>> +	if (ctx->file) {
>> +		audit_log_d_path(ab, "path=", &ctx->file->f_path);
>> +		inode = file_inode(ctx->file);
>> +		if (inode) {
>> +			audit_log_format(ab, " dev=");
>> +			audit_log_untrustedstring(ab, inode->i_sb->s_id);
>> +			audit_log_format(ab, " ino=%lu ", inode->i_ino);
>> +		}
>> +	}
>> +
>> +	if (match_type == IPE_MATCH_RULE)
>> +		audit_rule(ab, r);
>> +	else if (match_type == IPE_MATCH_TABLE)
>> +		audit_log_format(ab, "rule=\"DEFAULT op=%s action=%s\"", op,
>> +				 ACTSTR(act));
>> +	else
>> +		audit_log_format(ab, "rule=\"DEFAULT action=%s\"",
>> +				 ACTSTR(act));
>> +
>> +	audit_log_end(ab);
>> +}
> 
> --
> paul-moore.com

  reply	other threads:[~2023-11-02 22:55 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-04 22:09 [RFC PATCH v11 00/19] Integrity Policy Enforcement LSM (IPE) Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 01/19] security: add ipe lsm Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 02/19] ipe: add policy parser Fan Wu
2023-10-24  3:52   ` [PATCH RFC v11 2/19] " Paul Moore
2023-10-25 22:45     ` Fan Wu
2023-10-26 21:36       ` Paul Moore
2023-10-04 22:09 ` [RFC PATCH v11 03/19] ipe: add evaluation loop Fan Wu
2023-10-24  3:52   ` [PATCH RFC v11 3/19] " Paul Moore
2023-10-26  0:15     ` Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 04/19] ipe: add LSM hooks on execution and kernel read Fan Wu
2023-10-24  3:52   ` [PATCH RFC v11 4/19] " Paul Moore
2023-10-04 22:09 ` [RFC PATCH v11 05/19] ipe: introduce 'boot_verified' as a trust provider Fan Wu
2023-10-24  3:52   ` [PATCH RFC v11 5/19] " Paul Moore
2023-10-26 21:33     ` Fan Wu
2023-10-26 22:12       ` Paul Moore
2023-11-02 22:46         ` Fan Wu
2023-11-03 22:15           ` Paul Moore
2023-11-03 22:30             ` Paul Moore
2023-10-04 22:09 ` [RFC PATCH v11 06/19] security: add new securityfs delete function Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 07/19] ipe: add userspace interface Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 08/19] uapi|audit|ipe: add ipe auditing support Fan Wu
2023-10-24  3:52   ` [PATCH RFC v11 8/19] " Paul Moore
2023-11-02 22:55     ` Fan Wu [this message]
2023-10-04 22:09 ` [RFC PATCH v11 09/19] ipe: add permissive toggle Fan Wu
2023-10-24  3:52   ` [PATCH RFC v11 9/19] " Paul Moore
2023-11-02 22:56     ` Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 10/19] block|security: add LSM blob to block_device Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 11/19] dm verity: set DM_TARGET_SINGLETON feature flag Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-11-02  0:40     ` Paul Moore
2023-10-04 22:09 ` [RFC PATCH v11 12/19] dm: add finalize hook to target_type Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-11-02  0:41     ` Paul Moore
2023-10-04 22:09 ` [RFC PATCH v11 13/19] dm verity: consume root hash digest and signature data via LSM hook Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-11-02  0:41     ` Paul Moore
2023-10-04 22:09 ` [RFC PATCH v11 14/19] ipe: add support for dm-verity as a trust provider Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-11-02 22:40     ` Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 15/19] fsverity: consume builtin signature via LSM hook Fan Wu
2023-10-05  2:27   ` Eric Biggers
2023-10-05  2:49     ` Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-11-02  0:40     ` Paul Moore
2023-11-02  2:53       ` Eric Biggers
2023-11-02 15:42         ` Paul Moore
2023-11-02 19:33           ` Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 16/19] ipe: enable support for fs-verity as a trust provider Fan Wu
2023-10-04 23:58   ` Randy Dunlap
2023-10-05  2:45     ` Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-10-04 22:09 ` [RFC PATCH v11 17/19] scripts: add boot policy generation program Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-11-02 23:09     ` Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 18/19] ipe: kunit test for parser Fan Wu
2023-10-24  3:52   ` [PATCH RFC " Paul Moore
2023-11-02 23:11     ` Fan Wu
2023-10-04 22:09 ` [RFC PATCH v11 19/19] 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=d2a51f1e-14eb-4757-a1b8-1dcfb4635002@linux.microsoft.com \
    --to=wufan@linux.microsoft.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@redhat.com \
    --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=paul@paul-moore.com \
    --cc=roberto.sassu@huawei.com \
    --cc=serge@hallyn.com \
    --cc=snitzer@kernel.org \
    --cc=tytso@mit.edu \
    --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 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).