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@lists.linux.dev, audit@vger.kernel.org,
linux-kernel@vger.kernel.org,
Deven Bowers <deven.desai@linux.microsoft.com>
Subject: Re: [PATCH RFC v12 8/20] ipe: add userspace interface
Date: Mon, 5 Feb 2024 15:01:18 -0800 [thread overview]
Message-ID: <6e7c707c-28cd-42ec-a617-6f8d2ce9da4f@linux.microsoft.com> (raw)
In-Reply-To: <737a8ea0323b3db38044813041215bac@paul-moore.com>
On 2/3/2024 2:25 PM, Paul Moore wrote:
> On Jan 30, 2024 Fan Wu <wufan@linux.microsoft.com> wrote:
>>
>> As is typical with LSMs, IPE uses securityfs as its interface with
>> userspace. for a complete list of the interfaces and the respective
>> inputs/outputs, please see the documentation under
>> admin-guide/LSM/ipe.rst
>>
>> 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 policy load and activation audit event to 03/12
>> + Fix a potential panic when a policy failed to load.
>> + use pr_warn for a failure to parse instead of an
>> audit record
>> + Remove comments from headers
>> + Add lockdep assertions to ipe_update_active_policy and
>> ipe_activate_policy
>> + Fix up warnings with checkpatch --strict
>> + Use file_ns_capable for CAP_MAC_ADMIN for securityfs
>> nodes.
>> + Use memdup_user instead of kzalloc+simple_write_to_buffer.
>> + Remove strict_parse command line parameter, as it is added
>> by the sysctl command line.
>> + Prefix extern variables with ipe_
>>
>> v4:
>> + Remove securityfs to reverse-dependency
>> + Add SHA1 reverse dependency.
>> + Add versioning scheme for IPE properties, and associated
>> interface to query the versioning scheme.
>> + Cause a parser to always return an error on unknown syntax.
>> + Remove strict_parse option
>> + Change active_policy interface from sysctl, to securityfs,
>> and change scheme.
>>
>> v5:
>> + Cause an error if a default action is not defined for each
>> operation.
>> + Minor function renames
>>
>> v6:
>> + No changes
>>
>> v7:
>> + Propagating changes to support the new ipe_context structure in the
>> evaluation loop.
>>
>> + Further split the parser and userspace interface changes into
>> separate commits.
>>
>> + "raw" was renamed to "pkcs7" and made read only
>> + "raw"'s write functionality (update a policy) moved to "update"
>> + introduced "version", "policy_name" nodes.
>> + "content" renamed to "policy"
>> + changes to allow the compiled-in policy to be treated
>> identical to deployed-after-the-fact policies.
>>
>> v8:
>> + Prevent securityfs initialization if the LSM is disabled
>>
>> v9:
>> + Switch to securityfs_recursive_remove for policy folder deletion
>>
>> v10:
>> + Simplify and correct concurrency
>> + Fix typos
>>
>> v11:
>> + Correct code comments
>>
>> v12:
>> + Correct locking and remove redundant code
>> ---
>> security/ipe/Makefile | 2 +
>> security/ipe/fs.c | 101 +++++++++
>> security/ipe/fs.h | 16 ++
>> security/ipe/ipe.c | 3 +
>> security/ipe/ipe.h | 2 +
>> security/ipe/policy.c | 123 ++++++++++
>> security/ipe/policy.h | 9 +
>> security/ipe/policy_fs.c | 469 +++++++++++++++++++++++++++++++++++++++
>> 8 files changed, 725 insertions(+)
>> create mode 100644 security/ipe/fs.c
>> create mode 100644 security/ipe/fs.h
>> create mode 100644 security/ipe/policy_fs.c
>
> ...
>
>> diff --git a/security/ipe/policy.c b/security/ipe/policy.c
>> index f22a576a6d68..61fea3e38e11 100644
>> --- a/security/ipe/policy.c
>> +++ b/security/ipe/policy.c
>> @@ -43,6 +71,68 @@ static int set_pkcs7_data(void *ctx, const void *data, size_t len,
>> return 0;
>> }
>>
>> +/**
>> + * ipe_update_policy - parse a new policy and replace old with it.
>> + * @root: Supplies a pointer to the securityfs inode saved the policy.
>> + * @text: Supplies a pointer to the plain text policy.
>> + * @textlen: Supplies the length of @text.
>> + * @pkcs7: Supplies a pointer to a buffer containing a pkcs7 message.
>> + * @pkcs7len: Supplies the length of @pkcs7len.
>> + *
>> + * @text/@textlen is mutually exclusive with @pkcs7/@pkcs7len - see
>> + * ipe_new_policy.
>> + *
>> + * Context: Requires root->i_rwsem to be held.
>> + * Return:
>> + * * !IS_ERR - The existing policy saved in the inode before update
>> + * * -ENOENT - Policy doesn't exist
>> + * * -EINVAL - New policy is invalid
>> + */
>> +struct ipe_policy *ipe_update_policy(struct inode *root,
>> + const char *text, size_t textlen,
>> + const char *pkcs7, size_t pkcs7len)
>> +{
>> + int rc = 0;
>> + struct ipe_policy *old, *ap, *new = NULL;
>> +
>> + old = (struct ipe_policy *)root->i_private;
>> + if (!old)
>> + return ERR_PTR(-ENOENT);
>> +
>> + new = ipe_new_policy(text, textlen, pkcs7, pkcs7len);
>> + if (IS_ERR(new))
>> + return new;
>> +
>> + if (strcmp(new->parsed->name, old->parsed->name)) {
>> + rc = -EINVAL;
>> + goto err;
>> + }
>> +
>> + if (ver_to_u64(old) > ver_to_u64(new)) {
>> + rc = -EINVAL;
>> + goto err;
>> + }
>> +
>> + root->i_private = new;
>> + swap(new->policyfs, old->policyfs);
>
> Should the swap() take place with @ipe_policy_lock held?
>
I think we are safe here because root->i_rwsem is held. Other two
operations set_active and delete are also depending on the inode lock.
>> + mutex_lock(&ipe_policy_lock);
>> + ap = rcu_dereference_protected(ipe_active_policy,
>> + lockdep_is_held(&ipe_policy_lock));
>> + if (old == ap) {
>> + rcu_assign_pointer(ipe_active_policy, new);
>> + mutex_unlock(&ipe_policy_lock);
>> + synchronize_rcu();
>
> I'm guessing you are forcing a synchronize_rcu() here because you are
> free()'ing @old in the caller, yes? Looking at the code, I only see
> one caller, update_policy(). With only one caller, why not free @old
> directly in ipe_update_policy()? Do you see others callers that would
> do something different?
>
The call of synchronize_rcu() is because we are updating the current
active policy so we need to set the new policy as active.
I do agree we can free the old inside this function.
>> + } else {
>> + mutex_unlock(&ipe_policy_lock);
>> + }
>> +
>> + return old;
>> +err:
>> + ipe_free_policy(new);
>> + return ERR_PTR(rc);
>> +}
>> +
>> /**
>> * ipe_new_policy - Allocate and parse an ipe_policy structure.
>> *
>> @@ -99,3 +189,36 @@ struct ipe_policy *ipe_new_policy(const char *text, size_t textlen,
>> ipe_free_policy(new);
>> return ERR_PTR(rc);
>> }
>> +
>> +/**
>> + * ipe_set_active_pol - Make @p the active policy.
>> + * @p: Supplies a pointer to the policy to make active.
>> + *
>> + * Context: Requires root->i_rwsem, which i_private has the policy, to be held.
>> + * Return:
>> + * * !IS_ERR - Success
>> + * * -EINVAL - New active policy version is invalid
>> + */
>> +int ipe_set_active_pol(const struct ipe_policy *p)
>> +{
>> + struct ipe_policy *ap = NULL;
>> +
>> + mutex_lock(&ipe_policy_lock);
>> +
>> + ap = rcu_dereference_protected(ipe_active_policy,
>> + lockdep_is_held(&ipe_policy_lock));
>> + if (ap == p) {
>> + mutex_unlock(&ipe_policy_lock);
>> + return 0;
>> + }
>> + if (ap && ver_to_u64(ap) > ver_to_u64(p)) {
>> + mutex_unlock(&ipe_policy_lock);
>> + return -EINVAL;
>> + }
>> +
>> + rcu_assign_pointer(ipe_active_policy, p);
>> + mutex_unlock(&ipe_policy_lock);
>> + synchronize_rcu();
>
> Why do you need the synchronize_rcu() call here?
>
>> + return 0;
>> +}
>
>
> --
> paul-moore.com
next prev parent reply other threads:[~2024-02-05 23:01 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 [this message]
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 ` [PATCH RFC v12 9/20] " Paul Moore
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=6e7c707c-28cd-42ec-a617-6f8d2ce9da4f@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@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=paul@paul-moore.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 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.