Commit d9d300cdb6f233c4c591348919c758062198a4f4

Authored by Dmitry Kasatkin
Committed by Mimi Zohar
1 parent e23eb920b0

ima: rename ima_must_appraise_or_measure

When AUDIT action support is added to the IMA,
ima_must_appraise_or_measure() does not reflect the real meaning anymore.
Rename it to ima_get_action().

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Showing 3 changed files with 4 additions and 4 deletions Inline Diff

security/integrity/ima/ima.h
1 /* 1 /*
2 * Copyright (C) 2005,2006,2007,2008 IBM Corporation 2 * Copyright (C) 2005,2006,2007,2008 IBM Corporation
3 * 3 *
4 * Authors: 4 * Authors:
5 * Reiner Sailer <sailer@watson.ibm.com> 5 * Reiner Sailer <sailer@watson.ibm.com>
6 * Mimi Zohar <zohar@us.ibm.com> 6 * Mimi Zohar <zohar@us.ibm.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2 of the 10 * published by the Free Software Foundation, version 2 of the
11 * License. 11 * License.
12 * 12 *
13 * File: ima.h 13 * File: ima.h
14 * internal Integrity Measurement Architecture (IMA) definitions 14 * internal Integrity Measurement Architecture (IMA) definitions
15 */ 15 */
16 16
17 #ifndef __LINUX_IMA_H 17 #ifndef __LINUX_IMA_H
18 #define __LINUX_IMA_H 18 #define __LINUX_IMA_H
19 19
20 #include <linux/types.h> 20 #include <linux/types.h>
21 #include <linux/crypto.h> 21 #include <linux/crypto.h>
22 #include <linux/security.h> 22 #include <linux/security.h>
23 #include <linux/hash.h> 23 #include <linux/hash.h>
24 #include <linux/tpm.h> 24 #include <linux/tpm.h>
25 #include <linux/audit.h> 25 #include <linux/audit.h>
26 26
27 #include "../integrity.h" 27 #include "../integrity.h"
28 28
29 enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; 29 enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
30 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; 30 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
31 31
32 /* digest size for IMA, fits SHA1 or MD5 */ 32 /* digest size for IMA, fits SHA1 or MD5 */
33 #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE 33 #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE
34 #define IMA_EVENT_NAME_LEN_MAX 255 34 #define IMA_EVENT_NAME_LEN_MAX 255
35 35
36 #define IMA_HASH_BITS 9 36 #define IMA_HASH_BITS 9
37 #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) 37 #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
38 38
39 /* set during initialization */ 39 /* set during initialization */
40 extern int ima_initialized; 40 extern int ima_initialized;
41 extern int ima_used_chip; 41 extern int ima_used_chip;
42 extern char *ima_hash; 42 extern char *ima_hash;
43 extern int ima_appraise; 43 extern int ima_appraise;
44 44
45 /* IMA inode template definition */ 45 /* IMA inode template definition */
46 struct ima_template_data { 46 struct ima_template_data {
47 u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */ 47 u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */
48 char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */ 48 char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */
49 }; 49 };
50 50
51 struct ima_template_entry { 51 struct ima_template_entry {
52 u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ 52 u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */
53 const char *template_name; 53 const char *template_name;
54 int template_len; 54 int template_len;
55 struct ima_template_data template; 55 struct ima_template_data template;
56 }; 56 };
57 57
58 struct ima_queue_entry { 58 struct ima_queue_entry {
59 struct hlist_node hnext; /* place in hash collision list */ 59 struct hlist_node hnext; /* place in hash collision list */
60 struct list_head later; /* place in ima_measurements list */ 60 struct list_head later; /* place in ima_measurements list */
61 struct ima_template_entry *entry; 61 struct ima_template_entry *entry;
62 }; 62 };
63 extern struct list_head ima_measurements; /* list of all measurements */ 63 extern struct list_head ima_measurements; /* list of all measurements */
64 64
65 #ifdef CONFIG_IMA_AUDIT 65 #ifdef CONFIG_IMA_AUDIT
66 /* declarations */ 66 /* declarations */
67 void integrity_audit_msg(int audit_msgno, struct inode *inode, 67 void integrity_audit_msg(int audit_msgno, struct inode *inode,
68 const unsigned char *fname, const char *op, 68 const unsigned char *fname, const char *op,
69 const char *cause, int result, int info); 69 const char *cause, int result, int info);
70 #else 70 #else
71 static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, 71 static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
72 const unsigned char *fname, 72 const unsigned char *fname,
73 const char *op, const char *cause, 73 const char *op, const char *cause,
74 int result, int info) 74 int result, int info)
75 { 75 {
76 } 76 }
77 #endif 77 #endif
78 78
79 /* Internal IMA function definitions */ 79 /* Internal IMA function definitions */
80 int ima_init(void); 80 int ima_init(void);
81 void ima_cleanup(void); 81 void ima_cleanup(void);
82 int ima_fs_init(void); 82 int ima_fs_init(void);
83 void ima_fs_cleanup(void); 83 void ima_fs_cleanup(void);
84 int ima_inode_alloc(struct inode *inode); 84 int ima_inode_alloc(struct inode *inode);
85 int ima_add_template_entry(struct ima_template_entry *entry, int violation, 85 int ima_add_template_entry(struct ima_template_entry *entry, int violation,
86 const char *op, struct inode *inode); 86 const char *op, struct inode *inode);
87 int ima_calc_hash(struct file *file, char *digest); 87 int ima_calc_hash(struct file *file, char *digest);
88 int ima_calc_template_hash(int template_len, void *template, char *digest); 88 int ima_calc_template_hash(int template_len, void *template, char *digest);
89 int ima_calc_boot_aggregate(char *digest); 89 int ima_calc_boot_aggregate(char *digest);
90 void ima_add_violation(struct inode *inode, const unsigned char *filename, 90 void ima_add_violation(struct inode *inode, const unsigned char *filename,
91 const char *op, const char *cause); 91 const char *op, const char *cause);
92 92
93 /* 93 /*
94 * used to protect h_table and sha_table 94 * used to protect h_table and sha_table
95 */ 95 */
96 extern spinlock_t ima_queue_lock; 96 extern spinlock_t ima_queue_lock;
97 97
98 struct ima_h_table { 98 struct ima_h_table {
99 atomic_long_t len; /* number of stored measurements in the list */ 99 atomic_long_t len; /* number of stored measurements in the list */
100 atomic_long_t violations; 100 atomic_long_t violations;
101 struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE]; 101 struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
102 }; 102 };
103 extern struct ima_h_table ima_htable; 103 extern struct ima_h_table ima_htable;
104 104
105 static inline unsigned long ima_hash_key(u8 *digest) 105 static inline unsigned long ima_hash_key(u8 *digest)
106 { 106 {
107 return hash_long(*digest, IMA_HASH_BITS); 107 return hash_long(*digest, IMA_HASH_BITS);
108 } 108 }
109 109
110 /* LIM API function definitions */ 110 /* LIM API function definitions */
111 int ima_must_appraise_or_measure(struct inode *inode, int mask, int function); 111 int ima_get_action(struct inode *inode, int mask, int function);
112 int ima_must_measure(struct inode *inode, int mask, int function); 112 int ima_must_measure(struct inode *inode, int mask, int function);
113 int ima_collect_measurement(struct integrity_iint_cache *iint, 113 int ima_collect_measurement(struct integrity_iint_cache *iint,
114 struct file *file); 114 struct file *file);
115 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, 115 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
116 const unsigned char *filename); 116 const unsigned char *filename);
117 int ima_store_template(struct ima_template_entry *entry, int violation, 117 int ima_store_template(struct ima_template_entry *entry, int violation,
118 struct inode *inode); 118 struct inode *inode);
119 void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); 119 void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
120 120
121 /* rbtree tree calls to lookup, insert, delete 121 /* rbtree tree calls to lookup, insert, delete
122 * integrity data associated with an inode. 122 * integrity data associated with an inode.
123 */ 123 */
124 struct integrity_iint_cache *integrity_iint_insert(struct inode *inode); 124 struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
125 struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 125 struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
126 126
127 /* IMA policy related functions */ 127 /* IMA policy related functions */
128 enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR }; 128 enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR };
129 129
130 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 130 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
131 int flags); 131 int flags);
132 void ima_init_policy(void); 132 void ima_init_policy(void);
133 void ima_update_policy(void); 133 void ima_update_policy(void);
134 ssize_t ima_parse_add_rule(char *); 134 ssize_t ima_parse_add_rule(char *);
135 void ima_delete_rules(void); 135 void ima_delete_rules(void);
136 136
137 /* Appraise integrity measurements */ 137 /* Appraise integrity measurements */
138 #define IMA_APPRAISE_ENFORCE 0x01 138 #define IMA_APPRAISE_ENFORCE 0x01
139 #define IMA_APPRAISE_FIX 0x02 139 #define IMA_APPRAISE_FIX 0x02
140 140
141 #ifdef CONFIG_IMA_APPRAISE 141 #ifdef CONFIG_IMA_APPRAISE
142 int ima_appraise_measurement(struct integrity_iint_cache *iint, 142 int ima_appraise_measurement(struct integrity_iint_cache *iint,
143 struct file *file, const unsigned char *filename); 143 struct file *file, const unsigned char *filename);
144 int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask); 144 int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask);
145 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); 145 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
146 146
147 #else 147 #else
148 static inline int ima_appraise_measurement(struct integrity_iint_cache *iint, 148 static inline int ima_appraise_measurement(struct integrity_iint_cache *iint,
149 struct file *file, 149 struct file *file,
150 const unsigned char *filename) 150 const unsigned char *filename)
151 { 151 {
152 return INTEGRITY_UNKNOWN; 152 return INTEGRITY_UNKNOWN;
153 } 153 }
154 154
155 static inline int ima_must_appraise(struct inode *inode, 155 static inline int ima_must_appraise(struct inode *inode,
156 enum ima_hooks func, int mask) 156 enum ima_hooks func, int mask)
157 { 157 {
158 return 0; 158 return 0;
159 } 159 }
160 160
161 static inline void ima_update_xattr(struct integrity_iint_cache *iint, 161 static inline void ima_update_xattr(struct integrity_iint_cache *iint,
162 struct file *file) 162 struct file *file)
163 { 163 {
164 } 164 }
165 #endif 165 #endif
166 166
167 /* LSM based policy rules require audit */ 167 /* LSM based policy rules require audit */
168 #ifdef CONFIG_IMA_LSM_RULES 168 #ifdef CONFIG_IMA_LSM_RULES
169 169
170 #define security_filter_rule_init security_audit_rule_init 170 #define security_filter_rule_init security_audit_rule_init
171 #define security_filter_rule_match security_audit_rule_match 171 #define security_filter_rule_match security_audit_rule_match
172 172
173 #else 173 #else
174 174
175 static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, 175 static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr,
176 void **lsmrule) 176 void **lsmrule)
177 { 177 {
178 return -EINVAL; 178 return -EINVAL;
179 } 179 }
180 180
181 static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, 181 static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
182 void *lsmrule, 182 void *lsmrule,
183 struct audit_context *actx) 183 struct audit_context *actx)
184 { 184 {
185 return -EINVAL; 185 return -EINVAL;
186 } 186 }
187 #endif /* CONFIG_IMA_LSM_RULES */ 187 #endif /* CONFIG_IMA_LSM_RULES */
188 #endif 188 #endif
189 189
security/integrity/ima/ima_api.c
1 /* 1 /*
2 * Copyright (C) 2008 IBM Corporation 2 * Copyright (C) 2008 IBM Corporation
3 * 3 *
4 * Author: Mimi Zohar <zohar@us.ibm.com> 4 * Author: Mimi Zohar <zohar@us.ibm.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2 of the 8 * published by the Free Software Foundation, version 2 of the
9 * License. 9 * License.
10 * 10 *
11 * File: ima_api.c 11 * File: ima_api.c
12 * Implements must_appraise_or_measure, collect_measurement, 12 * Implements must_appraise_or_measure, collect_measurement,
13 * appraise_measurement, store_measurement and store_template. 13 * appraise_measurement, store_measurement and store_template.
14 */ 14 */
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/slab.h> 16 #include <linux/slab.h>
17 #include <linux/file.h> 17 #include <linux/file.h>
18 #include <linux/fs.h> 18 #include <linux/fs.h>
19 #include <linux/xattr.h> 19 #include <linux/xattr.h>
20 #include <linux/evm.h> 20 #include <linux/evm.h>
21 #include "ima.h" 21 #include "ima.h"
22 22
23 static const char *IMA_TEMPLATE_NAME = "ima"; 23 static const char *IMA_TEMPLATE_NAME = "ima";
24 24
25 /* 25 /*
26 * ima_store_template - store ima template measurements 26 * ima_store_template - store ima template measurements
27 * 27 *
28 * Calculate the hash of a template entry, add the template entry 28 * Calculate the hash of a template entry, add the template entry
29 * to an ordered list of measurement entries maintained inside the kernel, 29 * to an ordered list of measurement entries maintained inside the kernel,
30 * and also update the aggregate integrity value (maintained inside the 30 * and also update the aggregate integrity value (maintained inside the
31 * configured TPM PCR) over the hashes of the current list of measurement 31 * configured TPM PCR) over the hashes of the current list of measurement
32 * entries. 32 * entries.
33 * 33 *
34 * Applications retrieve the current kernel-held measurement list through 34 * Applications retrieve the current kernel-held measurement list through
35 * the securityfs entries in /sys/kernel/security/ima. The signed aggregate 35 * the securityfs entries in /sys/kernel/security/ima. The signed aggregate
36 * TPM PCR (called quote) can be retrieved using a TPM user space library 36 * TPM PCR (called quote) can be retrieved using a TPM user space library
37 * and is used to validate the measurement list. 37 * and is used to validate the measurement list.
38 * 38 *
39 * Returns 0 on success, error code otherwise 39 * Returns 0 on success, error code otherwise
40 */ 40 */
41 int ima_store_template(struct ima_template_entry *entry, 41 int ima_store_template(struct ima_template_entry *entry,
42 int violation, struct inode *inode) 42 int violation, struct inode *inode)
43 { 43 {
44 const char *op = "add_template_measure"; 44 const char *op = "add_template_measure";
45 const char *audit_cause = "hashing_error"; 45 const char *audit_cause = "hashing_error";
46 int result; 46 int result;
47 47
48 memset(entry->digest, 0, sizeof(entry->digest)); 48 memset(entry->digest, 0, sizeof(entry->digest));
49 entry->template_name = IMA_TEMPLATE_NAME; 49 entry->template_name = IMA_TEMPLATE_NAME;
50 entry->template_len = sizeof(entry->template); 50 entry->template_len = sizeof(entry->template);
51 51
52 if (!violation) { 52 if (!violation) {
53 result = ima_calc_template_hash(entry->template_len, 53 result = ima_calc_template_hash(entry->template_len,
54 &entry->template, 54 &entry->template,
55 entry->digest); 55 entry->digest);
56 if (result < 0) { 56 if (result < 0) {
57 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, 57 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
58 entry->template_name, op, 58 entry->template_name, op,
59 audit_cause, result, 0); 59 audit_cause, result, 0);
60 return result; 60 return result;
61 } 61 }
62 } 62 }
63 result = ima_add_template_entry(entry, violation, op, inode); 63 result = ima_add_template_entry(entry, violation, op, inode);
64 return result; 64 return result;
65 } 65 }
66 66
67 /* 67 /*
68 * ima_add_violation - add violation to measurement list. 68 * ima_add_violation - add violation to measurement list.
69 * 69 *
70 * Violations are flagged in the measurement list with zero hash values. 70 * Violations are flagged in the measurement list with zero hash values.
71 * By extending the PCR with 0xFF's instead of with zeroes, the PCR 71 * By extending the PCR with 0xFF's instead of with zeroes, the PCR
72 * value is invalidated. 72 * value is invalidated.
73 */ 73 */
74 void ima_add_violation(struct inode *inode, const unsigned char *filename, 74 void ima_add_violation(struct inode *inode, const unsigned char *filename,
75 const char *op, const char *cause) 75 const char *op, const char *cause)
76 { 76 {
77 struct ima_template_entry *entry; 77 struct ima_template_entry *entry;
78 int violation = 1; 78 int violation = 1;
79 int result; 79 int result;
80 80
81 /* can overflow, only indicator */ 81 /* can overflow, only indicator */
82 atomic_long_inc(&ima_htable.violations); 82 atomic_long_inc(&ima_htable.violations);
83 83
84 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 84 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
85 if (!entry) { 85 if (!entry) {
86 result = -ENOMEM; 86 result = -ENOMEM;
87 goto err_out; 87 goto err_out;
88 } 88 }
89 memset(&entry->template, 0, sizeof(entry->template)); 89 memset(&entry->template, 0, sizeof(entry->template));
90 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); 90 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
91 result = ima_store_template(entry, violation, inode); 91 result = ima_store_template(entry, violation, inode);
92 if (result < 0) 92 if (result < 0)
93 kfree(entry); 93 kfree(entry);
94 err_out: 94 err_out:
95 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 95 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
96 op, cause, result, 0); 96 op, cause, result, 0);
97 } 97 }
98 98
99 /** 99 /**
100 * ima_must_appraise_or_measure - appraise & measure decision based on policy. 100 * ima_get_action - appraise & measure decision based on policy.
101 * @inode: pointer to inode to measure 101 * @inode: pointer to inode to measure
102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
103 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP) 103 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
104 * 104 *
105 * The policy is defined in terms of keypairs: 105 * The policy is defined in terms of keypairs:
106 * subj=, obj=, type=, func=, mask=, fsmagic= 106 * subj=, obj=, type=, func=, mask=, fsmagic=
107 * subj,obj, and type: are LSM specific. 107 * subj,obj, and type: are LSM specific.
108 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP 108 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP
109 * mask: contains the permission mask 109 * mask: contains the permission mask
110 * fsmagic: hex value 110 * fsmagic: hex value
111 * 111 *
112 * Returns IMA_MEASURE, IMA_APPRAISE mask. 112 * Returns IMA_MEASURE, IMA_APPRAISE mask.
113 * 113 *
114 */ 114 */
115 int ima_must_appraise_or_measure(struct inode *inode, int mask, int function) 115 int ima_get_action(struct inode *inode, int mask, int function)
116 { 116 {
117 int flags = IMA_MEASURE | IMA_APPRAISE; 117 int flags = IMA_MEASURE | IMA_APPRAISE;
118 118
119 if (!ima_appraise) 119 if (!ima_appraise)
120 flags &= ~IMA_APPRAISE; 120 flags &= ~IMA_APPRAISE;
121 121
122 return ima_match_policy(inode, function, mask, flags); 122 return ima_match_policy(inode, function, mask, flags);
123 } 123 }
124 124
125 int ima_must_measure(struct inode *inode, int mask, int function) 125 int ima_must_measure(struct inode *inode, int mask, int function)
126 { 126 {
127 return ima_match_policy(inode, function, mask, IMA_MEASURE); 127 return ima_match_policy(inode, function, mask, IMA_MEASURE);
128 } 128 }
129 129
130 /* 130 /*
131 * ima_collect_measurement - collect file measurement 131 * ima_collect_measurement - collect file measurement
132 * 132 *
133 * Calculate the file hash, if it doesn't already exist, 133 * Calculate the file hash, if it doesn't already exist,
134 * storing the measurement and i_version in the iint. 134 * storing the measurement and i_version in the iint.
135 * 135 *
136 * Must be called with iint->mutex held. 136 * Must be called with iint->mutex held.
137 * 137 *
138 * Return 0 on success, error code otherwise 138 * Return 0 on success, error code otherwise
139 */ 139 */
140 int ima_collect_measurement(struct integrity_iint_cache *iint, 140 int ima_collect_measurement(struct integrity_iint_cache *iint,
141 struct file *file) 141 struct file *file)
142 { 142 {
143 struct inode *inode = file->f_dentry->d_inode; 143 struct inode *inode = file->f_dentry->d_inode;
144 const char *filename = file->f_dentry->d_name.name; 144 const char *filename = file->f_dentry->d_name.name;
145 int result = 0; 145 int result = 0;
146 146
147 if (!(iint->flags & IMA_COLLECTED)) { 147 if (!(iint->flags & IMA_COLLECTED)) {
148 u64 i_version = file->f_dentry->d_inode->i_version; 148 u64 i_version = file->f_dentry->d_inode->i_version;
149 149
150 iint->ima_xattr.type = IMA_XATTR_DIGEST; 150 iint->ima_xattr.type = IMA_XATTR_DIGEST;
151 result = ima_calc_hash(file, iint->ima_xattr.digest); 151 result = ima_calc_hash(file, iint->ima_xattr.digest);
152 if (!result) { 152 if (!result) {
153 iint->version = i_version; 153 iint->version = i_version;
154 iint->flags |= IMA_COLLECTED; 154 iint->flags |= IMA_COLLECTED;
155 } 155 }
156 } 156 }
157 if (result) 157 if (result)
158 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, 158 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
159 filename, "collect_data", "failed", 159 filename, "collect_data", "failed",
160 result, 0); 160 result, 0);
161 return result; 161 return result;
162 } 162 }
163 163
164 /* 164 /*
165 * ima_store_measurement - store file measurement 165 * ima_store_measurement - store file measurement
166 * 166 *
167 * Create an "ima" template and then store the template by calling 167 * Create an "ima" template and then store the template by calling
168 * ima_store_template. 168 * ima_store_template.
169 * 169 *
170 * We only get here if the inode has not already been measured, 170 * We only get here if the inode has not already been measured,
171 * but the measurement could already exist: 171 * but the measurement could already exist:
172 * - multiple copies of the same file on either the same or 172 * - multiple copies of the same file on either the same or
173 * different filesystems. 173 * different filesystems.
174 * - the inode was previously flushed as well as the iint info, 174 * - the inode was previously flushed as well as the iint info,
175 * containing the hashing info. 175 * containing the hashing info.
176 * 176 *
177 * Must be called with iint->mutex held. 177 * Must be called with iint->mutex held.
178 */ 178 */
179 void ima_store_measurement(struct integrity_iint_cache *iint, 179 void ima_store_measurement(struct integrity_iint_cache *iint,
180 struct file *file, const unsigned char *filename) 180 struct file *file, const unsigned char *filename)
181 { 181 {
182 const char *op = "add_template_measure"; 182 const char *op = "add_template_measure";
183 const char *audit_cause = "ENOMEM"; 183 const char *audit_cause = "ENOMEM";
184 int result = -ENOMEM; 184 int result = -ENOMEM;
185 struct inode *inode = file->f_dentry->d_inode; 185 struct inode *inode = file->f_dentry->d_inode;
186 struct ima_template_entry *entry; 186 struct ima_template_entry *entry;
187 int violation = 0; 187 int violation = 0;
188 188
189 if (iint->flags & IMA_MEASURED) 189 if (iint->flags & IMA_MEASURED)
190 return; 190 return;
191 191
192 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 192 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
193 if (!entry) { 193 if (!entry) {
194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
195 op, audit_cause, result, 0); 195 op, audit_cause, result, 0);
196 return; 196 return;
197 } 197 }
198 memset(&entry->template, 0, sizeof(entry->template)); 198 memset(&entry->template, 0, sizeof(entry->template));
199 memcpy(entry->template.digest, iint->ima_xattr.digest, IMA_DIGEST_SIZE); 199 memcpy(entry->template.digest, iint->ima_xattr.digest, IMA_DIGEST_SIZE);
200 strcpy(entry->template.file_name, 200 strcpy(entry->template.file_name,
201 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ? 201 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
202 file->f_dentry->d_name.name : filename); 202 file->f_dentry->d_name.name : filename);
203 203
204 result = ima_store_template(entry, violation, inode); 204 result = ima_store_template(entry, violation, inode);
205 if (!result || result == -EEXIST) 205 if (!result || result == -EEXIST)
206 iint->flags |= IMA_MEASURED; 206 iint->flags |= IMA_MEASURED;
207 if (result < 0) 207 if (result < 0)
208 kfree(entry); 208 kfree(entry);
209 } 209 }
210 210
security/integrity/ima/ima_main.c
1 /* 1 /*
2 * Copyright (C) 2005,2006,2007,2008 IBM Corporation 2 * Copyright (C) 2005,2006,2007,2008 IBM Corporation
3 * 3 *
4 * Authors: 4 * Authors:
5 * Reiner Sailer <sailer@watson.ibm.com> 5 * Reiner Sailer <sailer@watson.ibm.com>
6 * Serge Hallyn <serue@us.ibm.com> 6 * Serge Hallyn <serue@us.ibm.com>
7 * Kylene Hall <kylene@us.ibm.com> 7 * Kylene Hall <kylene@us.ibm.com>
8 * Mimi Zohar <zohar@us.ibm.com> 8 * Mimi Zohar <zohar@us.ibm.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as 11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation, version 2 of the 12 * published by the Free Software Foundation, version 2 of the
13 * License. 13 * License.
14 * 14 *
15 * File: ima_main.c 15 * File: ima_main.c
16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap, 16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
17 * and ima_file_check. 17 * and ima_file_check.
18 */ 18 */
19 #include <linux/module.h> 19 #include <linux/module.h>
20 #include <linux/file.h> 20 #include <linux/file.h>
21 #include <linux/binfmts.h> 21 #include <linux/binfmts.h>
22 #include <linux/mount.h> 22 #include <linux/mount.h>
23 #include <linux/mman.h> 23 #include <linux/mman.h>
24 #include <linux/slab.h> 24 #include <linux/slab.h>
25 #include <linux/xattr.h> 25 #include <linux/xattr.h>
26 #include <linux/ima.h> 26 #include <linux/ima.h>
27 27
28 #include "ima.h" 28 #include "ima.h"
29 29
30 int ima_initialized; 30 int ima_initialized;
31 31
32 #ifdef CONFIG_IMA_APPRAISE 32 #ifdef CONFIG_IMA_APPRAISE
33 int ima_appraise = IMA_APPRAISE_ENFORCE; 33 int ima_appraise = IMA_APPRAISE_ENFORCE;
34 #else 34 #else
35 int ima_appraise; 35 int ima_appraise;
36 #endif 36 #endif
37 37
38 char *ima_hash = "sha1"; 38 char *ima_hash = "sha1";
39 static int __init hash_setup(char *str) 39 static int __init hash_setup(char *str)
40 { 40 {
41 if (strncmp(str, "md5", 3) == 0) 41 if (strncmp(str, "md5", 3) == 0)
42 ima_hash = "md5"; 42 ima_hash = "md5";
43 return 1; 43 return 1;
44 } 44 }
45 __setup("ima_hash=", hash_setup); 45 __setup("ima_hash=", hash_setup);
46 46
47 /* 47 /*
48 * ima_rdwr_violation_check 48 * ima_rdwr_violation_check
49 * 49 *
50 * Only invalidate the PCR for measured files: 50 * Only invalidate the PCR for measured files:
51 * - Opening a file for write when already open for read, 51 * - Opening a file for write when already open for read,
52 * results in a time of measure, time of use (ToMToU) error. 52 * results in a time of measure, time of use (ToMToU) error.
53 * - Opening a file for read when already open for write, 53 * - Opening a file for read when already open for write,
54 * could result in a file measurement error. 54 * could result in a file measurement error.
55 * 55 *
56 */ 56 */
57 static void ima_rdwr_violation_check(struct file *file) 57 static void ima_rdwr_violation_check(struct file *file)
58 { 58 {
59 struct dentry *dentry = file->f_path.dentry; 59 struct dentry *dentry = file->f_path.dentry;
60 struct inode *inode = dentry->d_inode; 60 struct inode *inode = dentry->d_inode;
61 fmode_t mode = file->f_mode; 61 fmode_t mode = file->f_mode;
62 int must_measure; 62 int must_measure;
63 bool send_tomtou = false, send_writers = false; 63 bool send_tomtou = false, send_writers = false;
64 unsigned char *pathname = NULL, *pathbuf = NULL; 64 unsigned char *pathname = NULL, *pathbuf = NULL;
65 65
66 if (!S_ISREG(inode->i_mode) || !ima_initialized) 66 if (!S_ISREG(inode->i_mode) || !ima_initialized)
67 return; 67 return;
68 68
69 mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */ 69 mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */
70 70
71 if (mode & FMODE_WRITE) { 71 if (mode & FMODE_WRITE) {
72 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) 72 if (atomic_read(&inode->i_readcount) && IS_IMA(inode))
73 send_tomtou = true; 73 send_tomtou = true;
74 goto out; 74 goto out;
75 } 75 }
76 76
77 must_measure = ima_must_measure(inode, MAY_READ, FILE_CHECK); 77 must_measure = ima_must_measure(inode, MAY_READ, FILE_CHECK);
78 if (!must_measure) 78 if (!must_measure)
79 goto out; 79 goto out;
80 80
81 if (atomic_read(&inode->i_writecount) > 0) 81 if (atomic_read(&inode->i_writecount) > 0)
82 send_writers = true; 82 send_writers = true;
83 out: 83 out:
84 mutex_unlock(&inode->i_mutex); 84 mutex_unlock(&inode->i_mutex);
85 85
86 if (!send_tomtou && !send_writers) 86 if (!send_tomtou && !send_writers)
87 return; 87 return;
88 88
89 /* We will allow 11 spaces for ' (deleted)' to be appended */ 89 /* We will allow 11 spaces for ' (deleted)' to be appended */
90 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); 90 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
91 if (pathbuf) { 91 if (pathbuf) {
92 pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11); 92 pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11);
93 if (IS_ERR(pathname)) 93 if (IS_ERR(pathname))
94 pathname = NULL; 94 pathname = NULL;
95 else if (strlen(pathname) > IMA_EVENT_NAME_LEN_MAX) 95 else if (strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
96 pathname = NULL; 96 pathname = NULL;
97 } 97 }
98 if (send_tomtou) 98 if (send_tomtou)
99 ima_add_violation(inode, 99 ima_add_violation(inode,
100 !pathname ? dentry->d_name.name : pathname, 100 !pathname ? dentry->d_name.name : pathname,
101 "invalid_pcr", "ToMToU"); 101 "invalid_pcr", "ToMToU");
102 if (send_writers) 102 if (send_writers)
103 ima_add_violation(inode, 103 ima_add_violation(inode,
104 !pathname ? dentry->d_name.name : pathname, 104 !pathname ? dentry->d_name.name : pathname,
105 "invalid_pcr", "open_writers"); 105 "invalid_pcr", "open_writers");
106 kfree(pathbuf); 106 kfree(pathbuf);
107 } 107 }
108 108
109 static void ima_check_last_writer(struct integrity_iint_cache *iint, 109 static void ima_check_last_writer(struct integrity_iint_cache *iint,
110 struct inode *inode, struct file *file) 110 struct inode *inode, struct file *file)
111 { 111 {
112 fmode_t mode = file->f_mode; 112 fmode_t mode = file->f_mode;
113 113
114 if (!(mode & FMODE_WRITE)) 114 if (!(mode & FMODE_WRITE))
115 return; 115 return;
116 116
117 mutex_lock(&inode->i_mutex); 117 mutex_lock(&inode->i_mutex);
118 if (atomic_read(&inode->i_writecount) == 1 && 118 if (atomic_read(&inode->i_writecount) == 1 &&
119 iint->version != inode->i_version) { 119 iint->version != inode->i_version) {
120 iint->flags &= ~(IMA_COLLECTED | IMA_APPRAISED | IMA_MEASURED); 120 iint->flags &= ~(IMA_COLLECTED | IMA_APPRAISED | IMA_MEASURED);
121 if (iint->flags & IMA_APPRAISE) 121 if (iint->flags & IMA_APPRAISE)
122 ima_update_xattr(iint, file); 122 ima_update_xattr(iint, file);
123 } 123 }
124 mutex_unlock(&inode->i_mutex); 124 mutex_unlock(&inode->i_mutex);
125 } 125 }
126 126
127 /** 127 /**
128 * ima_file_free - called on __fput() 128 * ima_file_free - called on __fput()
129 * @file: pointer to file structure being freed 129 * @file: pointer to file structure being freed
130 * 130 *
131 * Flag files that changed, based on i_version 131 * Flag files that changed, based on i_version
132 */ 132 */
133 void ima_file_free(struct file *file) 133 void ima_file_free(struct file *file)
134 { 134 {
135 struct inode *inode = file->f_dentry->d_inode; 135 struct inode *inode = file->f_dentry->d_inode;
136 struct integrity_iint_cache *iint; 136 struct integrity_iint_cache *iint;
137 137
138 if (!iint_initialized || !S_ISREG(inode->i_mode)) 138 if (!iint_initialized || !S_ISREG(inode->i_mode))
139 return; 139 return;
140 140
141 iint = integrity_iint_find(inode); 141 iint = integrity_iint_find(inode);
142 if (!iint) 142 if (!iint)
143 return; 143 return;
144 144
145 ima_check_last_writer(iint, inode, file); 145 ima_check_last_writer(iint, inode, file);
146 } 146 }
147 147
148 static int process_measurement(struct file *file, const unsigned char *filename, 148 static int process_measurement(struct file *file, const unsigned char *filename,
149 int mask, int function) 149 int mask, int function)
150 { 150 {
151 struct inode *inode = file->f_dentry->d_inode; 151 struct inode *inode = file->f_dentry->d_inode;
152 struct integrity_iint_cache *iint; 152 struct integrity_iint_cache *iint;
153 unsigned char *pathname = NULL, *pathbuf = NULL; 153 unsigned char *pathname = NULL, *pathbuf = NULL;
154 int rc = -ENOMEM, action, must_appraise; 154 int rc = -ENOMEM, action, must_appraise;
155 155
156 if (!ima_initialized || !S_ISREG(inode->i_mode)) 156 if (!ima_initialized || !S_ISREG(inode->i_mode))
157 return 0; 157 return 0;
158 158
159 /* Determine if in appraise/measurement policy, 159 /* Determine if in appraise/measurement policy,
160 * returns IMA_MEASURE, IMA_APPRAISE bitmask. */ 160 * returns IMA_MEASURE, IMA_APPRAISE bitmask. */
161 action = ima_must_appraise_or_measure(inode, mask, function); 161 action = ima_get_action(inode, mask, function);
162 if (!action) 162 if (!action)
163 return 0; 163 return 0;
164 164
165 must_appraise = action & IMA_APPRAISE; 165 must_appraise = action & IMA_APPRAISE;
166 166
167 mutex_lock(&inode->i_mutex); 167 mutex_lock(&inode->i_mutex);
168 168
169 iint = integrity_inode_get(inode); 169 iint = integrity_inode_get(inode);
170 if (!iint) 170 if (!iint)
171 goto out; 171 goto out;
172 172
173 /* Determine if already appraised/measured based on bitmask 173 /* Determine if already appraised/measured based on bitmask
174 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED) */ 174 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED) */
175 iint->flags |= action; 175 iint->flags |= action;
176 action &= ~((iint->flags & (IMA_MEASURED | IMA_APPRAISED)) >> 1); 176 action &= ~((iint->flags & (IMA_MEASURED | IMA_APPRAISED)) >> 1);
177 177
178 /* Nothing to do, just return existing appraised status */ 178 /* Nothing to do, just return existing appraised status */
179 if (!action) { 179 if (!action) {
180 if (iint->flags & IMA_APPRAISED) 180 if (iint->flags & IMA_APPRAISED)
181 rc = iint->ima_status; 181 rc = iint->ima_status;
182 goto out; 182 goto out;
183 } 183 }
184 184
185 rc = ima_collect_measurement(iint, file); 185 rc = ima_collect_measurement(iint, file);
186 if (rc != 0) 186 if (rc != 0)
187 goto out; 187 goto out;
188 188
189 if (function != BPRM_CHECK) { 189 if (function != BPRM_CHECK) {
190 /* We will allow 11 spaces for ' (deleted)' to be appended */ 190 /* We will allow 11 spaces for ' (deleted)' to be appended */
191 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); 191 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
192 if (pathbuf) { 192 if (pathbuf) {
193 pathname = 193 pathname =
194 d_path(&file->f_path, pathbuf, PATH_MAX + 11); 194 d_path(&file->f_path, pathbuf, PATH_MAX + 11);
195 if (IS_ERR(pathname)) 195 if (IS_ERR(pathname))
196 pathname = NULL; 196 pathname = NULL;
197 } 197 }
198 } 198 }
199 if (action & IMA_MEASURE) 199 if (action & IMA_MEASURE)
200 ima_store_measurement(iint, file, 200 ima_store_measurement(iint, file,
201 !pathname ? filename : pathname); 201 !pathname ? filename : pathname);
202 if (action & IMA_APPRAISE) 202 if (action & IMA_APPRAISE)
203 rc = ima_appraise_measurement(iint, file, 203 rc = ima_appraise_measurement(iint, file,
204 !pathname ? filename : pathname); 204 !pathname ? filename : pathname);
205 kfree(pathbuf); 205 kfree(pathbuf);
206 out: 206 out:
207 mutex_unlock(&inode->i_mutex); 207 mutex_unlock(&inode->i_mutex);
208 return (rc && must_appraise) ? -EACCES : 0; 208 return (rc && must_appraise) ? -EACCES : 0;
209 } 209 }
210 210
211 /** 211 /**
212 * ima_file_mmap - based on policy, collect/store measurement. 212 * ima_file_mmap - based on policy, collect/store measurement.
213 * @file: pointer to the file to be measured (May be NULL) 213 * @file: pointer to the file to be measured (May be NULL)
214 * @prot: contains the protection that will be applied by the kernel. 214 * @prot: contains the protection that will be applied by the kernel.
215 * 215 *
216 * Measure files being mmapped executable based on the ima_must_measure() 216 * Measure files being mmapped executable based on the ima_must_measure()
217 * policy decision. 217 * policy decision.
218 * 218 *
219 * Return 0 on success, an error code on failure. 219 * Return 0 on success, an error code on failure.
220 * (Based on the results of appraise_measurement().) 220 * (Based on the results of appraise_measurement().)
221 */ 221 */
222 int ima_file_mmap(struct file *file, unsigned long prot) 222 int ima_file_mmap(struct file *file, unsigned long prot)
223 { 223 {
224 int rc = 0; 224 int rc = 0;
225 225
226 if (!file) 226 if (!file)
227 return 0; 227 return 0;
228 if (prot & PROT_EXEC) 228 if (prot & PROT_EXEC)
229 rc = process_measurement(file, file->f_dentry->d_name.name, 229 rc = process_measurement(file, file->f_dentry->d_name.name,
230 MAY_EXEC, FILE_MMAP); 230 MAY_EXEC, FILE_MMAP);
231 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; 231 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
232 } 232 }
233 233
234 /** 234 /**
235 * ima_bprm_check - based on policy, collect/store measurement. 235 * ima_bprm_check - based on policy, collect/store measurement.
236 * @bprm: contains the linux_binprm structure 236 * @bprm: contains the linux_binprm structure
237 * 237 *
238 * The OS protects against an executable file, already open for write, 238 * The OS protects against an executable file, already open for write,
239 * from being executed in deny_write_access() and an executable file, 239 * from being executed in deny_write_access() and an executable file,
240 * already open for execute, from being modified in get_write_access(). 240 * already open for execute, from being modified in get_write_access().
241 * So we can be certain that what we verify and measure here is actually 241 * So we can be certain that what we verify and measure here is actually
242 * what is being executed. 242 * what is being executed.
243 * 243 *
244 * Return 0 on success, an error code on failure. 244 * Return 0 on success, an error code on failure.
245 * (Based on the results of appraise_measurement().) 245 * (Based on the results of appraise_measurement().)
246 */ 246 */
247 int ima_bprm_check(struct linux_binprm *bprm) 247 int ima_bprm_check(struct linux_binprm *bprm)
248 { 248 {
249 int rc; 249 int rc;
250 250
251 rc = process_measurement(bprm->file, 251 rc = process_measurement(bprm->file,
252 (strcmp(bprm->filename, bprm->interp) == 0) ? 252 (strcmp(bprm->filename, bprm->interp) == 0) ?
253 bprm->filename : bprm->interp, 253 bprm->filename : bprm->interp,
254 MAY_EXEC, BPRM_CHECK); 254 MAY_EXEC, BPRM_CHECK);
255 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; 255 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
256 } 256 }
257 257
258 /** 258 /**
259 * ima_path_check - based on policy, collect/store measurement. 259 * ima_path_check - based on policy, collect/store measurement.
260 * @file: pointer to the file to be measured 260 * @file: pointer to the file to be measured
261 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE 261 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
262 * 262 *
263 * Measure files based on the ima_must_measure() policy decision. 263 * Measure files based on the ima_must_measure() policy decision.
264 * 264 *
265 * Always return 0 and audit dentry_open failures. 265 * Always return 0 and audit dentry_open failures.
266 * (Return code will be based upon measurement appraisal.) 266 * (Return code will be based upon measurement appraisal.)
267 */ 267 */
268 int ima_file_check(struct file *file, int mask) 268 int ima_file_check(struct file *file, int mask)
269 { 269 {
270 int rc; 270 int rc;
271 271
272 ima_rdwr_violation_check(file); 272 ima_rdwr_violation_check(file);
273 rc = process_measurement(file, file->f_dentry->d_name.name, 273 rc = process_measurement(file, file->f_dentry->d_name.name,
274 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 274 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
275 FILE_CHECK); 275 FILE_CHECK);
276 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; 276 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
277 } 277 }
278 EXPORT_SYMBOL_GPL(ima_file_check); 278 EXPORT_SYMBOL_GPL(ima_file_check);
279 279
280 static int __init init_ima(void) 280 static int __init init_ima(void)
281 { 281 {
282 int error; 282 int error;
283 283
284 error = ima_init(); 284 error = ima_init();
285 if (!error) 285 if (!error)
286 ima_initialized = 1; 286 ima_initialized = 1;
287 return error; 287 return error;
288 } 288 }
289 289
290 late_initcall(init_ima); /* Start IMA after the TPM is available */ 290 late_initcall(init_ima); /* Start IMA after the TPM is available */
291 291
292 MODULE_DESCRIPTION("Integrity Measurement Architecture"); 292 MODULE_DESCRIPTION("Integrity Measurement Architecture");
293 MODULE_LICENSE("GPL"); 293 MODULE_LICENSE("GPL");
294 294