linux/security/integrity/ima/ima_policy.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2008 IBM Corporation
 * Author: Mimi Zohar <[email protected]>
 *
 * ima_policy.c
 *	- initialize default measure policy rules
 */

#include <linux/init.h>
#include <linux/list.h>
#include <linux/kernel_read_file.h>
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/magic.h>
#include <linux/parser.h>
#include <linux/slab.h>
#include <linux/rculist.h>
#include <linux/seq_file.h>
#include <linux/ima.h>

#include "ima.h"

/* flags definitions */
#define IMA_FUNC
#define IMA_MASK
#define IMA_FSMAGIC
#define IMA_UID
#define IMA_FOWNER
#define IMA_FSUUID
#define IMA_INMASK
#define IMA_EUID
#define IMA_PCR
#define IMA_FSNAME
#define IMA_KEYRINGS
#define IMA_LABEL
#define IMA_VALIDATE_ALGOS
#define IMA_GID
#define IMA_EGID
#define IMA_FGROUP

#define UNKNOWN
#define MEASURE
#define DONT_MEASURE
#define APPRAISE
#define DONT_APPRAISE
#define AUDIT
#define HASH
#define DONT_HASH

#define INVALID_PCR(a)

int ima_policy_flag;
static int temp_ima_appraise;
static int build_ima_appraise __ro_after_init;

atomic_t ima_setxattr_allowed_hash_algorithms;

#define MAX_LSM_RULES
enum lsm_rule_types {};

enum policy_types {};

enum policy_rule_list {};

struct ima_rule_opt_list {};

/*
 * These comparators are needed nowhere outside of ima so just define them here.
 * This pattern should hopefully never be needed outside of ima.
 */
static inline bool vfsuid_gt_kuid(vfsuid_t vfsuid, kuid_t kuid)
{}

static inline bool vfsgid_gt_kgid(vfsgid_t vfsgid, kgid_t kgid)
{}

static inline bool vfsuid_lt_kuid(vfsuid_t vfsuid, kuid_t kuid)
{}

static inline bool vfsgid_lt_kgid(vfsgid_t vfsgid, kgid_t kgid)
{}

struct ima_rule_entry {};

/*
 * sanity check in case the kernels gains more hash algorithms that can
 * fit in an unsigned int
 */
static_assert();

/*
 * Without LSM specific knowledge, the default policy can only be
 * written in terms of .action, .func, .mask, .fsmagic, .uid, .gid,
 * .fowner, and .fgroup
 */

/*
 * The minimum rule set to allow for full TCB coverage.  Measures all files
 * opened or mmap for exec and everything read by root.  Dangerous because
 * normal users can easily run the machine out of memory simply building
 * and running executables.
 */
static struct ima_rule_entry dont_measure_rules[] __ro_after_init =;

static struct ima_rule_entry original_measurement_rules[] __ro_after_init =;

static struct ima_rule_entry default_measurement_rules[] __ro_after_init =;

static struct ima_rule_entry default_appraise_rules[] __ro_after_init =;

static struct ima_rule_entry build_appraise_rules[] __ro_after_init =;

static struct ima_rule_entry secure_boot_rules[] __ro_after_init =;

static struct ima_rule_entry critical_data_rules[] __ro_after_init =;

/* An array of architecture specific rules */
static struct ima_rule_entry *arch_policy_entry __ro_after_init;

static LIST_HEAD(ima_default_rules);
static LIST_HEAD(ima_policy_rules);
static LIST_HEAD(ima_temp_rules);
static struct list_head __rcu *ima_rules =;

static int ima_policy __initdata;

static int __init default_measure_policy_setup(char *str)
{}
__setup();

static bool ima_use_appraise_tcb __initdata;
static bool ima_use_secure_boot __initdata;
static bool ima_use_critical_data __initdata;
static bool ima_fail_unverifiable_sigs __ro_after_init;
static int __init policy_setup(char *str)
{}
__setup();

static int __init default_appraise_policy_setup(char *str)
{}
__setup();

