1*3323eec9SMimi Zohar /* 2*3323eec9SMimi Zohar * Copyright (C) 2008 IBM Corporation 3*3323eec9SMimi Zohar * Author: Mimi Zohar <zohar@us.ibm.com> 4*3323eec9SMimi Zohar * 5*3323eec9SMimi Zohar * This program is free software; you can redistribute it and/or modify 6*3323eec9SMimi Zohar * it under the terms of the GNU General Public License as published by 7*3323eec9SMimi Zohar * the Free Software Foundation, version 2 of the License. 8*3323eec9SMimi Zohar * 9*3323eec9SMimi Zohar * ima_policy.c 10*3323eec9SMimi Zohar * - initialize default measure policy rules 11*3323eec9SMimi Zohar * 12*3323eec9SMimi Zohar */ 13*3323eec9SMimi Zohar #include <linux/module.h> 14*3323eec9SMimi Zohar #include <linux/list.h> 15*3323eec9SMimi Zohar #include <linux/audit.h> 16*3323eec9SMimi Zohar #include <linux/security.h> 17*3323eec9SMimi Zohar #include <linux/magic.h> 18*3323eec9SMimi Zohar 19*3323eec9SMimi Zohar #include "ima.h" 20*3323eec9SMimi Zohar 21*3323eec9SMimi Zohar /* flags definitions */ 22*3323eec9SMimi Zohar #define IMA_FUNC 0x0001 23*3323eec9SMimi Zohar #define IMA_MASK 0x0002 24*3323eec9SMimi Zohar #define IMA_FSMAGIC 0x0004 25*3323eec9SMimi Zohar #define IMA_UID 0x0008 26*3323eec9SMimi Zohar 27*3323eec9SMimi Zohar enum ima_action { DONT_MEASURE, MEASURE }; 28*3323eec9SMimi Zohar 29*3323eec9SMimi Zohar struct ima_measure_rule_entry { 30*3323eec9SMimi Zohar struct list_head list; 31*3323eec9SMimi Zohar enum ima_action action; 32*3323eec9SMimi Zohar unsigned int flags; 33*3323eec9SMimi Zohar enum ima_hooks func; 34*3323eec9SMimi Zohar int mask; 35*3323eec9SMimi Zohar unsigned long fsmagic; 36*3323eec9SMimi Zohar uid_t uid; 37*3323eec9SMimi Zohar }; 38*3323eec9SMimi Zohar 39*3323eec9SMimi Zohar static struct ima_measure_rule_entry default_rules[] = { 40*3323eec9SMimi Zohar {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC, 41*3323eec9SMimi Zohar .flags = IMA_FSMAGIC}, 42*3323eec9SMimi Zohar {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 43*3323eec9SMimi Zohar {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 44*3323eec9SMimi Zohar {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, 45*3323eec9SMimi Zohar {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC, 46*3323eec9SMimi Zohar .flags = IMA_FSMAGIC}, 47*3323eec9SMimi Zohar {.action = DONT_MEASURE,.fsmagic = 0xF97CFF8C,.flags = IMA_FSMAGIC}, 48*3323eec9SMimi Zohar {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, 49*3323eec9SMimi Zohar .flags = IMA_FUNC | IMA_MASK}, 50*3323eec9SMimi Zohar {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, 51*3323eec9SMimi Zohar .flags = IMA_FUNC | IMA_MASK}, 52*3323eec9SMimi Zohar {.action = MEASURE,.func = PATH_CHECK,.mask = MAY_READ,.uid = 0, 53*3323eec9SMimi Zohar .flags = IMA_FUNC | IMA_MASK | IMA_UID} 54*3323eec9SMimi Zohar }; 55*3323eec9SMimi Zohar 56*3323eec9SMimi Zohar static LIST_HEAD(measure_default_rules); 57*3323eec9SMimi Zohar static struct list_head *ima_measure; 58*3323eec9SMimi Zohar 59*3323eec9SMimi Zohar /** 60*3323eec9SMimi Zohar * ima_match_rules - determine whether an inode matches the measure rule. 61*3323eec9SMimi Zohar * @rule: a pointer to a rule 62*3323eec9SMimi Zohar * @inode: a pointer to an inode 63*3323eec9SMimi Zohar * @func: LIM hook identifier 64*3323eec9SMimi Zohar * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 65*3323eec9SMimi Zohar * 66*3323eec9SMimi Zohar * Returns true on rule match, false on failure. 67*3323eec9SMimi Zohar */ 68*3323eec9SMimi Zohar static bool ima_match_rules(struct ima_measure_rule_entry *rule, 69*3323eec9SMimi Zohar struct inode *inode, enum ima_hooks func, int mask) 70*3323eec9SMimi Zohar { 71*3323eec9SMimi Zohar struct task_struct *tsk = current; 72*3323eec9SMimi Zohar 73*3323eec9SMimi Zohar if ((rule->flags & IMA_FUNC) && rule->func != func) 74*3323eec9SMimi Zohar return false; 75*3323eec9SMimi Zohar if ((rule->flags & IMA_MASK) && rule->mask != mask) 76*3323eec9SMimi Zohar return false; 77*3323eec9SMimi Zohar if ((rule->flags & IMA_FSMAGIC) 78*3323eec9SMimi Zohar && rule->fsmagic != inode->i_sb->s_magic) 79*3323eec9SMimi Zohar return false; 80*3323eec9SMimi Zohar if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid) 81*3323eec9SMimi Zohar return false; 82*3323eec9SMimi Zohar return true; 83*3323eec9SMimi Zohar } 84*3323eec9SMimi Zohar 85*3323eec9SMimi Zohar /** 86*3323eec9SMimi Zohar * ima_match_policy - decision based on LSM and other conditions 87*3323eec9SMimi Zohar * @inode: pointer to an inode for which the policy decision is being made 88*3323eec9SMimi Zohar * @func: IMA hook identifier 89*3323eec9SMimi Zohar * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 90*3323eec9SMimi Zohar * 91*3323eec9SMimi Zohar * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type) 92*3323eec9SMimi Zohar * conditions. 93*3323eec9SMimi Zohar * 94*3323eec9SMimi Zohar * (There is no need for locking when walking the policy list, 95*3323eec9SMimi Zohar * as elements in the list are never deleted, nor does the list 96*3323eec9SMimi Zohar * change.) 97*3323eec9SMimi Zohar */ 98*3323eec9SMimi Zohar int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask) 99*3323eec9SMimi Zohar { 100*3323eec9SMimi Zohar struct ima_measure_rule_entry *entry; 101*3323eec9SMimi Zohar 102*3323eec9SMimi Zohar list_for_each_entry(entry, ima_measure, list) { 103*3323eec9SMimi Zohar bool rc; 104*3323eec9SMimi Zohar 105*3323eec9SMimi Zohar rc = ima_match_rules(entry, inode, func, mask); 106*3323eec9SMimi Zohar if (rc) 107*3323eec9SMimi Zohar return entry->action; 108*3323eec9SMimi Zohar } 109*3323eec9SMimi Zohar return 0; 110*3323eec9SMimi Zohar } 111*3323eec9SMimi Zohar 112*3323eec9SMimi Zohar /** 113*3323eec9SMimi Zohar * ima_init_policy - initialize the default measure rules. 114*3323eec9SMimi Zohar * 115*3323eec9SMimi Zohar * (Could use the default_rules directly, but in policy patch 116*3323eec9SMimi Zohar * ima_measure points to either the measure_default_rules or the 117*3323eec9SMimi Zohar * the new measure_policy_rules.) 118*3323eec9SMimi Zohar */ 119*3323eec9SMimi Zohar void ima_init_policy(void) 120*3323eec9SMimi Zohar { 121*3323eec9SMimi Zohar int i; 122*3323eec9SMimi Zohar 123*3323eec9SMimi Zohar for (i = 0; i < ARRAY_SIZE(default_rules); i++) 124*3323eec9SMimi Zohar list_add_tail(&default_rules[i].list, &measure_default_rules); 125*3323eec9SMimi Zohar ima_measure = &measure_default_rules; 126*3323eec9SMimi Zohar } 127