aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-10-02 05:47:23 -0400
committerJames Morris <james.l.morris@oracle.com>2014-10-02 05:47:23 -0400
commitc867d07e3c861e75509650b8a359351d634db93a (patch)
treef912043f48b9232db284ff67311eae8692918729 /security
parent858f61c4298d858376ca7b9fc2e05677faabd2d5 (diff)
parent1b68bdf9cded82d37e443a20c5ed47bbb084d5dc (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima.h9
-rw-r--r--security/integrity/ima/ima_api.c5
-rw-r--r--security/integrity/ima/ima_appraise.c6
-rw-r--r--security/integrity/ima/ima_init.c25
-rw-r--r--security/integrity/ima/ima_main.c73
-rw-r--r--security/integrity/ima/ima_policy.c23
6 files changed, 94 insertions, 47 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 8e4bb883fc13..8ee997dff139 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -43,6 +43,9 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
43#define IMA_TEMPLATE_IMA_NAME "ima" 43#define IMA_TEMPLATE_IMA_NAME "ima"
44#define IMA_TEMPLATE_IMA_FMT "d|n" 44#define IMA_TEMPLATE_IMA_FMT "d|n"
45 45
46/* current content of the policy */
47extern int ima_policy_flag;
48
46/* set during initialization */ 49/* set during initialization */
47extern int ima_initialized; 50extern int ima_initialized;
48extern int ima_used_chip; 51extern int ima_used_chip;
@@ -153,14 +156,16 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
153 int flags); 156 int flags);
154void ima_init_policy(void); 157void ima_init_policy(void);
155void ima_update_policy(void); 158void ima_update_policy(void);
159void ima_update_policy_flag(void);
156ssize_t ima_parse_add_rule(char *); 160ssize_t ima_parse_add_rule(char *);
157void ima_delete_rules(void); 161void ima_delete_rules(void);
158 162
159/* Appraise integrity measurements */ 163/* Appraise integrity measurements */
160#define IMA_APPRAISE_ENFORCE 0x01 164#define IMA_APPRAISE_ENFORCE 0x01
161#define IMA_APPRAISE_FIX 0x02 165#define IMA_APPRAISE_FIX 0x02
162#define IMA_APPRAISE_MODULES 0x04 166#define IMA_APPRAISE_LOG 0x04
163#define IMA_APPRAISE_FIRMWARE 0x08 167#define IMA_APPRAISE_MODULES 0x08
168#define IMA_APPRAISE_FIRMWARE 0x10
164 169
165#ifdef CONFIG_IMA_APPRAISE 170#ifdef CONFIG_IMA_APPRAISE
166int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 171int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 65c41a968cc1..86885979918c 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -179,11 +179,6 @@ int ima_get_action(struct inode *inode, int mask, int function)
179 return ima_match_policy(inode, function, mask, flags); 179 return ima_match_policy(inode, function, mask, flags);
180} 180}
181 181
182int ima_must_measure(struct inode *inode, int mask, int function)
183{
184 return ima_match_policy(inode, function, mask, IMA_MEASURE);
185}
186
187/* 182/*
188 * ima_collect_measurement - collect file measurement 183 * ima_collect_measurement - collect file measurement
189 * 184 *
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 013ec3f0e42d..922685483bd3 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -23,6 +23,8 @@ static int __init default_appraise_setup(char *str)
23{ 23{
24 if (strncmp(str, "off", 3) == 0) 24 if (strncmp(str, "off", 3) == 0)
25 ima_appraise = 0; 25 ima_appraise = 0;
26 else if (strncmp(str, "log", 3) == 0)
27 ima_appraise = IMA_APPRAISE_LOG;
26 else if (strncmp(str, "fix", 3) == 0) 28 else if (strncmp(str, "fix", 3) == 0)
27 ima_appraise = IMA_APPRAISE_FIX; 29 ima_appraise = IMA_APPRAISE_FIX;
28 return 1; 30 return 1;
@@ -316,7 +318,7 @@ void ima_inode_post_setattr(struct dentry *dentry)
316 struct integrity_iint_cache *iint; 318 struct integrity_iint_cache *iint;
317 int must_appraise, rc; 319 int must_appraise, rc;
318 320
319 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode) 321 if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode)
320 || !inode->i_op->removexattr) 322 || !inode->i_op->removexattr)
321 return; 323 return;
322 324
@@ -354,7 +356,7 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
354{ 356{
355 struct integrity_iint_cache *iint; 357 struct integrity_iint_cache *iint;
356 358
357 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode)) 359 if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode))
358 return; 360 return;
359 361
360 iint = integrity_iint_find(inode); 362 iint = integrity_iint_find(inode);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index e8f9d70a465d..9164fc8cac84 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -43,7 +43,7 @@ int ima_used_chip;
43 * a different value.) Violations add a zero entry to the measurement 43 * a different value.) Violations add a zero entry to the measurement
44 * list and extend the aggregate PCR value with ff...ff's. 44 * list and extend the aggregate PCR value with ff...ff's.
45 */ 45 */
46static void __init ima_add_boot_aggregate(void) 46static int __init ima_add_boot_aggregate(void)
47{ 47{
48 static const char op[] = "add_boot_aggregate"; 48 static const char op[] = "add_boot_aggregate";
49 const char *audit_cause = "ENOMEM"; 49 const char *audit_cause = "ENOMEM";
@@ -72,17 +72,23 @@ static void __init ima_add_boot_aggregate(void)
72 72
73 result = ima_alloc_init_template(iint, NULL, boot_aggregate_name, 73 result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
74 NULL, 0, &entry); 74 NULL, 0, &entry);
75 if (result < 0) 75 if (result < 0) {
76 return; 76 audit_cause = "alloc_entry";
77 goto err_out;
78 }
77 79
78 result = ima_store_template(entry, violation, NULL, 80 result = ima_store_template(entry, violation, NULL,
79 boot_aggregate_name); 81 boot_aggregate_name);
80 if (result < 0) 82 if (result < 0) {
81 ima_free_template_entry(entry); 83 ima_free_template_entry(entry);
82 return; 84 audit_cause = "store_entry";
85 goto err_out;
86 }
87 return 0;
83err_out: 88err_out:
84 integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op, 89 integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
85 audit_cause, result, 0); 90 audit_cause, result, 0);
91 return result;
86} 92}
87 93
88int __init ima_init(void) 94int __init ima_init(void)
@@ -98,6 +104,10 @@ int __init ima_init(void)
98 if (!ima_used_chip) 104 if (!ima_used_chip)
99 pr_info("No TPM chip found, activating TPM-bypass!\n"); 105 pr_info("No TPM chip found, activating TPM-bypass!\n");
100 106
107 rc = ima_init_keyring(INTEGRITY_KEYRING_IMA);
108 if (rc)
109 return rc;
110
101 rc = ima_init_crypto(); 111 rc = ima_init_crypto();
102 if (rc) 112 if (rc)
103 return rc; 113 return rc;
@@ -105,7 +115,10 @@ int __init ima_init(void)
105 if (rc != 0) 115 if (rc != 0)
106 return rc; 116 return rc;
107 117
108 ima_add_boot_aggregate(); /* boot aggregate must be first entry */ 118 rc = ima_add_boot_aggregate(); /* boot aggregate must be first entry */
119 if (rc != 0)
120 return rc;
121
109 ima_init_policy(); 122 ima_init_policy();
110 123
111 return ima_fs_init(); 124 return ima_fs_init();
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 673a37e92ba3..62f59eca32d3 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -77,42 +77,39 @@ __setup("ima_hash=", hash_setup);
77 * could result in a file measurement error. 77 * could result in a file measurement error.
78 * 78 *
79 */ 79 */
80static void ima_rdwr_violation_check(struct file *file) 80static void ima_rdwr_violation_check(struct file *file,
81 struct integrity_iint_cache *iint,
82 int must_measure,
83 char **pathbuf,
84 const char **pathname)
81{ 85{
82 struct inode *inode = file_inode(file); 86 struct inode *inode = file_inode(file);
83 fmode_t mode = file->f_mode; 87 fmode_t mode = file->f_mode;
84 bool send_tomtou = false, send_writers = false; 88 bool send_tomtou = false, send_writers = false;
85 char *pathbuf = NULL;
86 const char *pathname;
87
88 if (!S_ISREG(inode->i_mode) || !ima_initialized)
89 return;
90 89
91 if (mode & FMODE_WRITE) { 90 if (mode & FMODE_WRITE) {
92 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) { 91 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) {
93 struct integrity_iint_cache *iint; 92 if (!iint)
94 iint = integrity_iint_find(inode); 93 iint = integrity_iint_find(inode);
95 /* IMA_MEASURE is set from reader side */ 94 /* IMA_MEASURE is set from reader side */
96 if (iint && (iint->flags & IMA_MEASURE)) 95 if (iint && (iint->flags & IMA_MEASURE))
97 send_tomtou = true; 96 send_tomtou = true;
98 } 97 }
99 } else { 98 } else {
100 if ((atomic_read(&inode->i_writecount) > 0) && 99 if ((atomic_read(&inode->i_writecount) > 0) && must_measure)
101 ima_must_measure(inode, MAY_READ, FILE_CHECK))
102 send_writers = true; 100 send_writers = true;
103 } 101 }
104 102
105 if (!send_tomtou && !send_writers) 103 if (!send_tomtou && !send_writers)
106 return; 104 return;
107 105
108 pathname = ima_d_path(&file->f_path, &pathbuf); 106 *pathname = ima_d_path(&file->f_path, pathbuf);
109 107
110 if (send_tomtou) 108 if (send_tomtou)
111 ima_add_violation(file, pathname, "invalid_pcr", "ToMToU"); 109 ima_add_violation(file, *pathname, "invalid_pcr", "ToMToU");
112 if (send_writers) 110 if (send_writers)
113 ima_add_violation(file, pathname, 111 ima_add_violation(file, *pathname,
114 "invalid_pcr", "open_writers"); 112 "invalid_pcr", "open_writers");
115 kfree(pathbuf);
116} 113}
117 114
118static void ima_check_last_writer(struct integrity_iint_cache *iint, 115static void ima_check_last_writer(struct integrity_iint_cache *iint,
@@ -160,15 +157,16 @@ static int process_measurement(struct file *file, int mask, int function,
160 int opened) 157 int opened)
161{ 158{
162 struct inode *inode = file_inode(file); 159 struct inode *inode = file_inode(file);
163 struct integrity_iint_cache *iint; 160 struct integrity_iint_cache *iint = NULL;
164 struct ima_template_desc *template_desc; 161 struct ima_template_desc *template_desc;
165 char *pathbuf = NULL; 162 char *pathbuf = NULL;
166 const char *pathname = NULL; 163 const char *pathname = NULL;
167 int rc = -ENOMEM, action, must_appraise; 164 int rc = -ENOMEM, action, must_appraise;
168 struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; 165 struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
169 int xattr_len = 0; 166 int xattr_len = 0;
167 bool violation_check;
170 168
171 if (!ima_initialized || !S_ISREG(inode->i_mode)) 169 if (!ima_policy_flag || !S_ISREG(inode->i_mode))
172 return 0; 170 return 0;
173 171
174 /* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action 172 /* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action
@@ -176,7 +174,9 @@ static int process_measurement(struct file *file, int mask, int function,
176 * Included is the appraise submask. 174 * Included is the appraise submask.
177 */ 175 */
178 action = ima_get_action(inode, mask, function); 176 action = ima_get_action(inode, mask, function);
179 if (!action) 177 violation_check = ((function == FILE_CHECK || function == MMAP_CHECK) &&
178 (ima_policy_flag & IMA_MEASURE));
179 if (!action && !violation_check)
180 return 0; 180 return 0;
181 181
182 must_appraise = action & IMA_APPRAISE; 182 must_appraise = action & IMA_APPRAISE;
@@ -187,9 +187,20 @@ static int process_measurement(struct file *file, int mask, int function,
187 187
188 mutex_lock(&inode->i_mutex); 188 mutex_lock(&inode->i_mutex);
189 189
190 iint = integrity_inode_get(inode); 190 if (action) {
191 if (!iint) 191 iint = integrity_inode_get(inode);
192 goto out; 192 if (!iint)
193 goto out;
194 }
195
196 if (violation_check) {
197 ima_rdwr_violation_check(file, iint, action & IMA_MEASURE,
198 &pathbuf, &pathname);
199 if (!action) {
200 rc = 0;
201 goto out_free;
202 }
203 }
193 204
194 /* Determine if already appraised/measured based on bitmask 205 /* Determine if already appraised/measured based on bitmask
195 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED, 206 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
@@ -218,7 +229,8 @@ static int process_measurement(struct file *file, int mask, int function,
218 goto out_digsig; 229 goto out_digsig;
219 } 230 }
220 231
221 pathname = ima_d_path(&file->f_path, &pathbuf); 232 if (!pathname) /* ima_rdwr_violation possibly pre-fetched */
233 pathname = ima_d_path(&file->f_path, &pathbuf);
222 234
223 if (action & IMA_MEASURE) 235 if (action & IMA_MEASURE)
224 ima_store_measurement(iint, file, pathname, 236 ima_store_measurement(iint, file, pathname,
@@ -228,13 +240,15 @@ static int process_measurement(struct file *file, int mask, int function,
228 xattr_value, xattr_len, opened); 240 xattr_value, xattr_len, opened);
229 if (action & IMA_AUDIT) 241 if (action & IMA_AUDIT)
230 ima_audit_measurement(iint, pathname); 242 ima_audit_measurement(iint, pathname);
231 kfree(pathbuf); 243
232out_digsig: 244out_digsig:
233 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG)) 245 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG))
234 rc = -EACCES; 246 rc = -EACCES;
247 kfree(xattr_value);
248out_free:
249 kfree(pathbuf);
235out: 250out:
236 mutex_unlock(&inode->i_mutex); 251 mutex_unlock(&inode->i_mutex);
237 kfree(xattr_value);
238 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) 252 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
239 return -EACCES; 253 return -EACCES;
240 return 0; 254 return 0;
@@ -288,7 +302,6 @@ int ima_bprm_check(struct linux_binprm *bprm)
288 */ 302 */
289int ima_file_check(struct file *file, int mask, int opened) 303int ima_file_check(struct file *file, int mask, int opened)
290{ 304{
291 ima_rdwr_violation_check(file);
292 return process_measurement(file, 305 return process_measurement(file,
293 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 306 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
294 FILE_CHECK, opened); 307 FILE_CHECK, opened);
@@ -334,14 +347,10 @@ static int __init init_ima(void)
334 347
335 hash_setup(CONFIG_IMA_DEFAULT_HASH); 348 hash_setup(CONFIG_IMA_DEFAULT_HASH);
336 error = ima_init(); 349 error = ima_init();
337 if (error) 350 if (!error) {
338 goto out; 351 ima_initialized = 1;
339 352 ima_update_policy_flag();
340 error = ima_init_keyring(INTEGRITY_KEYRING_IMA); 353 }
341 if (error)
342 goto out;
343 ima_initialized = 1;
344out:
345 return error; 354 return error;
346} 355}
347 356
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 07099a8bc283..cdc620b2152f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -35,6 +35,8 @@
35#define DONT_APPRAISE 0x0008 35#define DONT_APPRAISE 0x0008
36#define AUDIT 0x0040 36#define AUDIT 0x0040
37 37
38int ima_policy_flag;
39
38#define MAX_LSM_RULES 6 40#define MAX_LSM_RULES 6
39enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, 41enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
40 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE 42 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
@@ -295,6 +297,26 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
295 return action; 297 return action;
296} 298}
297 299
300/*
301 * Initialize the ima_policy_flag variable based on the currently
302 * loaded policy. Based on this flag, the decision to short circuit
303 * out of a function or not call the function in the first place
304 * can be made earlier.
305 */
306void ima_update_policy_flag(void)
307{
308 struct ima_rule_entry *entry;
309
310 ima_policy_flag = 0;
311 list_for_each_entry(entry, ima_rules, list) {
312 if (entry->action & IMA_DO_MASK)
313 ima_policy_flag |= entry->action;
314 }
315
316 if (!ima_appraise)
317 ima_policy_flag &= ~IMA_APPRAISE;
318}
319
298/** 320/**
299 * ima_init_policy - initialize the default measure rules. 321 * ima_init_policy - initialize the default measure rules.
300 * 322 *
@@ -341,6 +363,7 @@ void ima_update_policy(void)
341 363
342 if (ima_rules == &ima_default_rules) { 364 if (ima_rules == &ima_default_rules) {
343 ima_rules = &ima_policy_rules; 365 ima_rules = &ima_policy_rules;
366 ima_update_policy_flag();
344 cause = "complete"; 367 cause = "complete";
345 result = 0; 368 result = 0;
346 } 369 }