static struct ima_rule_opt_list *ima_alloc_rule_opt_list(const substring_t *src)
{}

static void ima_free_rule_opt_list(struct ima_rule_opt_list *opt_list)
{}

static void ima_lsm_free_rule(struct ima_rule_entry *entry)
{}

static void ima_free_rule(struct ima_rule_entry *entry)
{}

static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry,
						gfp_t gfp)
{}

static int ima_lsm_update_rule(struct ima_rule_entry *entry)
{}

static bool ima_rule_contains_lsm_cond(struct ima_rule_entry *entry)
{}

/*
 * The LSM policy can be reloaded, leaving the IMA LSM based rules referring
 * to the old, stale LSM policy.  Update the IMA LSM based rules to reflect
 * the reloaded LSM policy.
 */
static void ima_lsm_update_rules(void)
{}

int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
			  void *lsm_data)
{}

/**
 * ima_match_rule_data - determine whether func_data matches the policy rule
 * @rule: a pointer to a rule
 * @func_data: data to match against the measure rule data
 * @cred: a pointer to a credentials structure for user validation
 *
 * Returns true if func_data matches one in the rule, false otherwise.
 */
static bool ima_match_rule_data(struct ima_rule_entry *rule,
				const char *func_data,
				const struct cred *cred)
{}

/**
 * ima_match_rules - determine whether an inode matches the policy rule.
 * @rule: a pointer to a rule
 * @idmap: idmap of the mount the inode was found from
 * @inode: a pointer to an inode
 * @cred: a pointer to a credentials structure for user validation
 * @secid: the secid of the task to be validated
 * @func: LIM hook identifier
 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
 * @func_data: func specific data, may be NULL
 *
 * Returns true on rule match, false on failure.
 */
static bool ima_match_rules(struct ima_rule_entry *rule,
			    struct mnt_idmap *idmap,
			    struct inode *inode, const struct cred *cred,
			    u32 secid, enum ima_hooks func, int mask,
			    const char *func_data)
{}

/*
 * In addition to knowing that we need to appraise the file in general,
 * we need to differentiate between calling hooks, for hook specific rules.
 */
static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
{}

/**
 * ima_match_policy - decision based on LSM and other conditions
 * @idmap: idmap of the mount the inode was found from
 * @inode: pointer to an inode for which the policy decision is being made
 * @cred: pointer to a credentials structure for which the policy decision is
 *        being made
 * @secid: LSM secid of the task to be validated
 * @func: IMA hook identifier
 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
 * @flags: IMA actions to consider (e.g. IMA_MEASURE | IMA_APPRAISE)
 * @pcr: set the pcr to extend
 * @template_desc: the template that should be used for this rule
 * @func_data: func specific data, may be NULL
 * @allowed_algos: allowlist of hash algorithms for the IMA xattr
 *
 * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type)
 * conditions.
 *
 * Since the IMA policy may be updated multiple times we need to lock the
 * list when walking it.  Reads are many orders of magnitude more numerous
 * than writes so ima_match_policy() is classical RCU candidate.
 */
int ima_match_policy(struct mnt_idmap *idmap, struct inode *inode,
		     const struct cred *cred, u32 secid, enum ima_hooks func,
		     int mask, int flags, int *pcr,
		     struct ima_template_desc **template_desc,
		     const char *func_data, unsigned int *allowed_algos)
{}

/**
 * ima_update_policy_flags() - Update global IMA variables
 *
 * Update ima_policy_flag and ima_setxattr_allowed_hash_algorithms
 * based on the currently loaded policy.
 *
 * With ima_policy_flag, the decision to short circuit out of a function
 * or not call the function in the first place can be made earlier.
 *
 * With ima_setxattr_allowed_hash_algorithms, the policy can restrict the
 * set of hash algorithms accepted when updating the security.ima xattr of
 * a file.
 *
 * Context: called after a policy update and at system initialization.
 */
void ima_update_policy_flags(void)
{}

