aboutsummaryrefslogtreecommitdiffstats
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
parent858f61c4298d858376ca7b9fc2e05677faabd2d5 (diff)
parent1b68bdf9cded82d37e443a20c5ed47bbb084d5dc (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next
-rw-r--r--Documentation/kernel-parameters.txt2
-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
7 files changed, 95 insertions, 48 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 0cd50491c0a4..802a3fd9e485 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1292,7 +1292,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1292 Set number of hash buckets for inode cache. 1292 Set number of hash buckets for inode cache.
1293 1293
1294 ima_appraise= [IMA] appraise integrity measurements 1294 ima_appraise= [IMA] appraise integrity measurements
1295 Format: { "off" | "enforce" | "fix" } 1295 Format: { "off" | "enforce" | "fix" | "log" }
1296 default: "enforce" 1296 default: "enforce"
1297 1297
1298 ima_appraise_tcb [IMA] 1298 ima_appraise_tcb [IMA]
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 }