[PATCH RFC v10 3/17] ipe: add evaluation loop
Paul Moore
paul at paul-moore.com
Sat Jul 8 05:36:56 UTC 2023
On Jun 28, 2023 Fan Wu <wufan at linux.microsoft.com> wrote:
>
> IPE must have a centralized function to evaluate incoming callers
> against IPE's policy. This iteration of the policy for against the rules
> for that specific caller is known as the evaluation loop.
Can you rewrite that second sentence, it reads a bit awkward and I'm
unclear as to the meaning.
> Signed-off-by: Deven Bowers <deven.desai at linux.microsoft.com>
> Signed-off-by: Fan Wu <wufan at linux.microsoft.com>
> ---
> security/ipe/Makefile | 1 +
> security/ipe/eval.c | 94 +++++++++++++++++++++++++++++++++++++++++++
> security/ipe/eval.h | 25 ++++++++++++
> 3 files changed, 120 insertions(+)
> create mode 100644 security/ipe/eval.c
> create mode 100644 security/ipe/eval.h
...
> diff --git a/security/ipe/eval.c b/security/ipe/eval.c
> new file mode 100644
> index 000000000000..59144b2ecdda
> --- /dev/null
> +++ b/security/ipe/eval.c
> @@ -0,0 +1,94 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) Microsoft Corporation. All rights reserved.
> + */
> +
> +#include <linux/fs.h>
> +#include <linux/types.h>
> +#include <linux/slab.h>
> +#include <linux/file.h>
> +#include <linux/sched.h>
> +#include <linux/rcupdate.h>
> +
> +#include "ipe.h"
> +#include "eval.h"
> +#include "hooks.h"
There is no "hooks.h" at this point in the patchset.
In order for 'git bisect' to remain useful (and it can be a very handy
tool), we need to ensure that each point in the patchset compiles
cleanly.
> +#include "policy.h"
> +
> +struct ipe_policy __rcu *ipe_active_policy;
> +
> +/**
> + * evaluate_property - Analyze @ctx against a property.
> + * @ctx: Supplies a pointer to the context to be evaluated.
> + * @p: Supplies a pointer to the property to be evaluated.
> + *
> + * Return:
> + * * true - The current @ctx match the @p
> + * * false - The current @ctx doesn't match the @p
> + */
> +static bool evaluate_property(const struct ipe_eval_ctx *const ctx,
> + struct ipe_prop *p)
> +{
> + return false;
> +}
> +
> +/**
> + * ipe_evaluate_event - Analyze @ctx against the current active policy.
> + * @ctx: Supplies a pointer to the context to be evaluated.
> + *
> + * This is the loop where all policy evaluation happens against IPE policy.
> + *
> + * Return:
> + * * 0 - OK
> + * * -EACCES - @ctx did not pass evaluation.
> + * * !0 - Error
> + */
> +int ipe_evaluate_event(const struct ipe_eval_ctx *const ctx)
> +{
> + int rc = 0;
> + bool match = false;
> + enum ipe_action_type action;
> + struct ipe_policy *pol = NULL;
> + const struct ipe_rule *rule = NULL;
> + const struct ipe_op_table *rules = NULL;
> + struct ipe_prop *prop = NULL;
> +
> + rcu_read_lock();
> +
> + pol = rcu_dereference(ipe_active_policy);
> + if (!pol) {
> + rcu_read_unlock();
> + return 0;
> + }
> +
> + if (ctx->op == __IPE_OP_INVALID) {
> + action = pol->parsed->global_default_action;
> + goto eval;
It looks like you are missing a rcu_read_unlock() in this case.
Also, given how simplistic the evaluation is in this case, why not
just do it here, saving the assignment, jump, etc.?
if (ctx->op == INVALID) {
rcu_read_unlock()
if (global_action == DENY)
return -EACCES;
return 0;
}
> + }
> +
> + rules = &pol->parsed->rules[ctx->op];
> +
> + list_for_each_entry(rule, &rules->rules, next) {
> + match = true;
> +
> + list_for_each_entry(prop, &rule->props, next)
> + match = match && evaluate_property(ctx, prop);
Why not break from this loop once evaluate_property() returns false?
> +
> + if (match)
> + break;
> + }
> +
> + if (match)
> + action = rule->action;
> + else if (rules->default_action != __IPE_ACTION_INVALID)
> + action = rules->default_action;
> + else
> + action = pol->parsed->global_default_action;
> +
> + rcu_read_unlock();
> +eval:
> + if (action == __IPE_ACTION_DENY)
> + rc = -EACCES;
> +
> + return rc;
This can just be 'return 0;' right?
> +}
--
paul-moore.com
More information about the Linux-security-module-archive
mailing list