static int ima_appraise_flag(enum ima_hooks func)
{}

static void add_rules(struct ima_rule_entry *entries, int count,
		      enum policy_rule_list policy_rule)
{}

static int ima_parse_rule(char *rule, struct ima_rule_entry *entry);

static int __init ima_init_arch_policy(void)
{}

/**
 * ima_init_policy - initialize the default measure rules.
 *
 * ima_rules points to either the ima_default_rules or the new ima_policy_rules.
 */
void __init ima_init_policy(void)
{}

/* Make sure we have a valid policy, at least containing some rules. */
int ima_check_policy(void)
{}

/**
 * ima_update_policy - update default_rules with new measure rules
 *
 * Called on file .release to update the default rules with a complete new
 * policy.  What we do here is to splice ima_policy_rules and ima_temp_rules so
 * they make a queue.  The policy may be updated multiple times and this is the
 * RCU updater.
 *
 * Policy rules are never deleted so ima_policy_flag gets zeroed only once when
 * we switch from the default policy to user defined.
 */
void ima_update_policy(void)
{}

/* Keep the enumeration in sync with the policy_tokens! */
enum policy_opt {};

static const match_table_t policy_tokens =;

static int ima_lsm_rule_init(struct ima_rule_entry *entry,
			     substring_t *args, int lsm_rule, int audit_type)
{}

static void ima_log_string_op(struct audit_buffer *ab, char *key, char *value,
			      enum policy_opt rule_operator)
{}
static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
{}

/*
 * Validating the appended signature included in the measurement list requires
 * the file hash calculated without the appended signature (i.e., the 'd-modsig'
 * field). Therefore, notify the user if they have the 'modsig' field but not
 * the 'd-modsig' field in the template.
 */
static void check_template_modsig(const struct ima_template_desc *template)
{}

/*
 * Warn if the template does not contain the given field.
 */
static void check_template_field(const struct ima_template_desc *template,
				 const char *field, const char *msg)
{}

static bool ima_validate_rule(struct ima_rule_entry *entry)
{}

static unsigned int ima_parse_appraise_algos(char *arg)
{}

static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
{}

/**
 * ima_parse_add_rule - add a rule to ima_policy_rules
 * @rule: ima measurement policy rule
 *
 * Avoid locking by allowing just one writer at a time in ima_write_policy()
 * Returns the length of the rule parsed, an error code on failure
 */
ssize_t ima_parse_add_rule(char *rule)
{}

/**
 * ima_delete_rules() - called to cleanup invalid in-flight policy.
 *
 * We don't need locking as we operate on the temp list, which is
 * different from the active one.  There is also only one user of
 * ima_delete_rules() at a time.
 */
void ima_delete_rules(void)
{}

#define __ima_hook_stringify(func, str)

const char *const func_tokens[] =;

#ifdef	CONFIG_IMA_READ_POLICY
enum {};

static const char *const mask_tokens[] =;

void *ima_policy_start(struct seq_file *m, loff_t *pos)
{}

void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos)
{}

void ima_policy_stop(struct seq_file *m, void *v)
{}

#define pt(token)
#define mt(token)

/*
 * policy_func_show - display the ima_hooks policy rule
 */
static void policy_func_show(struct seq_file *m, enum ima_hooks func)
{}

static void ima_show_rule_opt_list(struct seq_file *m,
				   const struct ima_rule_opt_list *opt_list)
{}

static void ima_policy_show_appraise_algos(struct seq_file *m,
					   unsigned int allowed_hashes)
{}

int ima_policy_show(struct seq_file *m, void *v)
{}
#endif	/* CONFIG_IMA_READ_POLICY */

#if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING)
/*
 * ima_appraise_signature: whether IMA will appraise a given function using
 * an IMA digital signature. This is restricted to cases where the kernel
 * has a set of built-in trusted keys in order to avoid an attacker simply
 * loading additional keys.
 */
bool ima_appraise_signature(enum kernel_read_file_id id)
{}
#endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */