diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/integrity/ima/ima_appraise.c | 5 | ||||
| -rw-r--r-- | security/integrity/ima/ima_policy.c | 151 |
2 files changed, 116 insertions, 40 deletions
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 4865f61f9044..681cb6e72257 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
| @@ -36,7 +36,10 @@ __setup("ima_appraise=", default_appraise_setup); | |||
| 36 | */ | 36 | */ |
| 37 | int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask) | 37 | int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask) |
| 38 | { | 38 | { |
| 39 | return 0; | 39 | if (!ima_appraise) |
| 40 | return 0; | ||
| 41 | |||
| 42 | return ima_match_policy(inode, func, mask, IMA_APPRAISE); | ||
| 40 | } | 43 | } |
| 41 | 44 | ||
| 42 | static void ima_fix_xattr(struct dentry *dentry, | 45 | static void ima_fix_xattr(struct dentry *dentry, |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 3e22e17da295..0d6d60b4ba6f 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #define IMA_MASK 0x0002 | 24 | #define IMA_MASK 0x0002 |
| 25 | #define IMA_FSMAGIC 0x0004 | 25 | #define IMA_FSMAGIC 0x0004 |
| 26 | #define IMA_UID 0x0008 | 26 | #define IMA_UID 0x0008 |
| 27 | #define IMA_FOWNER 0x0010 | ||
| 27 | 28 | ||
| 28 | #define UNKNOWN 0 | 29 | #define UNKNOWN 0 |
| 29 | #define MEASURE 1 /* same as IMA_MEASURE */ | 30 | #define MEASURE 1 /* same as IMA_MEASURE */ |
| @@ -38,7 +39,7 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, | |||
| 38 | LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE | 39 | LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE |
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | struct ima_measure_rule_entry { | 42 | struct ima_rule_entry { |
| 42 | struct list_head list; | 43 | struct list_head list; |
| 43 | int action; | 44 | int action; |
| 44 | unsigned int flags; | 45 | unsigned int flags; |
| @@ -46,6 +47,7 @@ struct ima_measure_rule_entry { | |||
| 46 | int mask; | 47 | int mask; |
| 47 | unsigned long fsmagic; | 48 | unsigned long fsmagic; |
| 48 | uid_t uid; | 49 | uid_t uid; |
| 50 | uid_t fowner; | ||
| 49 | struct { | 51 | struct { |
| 50 | void *rule; /* LSM file metadata specific */ | 52 | void *rule; /* LSM file metadata specific */ |
| 51 | int type; /* audit type */ | 53 | int type; /* audit type */ |
| @@ -54,7 +56,7 @@ struct ima_measure_rule_entry { | |||
| 54 | 56 | ||
| 55 | /* | 57 | /* |
| 56 | * Without LSM specific knowledge, the default policy can only be | 58 | * Without LSM specific knowledge, the default policy can only be |
| 57 | * written in terms of .action, .func, .mask, .fsmagic, and .uid | 59 | * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner |
| 58 | */ | 60 | */ |
| 59 | 61 | ||
| 60 | /* | 62 | /* |
| @@ -63,7 +65,7 @@ struct ima_measure_rule_entry { | |||
| 63 | * normal users can easily run the machine out of memory simply building | 65 | * normal users can easily run the machine out of memory simply building |
| 64 | * and running executables. | 66 | * and running executables. |
| 65 | */ | 67 | */ |
| 66 | static struct ima_measure_rule_entry default_rules[] = { | 68 | static struct ima_rule_entry default_rules[] = { |
| 67 | {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, | 69 | {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, |
| 68 | {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, | 70 | {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, |
| 69 | {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, | 71 | {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, |
| @@ -81,19 +83,41 @@ static struct ima_measure_rule_entry default_rules[] = { | |||
| 81 | .flags = IMA_FUNC | IMA_MASK | IMA_UID}, | 83 | .flags = IMA_FUNC | IMA_MASK | IMA_UID}, |
| 82 | }; | 84 | }; |
| 83 | 85 | ||
| 84 | static LIST_HEAD(measure_default_rules); | 86 | static struct ima_rule_entry default_appraise_rules[] = { |
| 85 | static LIST_HEAD(measure_policy_rules); | 87 | {.action = DONT_APPRAISE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, |
| 86 | static struct list_head *ima_measure; | 88 | {.action = DONT_APPRAISE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, |
| 89 | {.action = DONT_APPRAISE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 90 | {.action = DONT_APPRAISE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 91 | {.action = DONT_APPRAISE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 92 | {.action = DONT_APPRAISE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 93 | {.action = DONT_APPRAISE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 94 | {.action = DONT_APPRAISE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 95 | {.action = DONT_APPRAISE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 96 | {.action = DONT_APPRAISE,.fsmagic = CGROUP_SUPER_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 97 | {.action = APPRAISE,.fowner = 0,.flags = IMA_FOWNER}, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static LIST_HEAD(ima_default_rules); | ||
| 101 | static LIST_HEAD(ima_policy_rules); | ||
| 102 | static struct list_head *ima_rules; | ||
| 87 | 103 | ||
| 88 | static DEFINE_MUTEX(ima_measure_mutex); | 104 | static DEFINE_MUTEX(ima_rules_mutex); |
| 89 | 105 | ||
| 90 | static bool ima_use_tcb __initdata; | 106 | static bool ima_use_tcb __initdata; |
| 91 | static int __init default_policy_setup(char *str) | 107 | static int __init default_measure_policy_setup(char *str) |
| 92 | { | 108 | { |
| 93 | ima_use_tcb = 1; | 109 | ima_use_tcb = 1; |
| 94 | return 1; | 110 | return 1; |
| 95 | } | 111 | } |
| 96 | __setup("ima_tcb", default_policy_setup); | 112 | __setup("ima_tcb", default_measure_policy_setup); |
| 113 | |||
| 114 | static bool ima_use_appraise_tcb __initdata; | ||
| 115 | static int __init default_appraise_policy_setup(char *str) | ||
| 116 | { | ||
| 117 | ima_use_appraise_tcb = 1; | ||
| 118 | return 1; | ||
| 119 | } | ||
| 120 | __setup("ima_appraise_tcb", default_appraise_policy_setup); | ||
| 97 | 121 | ||
| 98 | /** | 122 | /** |
| 99 | * ima_match_rules - determine whether an inode matches the measure rule. | 123 | * ima_match_rules - determine whether an inode matches the measure rule. |
| @@ -104,7 +128,7 @@ __setup("ima_tcb", default_policy_setup); | |||
| 104 | * | 128 | * |
| 105 | * Returns true on rule match, false on failure. | 129 | * Returns true on rule match, false on failure. |
| 106 | */ | 130 | */ |
| 107 | static bool ima_match_rules(struct ima_measure_rule_entry *rule, | 131 | static bool ima_match_rules(struct ima_rule_entry *rule, |
| 108 | struct inode *inode, enum ima_hooks func, int mask) | 132 | struct inode *inode, enum ima_hooks func, int mask) |
| 109 | { | 133 | { |
| 110 | struct task_struct *tsk = current; | 134 | struct task_struct *tsk = current; |
| @@ -120,6 +144,8 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule, | |||
| 120 | return false; | 144 | return false; |
| 121 | if ((rule->flags & IMA_UID) && rule->uid != cred->uid) | 145 | if ((rule->flags & IMA_UID) && rule->uid != cred->uid) |
| 122 | return false; | 146 | return false; |
| 147 | if ((rule->flags & IMA_FOWNER) && rule->fowner != inode->i_uid) | ||
| 148 | return false; | ||
| 123 | for (i = 0; i < MAX_LSM_RULES; i++) { | 149 | for (i = 0; i < MAX_LSM_RULES; i++) { |
| 124 | int rc = 0; | 150 | int rc = 0; |
| 125 | u32 osid, sid; | 151 | u32 osid, sid; |
| @@ -172,10 +198,10 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule, | |||
| 172 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, | 198 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, |
| 173 | int flags) | 199 | int flags) |
| 174 | { | 200 | { |
| 175 | struct ima_measure_rule_entry *entry; | 201 | struct ima_rule_entry *entry; |
| 176 | int action = 0, actmask = flags | (flags << 1); | 202 | int action = 0, actmask = flags | (flags << 1); |
| 177 | 203 | ||
| 178 | list_for_each_entry(entry, ima_measure, list) { | 204 | list_for_each_entry(entry, ima_rules, list) { |
| 179 | 205 | ||
| 180 | if (!(entry->action & actmask)) | 206 | if (!(entry->action & actmask)) |
| 181 | continue; | 207 | continue; |
| @@ -196,22 +222,31 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, | |||
| 196 | /** | 222 | /** |
| 197 | * ima_init_policy - initialize the default measure rules. | 223 | * ima_init_policy - initialize the default measure rules. |
| 198 | * | 224 | * |
| 199 | * ima_measure points to either the measure_default_rules or the | 225 | * ima_rules points to either the ima_default_rules or the |
| 200 | * the new measure_policy_rules. | 226 | * the new ima_policy_rules. |
| 201 | */ | 227 | */ |
| 202 | void __init ima_init_policy(void) | 228 | void __init ima_init_policy(void) |
| 203 | { | 229 | { |
| 204 | int i, entries; | 230 | int i, measure_entries, appraise_entries; |
| 205 | 231 | ||
| 206 | /* if !ima_use_tcb set entries = 0 so we load NO default rules */ | 232 | /* if !ima_use_tcb set entries = 0 so we load NO default rules */ |
| 207 | if (ima_use_tcb) | 233 | measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0; |
| 208 | entries = ARRAY_SIZE(default_rules); | 234 | appraise_entries = ima_use_appraise_tcb ? |
| 209 | else | 235 | ARRAY_SIZE(default_appraise_rules) : 0; |
| 210 | entries = 0; | ||
