105a35163SDeven Bowers // SPDX-License-Identifier: GPL-2.0 205a35163SDeven Bowers /* 305a35163SDeven Bowers * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved. 405a35163SDeven Bowers */ 505a35163SDeven Bowers 605a35163SDeven Bowers #include <linux/fs.h> 705a35163SDeven Bowers #include <linux/types.h> 805a35163SDeven Bowers #include <linux/slab.h> 905a35163SDeven Bowers #include <linux/file.h> 1005a35163SDeven Bowers #include <linux/sched.h> 1105a35163SDeven Bowers #include <linux/rcupdate.h> 1205a35163SDeven Bowers 1305a35163SDeven Bowers #include "ipe.h" 1405a35163SDeven Bowers #include "eval.h" 1505a35163SDeven Bowers #include "policy.h" 1605a35163SDeven Bowers 1705a35163SDeven Bowers struct ipe_policy __rcu *ipe_active_policy; 1805a35163SDeven Bowers 1905a35163SDeven Bowers /** 20*52443cb6SDeven Bowers * ipe_build_eval_ctx() - Build an ipe evaluation context. 21*52443cb6SDeven Bowers * @ctx: Supplies a pointer to the context to be populated. 22*52443cb6SDeven Bowers * @file: Supplies a pointer to the file to associated with the evaluation. 23*52443cb6SDeven Bowers * @op: Supplies the IPE policy operation associated with the evaluation. 24*52443cb6SDeven Bowers */ 25*52443cb6SDeven Bowers void ipe_build_eval_ctx(struct ipe_eval_ctx *ctx, 26*52443cb6SDeven Bowers const struct file *file, 27*52443cb6SDeven Bowers enum ipe_op_type op) 28*52443cb6SDeven Bowers { 29*52443cb6SDeven Bowers ctx->file = file; 30*52443cb6SDeven Bowers ctx->op = op; 31*52443cb6SDeven Bowers } 32*52443cb6SDeven Bowers 33*52443cb6SDeven Bowers /** 3405a35163SDeven Bowers * evaluate_property() - Analyze @ctx against a rule property. 3505a35163SDeven Bowers * @ctx: Supplies a pointer to the context to be evaluated. 3605a35163SDeven Bowers * @p: Supplies a pointer to the property to be evaluated. 3705a35163SDeven Bowers * 3805a35163SDeven Bowers * This is a placeholder. The actual function will be introduced in the 3905a35163SDeven Bowers * latter commits. 4005a35163SDeven Bowers * 4105a35163SDeven Bowers * Return: 4205a35163SDeven Bowers * * %true - The current @ctx match the @p 4305a35163SDeven Bowers * * %false - The current @ctx doesn't match the @p 4405a35163SDeven Bowers */ 4505a35163SDeven Bowers static bool evaluate_property(const struct ipe_eval_ctx *const ctx, 4605a35163SDeven Bowers struct ipe_prop *p) 4705a35163SDeven Bowers { 4805a35163SDeven Bowers return false; 4905a35163SDeven Bowers } 5005a35163SDeven Bowers 5105a35163SDeven Bowers /** 5205a35163SDeven Bowers * ipe_evaluate_event() - Analyze @ctx against the current active policy. 5305a35163SDeven Bowers * @ctx: Supplies a pointer to the context to be evaluated. 5405a35163SDeven Bowers * 5505a35163SDeven Bowers * This is the loop where all policy evaluations happen against the IPE policy. 5605a35163SDeven Bowers * 5705a35163SDeven Bowers * Return: 5805a35163SDeven Bowers * * %0 - Success 5905a35163SDeven Bowers * * %-EACCES - @ctx did not pass evaluation 6005a35163SDeven Bowers */ 6105a35163SDeven Bowers int ipe_evaluate_event(const struct ipe_eval_ctx *const ctx) 6205a35163SDeven Bowers { 6305a35163SDeven Bowers const struct ipe_op_table *rules = NULL; 6405a35163SDeven Bowers const struct ipe_rule *rule = NULL; 6505a35163SDeven Bowers struct ipe_policy *pol = NULL; 6605a35163SDeven Bowers struct ipe_prop *prop = NULL; 6705a35163SDeven Bowers enum ipe_action_type action; 6805a35163SDeven Bowers bool match = false; 6905a35163SDeven Bowers 7005a35163SDeven Bowers rcu_read_lock(); 7105a35163SDeven Bowers 7205a35163SDeven Bowers pol = rcu_dereference(ipe_active_policy); 7305a35163SDeven Bowers if (!pol) { 7405a35163SDeven Bowers rcu_read_unlock(); 7505a35163SDeven Bowers return 0; 7605a35163SDeven Bowers } 7705a35163SDeven Bowers 7805a35163SDeven Bowers if (ctx->op == IPE_OP_INVALID) { 7905a35163SDeven Bowers if (pol->parsed->global_default_action == IPE_ACTION_DENY) { 8005a35163SDeven Bowers rcu_read_unlock(); 8105a35163SDeven Bowers return -EACCES; 8205a35163SDeven Bowers } 8305a35163SDeven Bowers if (pol->parsed->global_default_action == IPE_ACTION_INVALID) 8405a35163SDeven Bowers WARN(1, "no default rule set for unknown op, ALLOW it"); 8505a35163SDeven Bowers rcu_read_unlock(); 8605a35163SDeven Bowers return 0; 8705a35163SDeven Bowers } 8805a35163SDeven Bowers 8905a35163SDeven Bowers rules = &pol->parsed->rules[ctx->op]; 9005a35163SDeven Bowers 9105a35163SDeven Bowers list_for_each_entry(rule, &rules->rules, next) { 9205a35163SDeven Bowers match = true; 9305a35163SDeven Bowers 9405a35163SDeven Bowers list_for_each_entry(prop, &rule->props, next) { 9505a35163SDeven Bowers match = evaluate_property(ctx, prop); 9605a35163SDeven Bowers if (!match) 9705a35163SDeven Bowers break; 9805a35163SDeven Bowers } 9905a35163SDeven Bowers 10005a35163SDeven Bowers if (match) 10105a35163SDeven Bowers break; 10205a35163SDeven Bowers } 10305a35163SDeven Bowers 10405a35163SDeven Bowers if (match) 10505a35163SDeven Bowers action = rule->action; 10605a35163SDeven Bowers else if (rules->default_action != IPE_ACTION_INVALID) 10705a35163SDeven Bowers action = rules->default_action; 10805a35163SDeven Bowers else 10905a35163SDeven Bowers action = pol->parsed->global_default_action; 11005a35163SDeven Bowers 11105a35163SDeven Bowers rcu_read_unlock(); 11205a35163SDeven Bowers if (action == IPE_ACTION_DENY) 11305a35163SDeven Bowers return -EACCES; 11405a35163SDeven Bowers 11505a35163SDeven Bowers return 0; 11605a35163SDeven Bowers } 117