diff options
author | Peter Moody <pmoody@google.com> | 2012-06-14 13:04:36 -0400 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2012-09-13 14:48:44 -0400 |
commit | e7c568e0fd0cf6d9c8ab8ea537ba8f3a3ae7c3d8 (patch) | |
tree | f920b77b98c38e28dd2974564db102160e59f3e9 /security/integrity/ima | |
parent | 45e2472e67bf66f794d507b52e82af92e0614e49 (diff) |
ima: audit log hashes
This adds an 'audit' policy action which audit logs file measurements.
Changelog v6:
- use new action flag handling (Dmitry Kasatkin).
- removed whitespace (Mimi)
Changelog v5:
- use audit_log_untrustedstring.
Changelog v4:
- cleanup digest -> hash conversion.
- use filename rather than d_path in ima_audit_measurement.
Changelog v3:
- Use newly exported audit_log_task_info for logging pid/ppid/uid/etc.
- Update the ima_policy ABI documentation.
Changelog v2:
- Use 'audit' action rather than 'measure_and_audit' to permit
auditing in the absence of measuring..
Changelog v1:
- Initial posting.
Signed-off-by: Peter Moody <pmoody@google.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/integrity/ima')
-rw-r--r-- | security/integrity/ima/ima.h | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_api.c | 32 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 9 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 11 |
4 files changed, 50 insertions, 4 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 48aa0d46d3e7..8180adde10b7 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -114,6 +114,8 @@ 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 | void ima_audit_measurement(struct integrity_iint_cache *iint, | ||
118 | const unsigned char *filename); | ||
117 | int ima_store_template(struct ima_template_entry *entry, int violation, | 119 | int ima_store_template(struct ima_template_entry *entry, int violation, |
118 | struct inode *inode); | 120 | struct inode *inode); |
119 | void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); | 121 | void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); |
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index f0d60e754b3e..b356884fb3ef 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c | |||
@@ -114,7 +114,7 @@ err_out: | |||
114 | */ | 114 | */ |
115 | int ima_get_action(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_AUDIT | IMA_APPRAISE; |
118 | 118 | ||
119 | if (!ima_appraise) | 119 | if (!ima_appraise) |
120 | flags &= ~IMA_APPRAISE; | 120 | flags &= ~IMA_APPRAISE; |
@@ -207,3 +207,33 @@ void ima_store_measurement(struct integrity_iint_cache *iint, | |||
207 | if (result < 0) | 207 | if (result < 0) |
208 | kfree(entry); | 208 | kfree(entry); |
209 | } | 209 | } |
210 | |||
211 | void ima_audit_measurement(struct integrity_iint_cache *iint, | ||
212 | const unsigned char *filename) | ||
213 | { | ||
214 | struct audit_buffer *ab; | ||
215 | char hash[(IMA_DIGEST_SIZE * 2) + 1]; | ||
216 | int i; | ||
217 | |||
218 | if (iint->flags & IMA_AUDITED) | ||
219 | return; | ||
220 | |||
221 | for (i = 0; i < IMA_DIGEST_SIZE; i++) | ||
222 | hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]); | ||
223 | hash[i * 2] = '\0'; | ||
224 | |||
225 | ab = audit_log_start(current->audit_context, GFP_KERNEL, | ||
226 | AUDIT_INTEGRITY_RULE); | ||
227 | if (!ab) | ||
228 | return; | ||
229 | |||
230 | audit_log_format(ab, "file="); | ||
231 | audit_log_untrustedstring(ab, filename); | ||
232 | audit_log_format(ab, " hash="); | ||
233 | audit_log_untrustedstring(ab, hash); | ||
234 | |||
235 | audit_log_task_info(ab, current); | ||
236 | audit_log_end(ab); | ||
237 | |||
238 | iint->flags |= IMA_AUDITED; | ||
239 | } | ||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 5da08b75d367..73c9a268253e 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -156,8 +156,8 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
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/audit/measurement policy, |
160 | * returns IMA_MEASURE, IMA_APPRAISE bitmask. */ | 160 | * returns IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT bitmask. */ |
161 | action = ima_get_action(inode, mask, function); | 161 | action = ima_get_action(inode, mask, function); |
162 | if (!action) | 162 | if (!action) |
163 | return 0; | 163 | return 0; |
@@ -171,7 +171,8 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
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 | * IMA_AUDIT, IMA_AUDITED) */ | ||
175 | iint->flags |= action; | 176 | iint->flags |= action; |
176 | action &= ~((iint->flags & IMA_DONE_MASK) >> 1); | 177 | action &= ~((iint->flags & IMA_DONE_MASK) >> 1); |
177 | 178 | ||
@@ -202,6 +203,8 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
202 | if (action & IMA_APPRAISE) | 203 | if (action & IMA_APPRAISE) |
203 | rc = ima_appraise_measurement(iint, file, | 204 | rc = ima_appraise_measurement(iint, file, |
204 | !pathname ? filename : pathname); | 205 | !pathname ? filename : pathname); |
206 | if (action & IMA_AUDIT) | ||
207 | ima_audit_measurement(iint, !pathname ? filename : pathname); | ||
205 | kfree(pathbuf); | 208 | kfree(pathbuf); |
206 | out: | 209 | out: |
207 | mutex_unlock(&inode->i_mutex); | 210 | mutex_unlock(&inode->i_mutex); |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index f46f685a1711..cda903131dbf 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #define DONT_MEASURE 0x0002 | 31 | #define DONT_MEASURE 0x0002 |
32 | #define APPRAISE 0x0004 /* same as IMA_APPRAISE */ | 32 | #define APPRAISE 0x0004 /* same as IMA_APPRAISE */ |
33 | #define DONT_APPRAISE 0x0008 | 33 | #define DONT_APPRAISE 0x0008 |
34 | #define AUDIT 0x0040 | ||
34 | 35 | ||
35 | #define MAX_LSM_RULES 6 | 36 | #define MAX_LSM_RULES 6 |
36 | enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, | 37 | enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, |
@@ -277,6 +278,7 @@ enum { | |||
277 | Opt_err = -1, | 278 | Opt_err = -1, |
278 | Opt_measure = 1, Opt_dont_measure, | 279 | Opt_measure = 1, Opt_dont_measure, |
279 | Opt_appraise, Opt_dont_appraise, | 280 | Opt_appraise, Opt_dont_appraise, |
281 | Opt_audit, | ||
280 | Opt_obj_user, Opt_obj_role, Opt_obj_type, | 282 | Opt_obj_user, Opt_obj_role, Opt_obj_type, |
281 | Opt_subj_user, Opt_subj_role, Opt_subj_type, | 283 | Opt_subj_user, Opt_subj_role, Opt_subj_type, |
282 | Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner | 284 | Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner |
@@ -287,6 +289,7 @@ static match_table_t policy_tokens = { | |||
287 | {Opt_dont_measure, "dont_measure"}, | 289 | {Opt_dont_measure, "dont_measure"}, |
288 | {Opt_appraise, "appraise"}, | 290 | {Opt_appraise, "appraise"}, |
289 | {Opt_dont_appraise, "dont_appraise"}, | 291 | {Opt_dont_appraise, "dont_appraise"}, |
292 | {Opt_audit, "audit"}, | ||
290 | {Opt_obj_user, "obj_user=%s"}, | 293 | {Opt_obj_user, "obj_user=%s"}, |
291 | {Opt_obj_role, "obj_role=%s"}, | 294 | {Opt_obj_role, "obj_role=%s"}, |
292 | {Opt_obj_type, "obj_type=%s"}, | 295 | {Opt_obj_type, "obj_type=%s"}, |
@@ -379,6 +382,14 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
379 | 382 | ||
380 | entry->action = DONT_APPRAISE; | 383 | entry->action = DONT_APPRAISE; |
381 | break; | 384 | break; |
385 | case Opt_audit: | ||
386 | ima_log_string(ab, "action", "audit"); | ||
387 | |||
388 | if (entry->action != UNKNOWN) | ||
389 | result = -EINVAL; | ||
390 | |||
391 | entry->action = AUDIT; | ||
392 | break; | ||
382 | case Opt_func: | 393 | case Opt_func: |
383 | ima_log_string(ab, "func", args[0].from); | 394 | ima_log_string(ab, "func", args[0].from); |
384 | 395 | ||