^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Integrity Measurement Architecture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005,2006,2007,2008 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Reiner Sailer <sailer@watson.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Serge Hallyn <serue@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Kylene Hall <kylene@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Mimi Zohar <zohar@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * File: ima_main.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * and ima_file_check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/binfmts.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel_read_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/ima.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "ima.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #ifdef CONFIG_IMA_APPRAISE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int ima_appraise = IMA_APPRAISE_ENFORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int ima_appraise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int ima_hash_algo = HASH_ALGO_SHA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int hash_setup_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static struct notifier_block ima_lsm_policy_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .notifier_call = ima_lsm_policy_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int __init hash_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct ima_template_desc *template_desc = ima_template_desc_current();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (hash_setup_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (strncmp(str, "sha1", 4) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ima_hash_algo = HASH_ALGO_SHA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) } else if (strncmp(str, "md5", 3) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ima_hash_algo = HASH_ALGO_MD5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) pr_err("invalid hash algorithm \"%s\" for template \"%s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) str, IMA_TEMPLATE_IMA_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) i = match_string(hash_algo_name, HASH_ALGO__LAST, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) pr_err("invalid hash algorithm \"%s\"", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ima_hash_algo = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) hash_setup_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __setup("ima_hash=", hash_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Prevent mmap'ing a file execute that is already mmap'ed write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int mmap_violation_check(enum ima_hooks func, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) char **pathbuf, const char **pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if ((func == MMAP_CHECK) && mapping_writably_mapped(file->f_mapping)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) rc = -ETXTBSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (!*pathbuf) /* ima_rdwr_violation possibly pre-fetched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *pathname = ima_d_path(&file->f_path, pathbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, *pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) "mmap_file", "mmapped_writers", rc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * ima_rdwr_violation_check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Only invalidate the PCR for measured files:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * - Opening a file for write when already open for read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * results in a time of measure, time of use (ToMToU) error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * - Opening a file for read when already open for write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * could result in a file measurement error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void ima_rdwr_violation_check(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct integrity_iint_cache *iint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int must_measure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) char **pathbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) const char **pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) fmode_t mode = file->f_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bool send_tomtou = false, send_writers = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (mode & FMODE_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (!iint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) iint = integrity_iint_find(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* IMA_MEASURE is set from reader side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (iint && test_bit(IMA_MUST_MEASURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) &iint->atomic_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) send_tomtou = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (must_measure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) set_bit(IMA_MUST_MEASURE, &iint->atomic_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (inode_is_open_for_write(inode) && must_measure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) send_writers = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (!send_tomtou && !send_writers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *pathname = ima_d_path(&file->f_path, pathbuf, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (send_tomtou)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ima_add_violation(file, *pathname, iint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) "invalid_pcr", "ToMToU");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (send_writers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ima_add_violation(file, *pathname, iint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) "invalid_pcr", "open_writers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void ima_check_last_writer(struct integrity_iint_cache *iint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) fmode_t mode = file->f_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) bool update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!(mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) mutex_lock(&iint->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (atomic_read(&inode->i_writecount) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) update = test_and_clear_bit(IMA_UPDATE_XATTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) &iint->atomic_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!IS_I_VERSION(inode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) !inode_eq_iversion(inode, iint->version) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) (iint->flags & IMA_NEW_FILE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) iint->measured_pcrs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ima_update_xattr(iint, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mutex_unlock(&iint->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * ima_file_free - called on __fput()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * @file: pointer to file structure being freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * Flag files that changed, based on i_version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) void ima_file_free(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct integrity_iint_cache *iint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!ima_policy_flag || !S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) iint = integrity_iint_find(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!iint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ima_check_last_writer(iint, inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int process_measurement(struct file *file, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 secid, char *buf, loff_t size, int mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) enum ima_hooks func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct integrity_iint_cache *iint = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct ima_template_desc *template_desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) char *pathbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) char filename[NAME_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) const char *pathname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int rc = 0, action, must_appraise = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct evm_ima_xattr_data *xattr_value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct modsig *modsig = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int xattr_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) bool violation_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) enum hash_algo hash_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!ima_policy_flag || !S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * bitmask based on the appraise/audit/measurement policy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Included is the appraise submask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) action = ima_get_action(inode, cred, secid, mask, func, &pcr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) &template_desc, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) (ima_policy_flag & IMA_MEASURE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (!action && !violation_check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) must_appraise = action & IMA_APPRAISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Is the appraise rule hook specific? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (action & IMA_FILE_APPRAISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) func = FILE_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) iint = integrity_inode_get(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!iint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!rc && violation_check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ima_rdwr_violation_check(file, iint, action & IMA_MEASURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) &pathbuf, &pathname, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mutex_lock(&iint->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (test_and_clear_bit(IMA_CHANGE_ATTR, &iint->atomic_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* reset appraisal flags if ima_inode_post_setattr was called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) IMA_ACTION_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Re-evaulate the file if either the xattr has changed or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * kernel has no way of detecting file change on the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * (Limited to privileged mounted filesystems.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (test_and_clear_bit(IMA_CHANGE_XATTR, &iint->atomic_flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ((inode->i_sb->s_iflags & SB_I_IMA_UNVERIFIABLE_SIGNATURE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) !(inode->i_sb->s_iflags & SB_I_UNTRUSTED_MOUNTER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) !(action & IMA_FAIL_UNVERIFIABLE_SIGS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) iint->flags &= ~IMA_DONE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) iint->measured_pcrs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Determine if already appraised/measured based on bitmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * IMA_AUDIT, IMA_AUDITED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) iint->flags |= action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) action &= IMA_DO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) action &= ~((iint->flags & (IMA_DONE_MASK ^ IMA_MEASURED)) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* If target pcr is already measured, unset IMA_MEASURE action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if ((action & IMA_MEASURE) && (iint->measured_pcrs & (0x1 << pcr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) action ^= IMA_MEASURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* HASH sets the digital signature and update flags, nothing else */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if ((action & IMA_HASH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) !(test_bit(IMA_DIGSIG, &iint->atomic_flags))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) xattr_len = ima_read_xattr(file_dentry(file), &xattr_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if ((xattr_value && xattr_len > 2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) (xattr_value->type == EVM_IMA_XATTR_DIGSIG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) set_bit(IMA_DIGSIG, &iint->atomic_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) iint->flags |= IMA_HASHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) action ^= IMA_HASH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) set_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Nothing to do, just return existing appraised status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (!action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (must_appraise) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rc = mmap_violation_check(func, file, &pathbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) &pathname, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) rc = ima_get_cache_status(iint, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) goto out_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if ((action & IMA_APPRAISE_SUBMASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* read 'security.ima' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) xattr_len = ima_read_xattr(file_dentry(file), &xattr_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * Read the appended modsig if allowed by the policy, and allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * an additional measurement list entry, if needed, based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * template format and whether the file was already measured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (iint->flags & IMA_MODSIG_ALLOWED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) rc = ima_read_modsig(func, buf, size, &modsig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!rc && ima_template_has_modsig(template_desc) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) iint->flags & IMA_MEASURED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) action |= IMA_MEASURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) rc = ima_collect_measurement(iint, file, buf, size, hash_algo, modsig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (rc != 0 && rc != -EBADF && rc != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) goto out_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) pathname = ima_d_path(&file->f_path, &pathbuf, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (action & IMA_MEASURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ima_store_measurement(iint, file, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) xattr_value, xattr_len, modsig, pcr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) template_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rc = ima_check_blacklist(iint, modsig, pcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (rc != -EPERM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rc = ima_appraise_measurement(func, iint, file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) pathname, xattr_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) xattr_len, modsig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) rc = mmap_violation_check(func, file, &pathbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) &pathname, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (action & IMA_AUDIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ima_audit_measurement(iint, pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if ((file->f_flags & O_DIRECT) && (iint->flags & IMA_PERMIT_DIRECTIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) out_locked:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if ((mask & MAY_WRITE) && test_bit(IMA_DIGSIG, &iint->atomic_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) !(iint->flags & IMA_NEW_FILE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) rc = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mutex_unlock(&iint->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) kfree(xattr_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ima_free_modsig(modsig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (pathbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) __putname(pathbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (must_appraise) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (rc && (ima_appraise & IMA_APPRAISE_ENFORCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (file->f_mode & FMODE_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) set_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * ima_file_mmap - based on policy, collect/store measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * @file: pointer to the file to be measured (May be NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * @prot: contains the protection that will be applied by the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * Measure files being mmapped executable based on the ima_must_measure()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * policy decision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * On success return 0. On integrity appraisal error, assuming the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int ima_file_mmap(struct file *file, unsigned long prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) u32 secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (file && (prot & PROT_EXEC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) security_task_getsecid(current, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return process_measurement(file, current_cred(), secid, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 0, MAY_EXEC, MMAP_CHECK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * ima_file_mprotect - based on policy, limit mprotect change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * @prot: contains the protection that will be applied by the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * Files can be mmap'ed read/write and later changed to execute to circumvent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * IMA's mmap appraisal policy rules. Due to locking issues (mmap semaphore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * would be taken before i_mutex), files can not be measured or appraised at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * this point. Eliminate this integrity gap by denying the mprotect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * PROT_EXECUTE change, if an mmap appraise policy rule exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * On mprotect change success, return 0. On failure, return -EACESS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct ima_template_desc *template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct file *file = vma->vm_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) char filename[NAME_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) char *pathbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) const char *pathname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) u32 secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Is mprotect making an mmap'ed file executable? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!(ima_policy_flag & IMA_APPRAISE) || !vma->vm_file ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) security_task_getsecid(current, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) inode = file_inode(vma->vm_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) action = ima_get_action(inode, current_cred(), secid, MAY_EXEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) MMAP_CHECK, &pcr, &template, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* Is the mmap'ed file in policy? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (!(action & (IMA_MEASURE | IMA_APPRAISE_SUBMASK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (action & IMA_APPRAISE_SUBMASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) result = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) file = vma->vm_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pathname = ima_d_path(&file->f_path, &pathbuf, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) "collect_data", "failed-mprotect", result, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (pathbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) __putname(pathbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * ima_bprm_check - based on policy, collect/store measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @bprm: contains the linux_binprm structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * The OS protects against an executable file, already open for write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * from being executed in deny_write_access() and an executable file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * already open for execute, from being modified in get_write_access().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * So we can be certain that what we verify and measure here is actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * what is being executed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * On success return 0. On integrity appraisal error, assuming the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int ima_bprm_check(struct linux_binprm *bprm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u32 secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) security_task_getsecid(current, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) MAY_EXEC, BPRM_CHECK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) security_cred_getsecid(bprm->cred, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return process_measurement(bprm->file, bprm->cred, secid, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) MAY_EXEC, CREDS_CHECK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * ima_path_check - based on policy, collect/store measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * @file: pointer to the file to be measured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * @mask: contains MAY_READ, MAY_WRITE, MAY_EXEC or MAY_APPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * Measure files based on the ima_must_measure() policy decision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * On success return 0. On integrity appraisal error, assuming the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int ima_file_check(struct file *file, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u32 secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) security_task_getsecid(current, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return process_measurement(file, current_cred(), secid, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) MAY_APPEND), FILE_CHECK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) EXPORT_SYMBOL_GPL(ima_file_check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * ima_file_hash - return the stored measurement if a file has been hashed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * is in the iint cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * @file: pointer to the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * @buf: buffer in which to store the hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * @buf_size: length of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * On success, return the hash algorithm (as defined in the enum hash_algo).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * If buf is not NULL, this function also outputs the hash into buf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * If the hash is larger than buf_size, then only buf_size bytes will be copied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * It generally just makes sense to pass a buffer capable of holding the largest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * possible hash: IMA_MAX_DIGEST_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * The file hash returned is based on the entire file, including the appended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * If IMA is disabled or if no measurement is available, return -EOPNOTSUPP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * If the parameters are incorrect, return -EINVAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int ima_file_hash(struct file *file, char *buf, size_t buf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct integrity_iint_cache *iint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int hash_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (!ima_policy_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) iint = integrity_iint_find(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (!iint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) mutex_lock(&iint->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * ima_file_hash can be called when ima_collect_measurement has still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * not been called, we might not always have a hash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!iint->ima_hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) mutex_unlock(&iint->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) size_t copied_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) copied_size = min_t(size_t, iint->ima_hash->length, buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) memcpy(buf, iint->ima_hash->digest, copied_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) hash_algo = iint->ima_hash->algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) mutex_unlock(&iint->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return hash_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) EXPORT_SYMBOL_GPL(ima_file_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * ima_post_create_tmpfile - mark newly created tmpfile as new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * @file : newly created tmpfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * No measuring, appraising or auditing of newly created tmpfiles is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * Skip calling process_measurement(), but indicate which newly, created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * tmpfiles are in policy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) void ima_post_create_tmpfile(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct integrity_iint_cache *iint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int must_appraise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (!must_appraise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* Nothing to do if we can't allocate memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) iint = integrity_inode_get(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!iint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* needed for writing the security xattrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) set_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) iint->ima_file_status = INTEGRITY_PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * ima_post_path_mknod - mark as a new inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * @dentry: newly created dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * Mark files created via the mknodat syscall as new, so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * file data can be written later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) void ima_post_path_mknod(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct integrity_iint_cache *iint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct inode *inode = dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) int must_appraise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (!must_appraise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Nothing to do if we can't allocate memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) iint = integrity_inode_get(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!iint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* needed for re-opening empty files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) iint->flags |= IMA_NEW_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * ima_read_file - pre-measure/appraise hook decision based on policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * @file: pointer to the file to be measured/appraised/audit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * @read_id: caller identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * @contents: whether a subsequent call will be made to ima_post_read_file()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * Permit reading a file based on policy. The policy rules are written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * in terms of the policy identifier. Appraising the integrity of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * a file requires a file descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * For permission return 0, otherwise return -EACCES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int ima_read_file(struct file *file, enum kernel_read_file_id read_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) bool contents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) enum ima_hooks func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u32 secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * Do devices using pre-allocated memory run the risk of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * firmware being accessible to the device prior to the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * of IMA's signature verification any more than when using two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * buffers? It may be desirable to include the buffer address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * in this API and walk all the dma_map_single() mappings to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * There will be a call made to ima_post_read_file() with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * a filled buffer, so we don't need to perform an extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * read early here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (contents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* Read entire file for all partial reads. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) func = read_idmap[read_id] ?: FILE_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) security_task_getsecid(current, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return process_measurement(file, current_cred(), secid, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 0, MAY_READ, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) const int read_idmap[READING_MAX_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) [READING_FIRMWARE] = FIRMWARE_CHECK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) [READING_MODULE] = MODULE_CHECK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) [READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) [READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) [READING_POLICY] = POLICY_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * ima_post_read_file - in memory collect/appraise/audit measurement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * @file: pointer to the file to be measured/appraised/audit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * @buf: pointer to in memory file contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * @size: size of in memory file contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * @read_id: caller identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * Measure/appraise/audit in memory file based on policy. Policy rules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * are written in terms of a policy identifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * On success return 0. On integrity appraisal error, assuming the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) int ima_post_read_file(struct file *file, void *buf, loff_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) enum kernel_read_file_id read_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) enum ima_hooks func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) u32 secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* permit signed certs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (!file && read_id == READING_X509_CERTIFICATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (!file || !buf || size == 0) { /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (ima_appraise & IMA_APPRAISE_ENFORCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) func = read_idmap[read_id] ?: FILE_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) security_task_getsecid(current, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return process_measurement(file, current_cred(), secid, buf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) MAY_READ, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * ima_load_data - appraise decision based on policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * @id: kernel load data caller identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * @contents: whether the full contents will be available in a later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * call to ima_post_load_data().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * Callers of this LSM hook can not measure, appraise, or audit the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * data provided by userspace. Enforce policy rules requring a file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * signature (eg. kexec'ed kernel image).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * For permission return 0, otherwise return -EACCES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) int ima_load_data(enum kernel_load_data_id id, bool contents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) bool ima_enforce, sig_enforce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ima_enforce =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) (ima_appraise & IMA_APPRAISE_ENFORCE) == IMA_APPRAISE_ENFORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) switch (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case LOADING_KEXEC_IMAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (IS_ENABLED(CONFIG_KEXEC_SIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) && arch_ima_get_secureboot()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ima_enforce && (ima_appraise & IMA_APPRAISE_KEXEC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return -EACCES; /* INTEGRITY_UNKNOWN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case LOADING_FIRMWARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (ima_enforce && (ima_appraise & IMA_APPRAISE_FIRMWARE) && !contents) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) pr_err("Prevent firmware sysfs fallback loading.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return -EACCES; /* INTEGRITY_UNKNOWN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) case LOADING_MODULE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) sig_enforce = is_module_sig_enforced();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (ima_enforce && (!sig_enforce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) && (ima_appraise & IMA_APPRAISE_MODULES))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return -EACCES; /* INTEGRITY_UNKNOWN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * ima_post_load_data - appraise decision based on policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * @buf: pointer to in memory file contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * @size: size of in memory file contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * @id: kernel load data caller identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * @description: @id-specific description of contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * Measure/appraise/audit in memory buffer based on policy. Policy rules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * are written in terms of a policy identifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * On success return 0. On integrity appraisal error, assuming the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) int ima_post_load_data(char *buf, loff_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) enum kernel_load_data_id load_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) char *description)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (load_id == LOADING_FIRMWARE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) (ima_appraise & IMA_APPRAISE_ENFORCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) pr_err("Prevent firmware loading_store.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return -EACCES; /* INTEGRITY_UNKNOWN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * process_buffer_measurement - Measure the buffer to ima log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * @inode: inode associated with the object being measured (NULL for KEY_CHECK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * @buf: pointer to the buffer that needs to be added to the log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * @size: size of buffer(in bytes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * @eventname: event name to be used for the buffer entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * @func: IMA hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * @pcr: pcr to extend the measurement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * @keyring: keyring name to determine the action to be performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * Based on policy, the buffer is measured into the ima log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) void process_buffer_measurement(struct inode *inode, const void *buf, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) const char *eventname, enum ima_hooks func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) int pcr, const char *keyring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) const char *audit_cause = "ENOMEM";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct ima_template_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct integrity_iint_cache iint = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct ima_event_data event_data = {.iint = &iint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .filename = eventname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .buf_len = size};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct ima_template_desc *template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct ima_digest_data hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) char digest[IMA_MAX_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) } hash = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) int violation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) int action = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) u32 secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (!ima_policy_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * Both LSM hooks and auxilary based buffer measurements are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * based on policy. To avoid code duplication, differentiate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * between the LSM hooks and auxilary buffer measurements,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * retrieving the policy rule information only for the LSM hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * buffer measurements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) security_task_getsecid(current, &secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) action = ima_get_action(inode, current_cred(), secid, 0, func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) &pcr, &template, keyring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (!(action & IMA_MEASURE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (!pcr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) pcr = CONFIG_IMA_MEASURE_PCR_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (!template) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) template = lookup_template_desc("ima-buf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ret = template_desc_init_fields(template->fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) &(template->fields),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) &(template->num_fields));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) pr_err("template %s init failed, result: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) (strlen(template->name) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) template->name : template->fmt), ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) iint.ima_hash = &hash.hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) iint.ima_hash->algo = ima_hash_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) iint.ima_hash->length = hash_digest_size[ima_hash_algo];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ret = ima_calc_buffer_hash(buf, size, iint.ima_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) audit_cause = "hashing_error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) ret = ima_alloc_init_template(&event_data, &entry, template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) audit_cause = "alloc_entry";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) ret = ima_store_template(entry, violation, NULL, buf, pcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) audit_cause = "store_entry";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ima_free_template_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL, eventname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) func_measure_str(func),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) audit_cause, ret, 0, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * ima_kexec_cmdline - measure kexec cmdline boot args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * @kernel_fd: file descriptor of the kexec kernel being loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * @buf: pointer to buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * @size: size of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) * Buffers can only be measured, not appraised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) void ima_kexec_cmdline(int kernel_fd, const void *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (!buf || !size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) f = fdget(kernel_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) process_buffer_measurement(file_inode(f.file), buf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) "kexec-cmdline", KEXEC_CMDLINE, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static int __init init_ima(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ima_init_template_list();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) hash_setup(CONFIG_IMA_DEFAULT_HASH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) error = ima_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (error && strcmp(hash_algo_name[ima_hash_algo],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) CONFIG_IMA_DEFAULT_HASH) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) hash_setup_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) hash_setup(CONFIG_IMA_DEFAULT_HASH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) error = ima_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) pr_warn("Couldn't register LSM notifier, error %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ima_update_policy_flag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) late_initcall(init_ima); /* Start IMA after the TPM is available */