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 | |
| 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>
| -rw-r--r-- | Documentation/ABI/testing/ima_policy | 2 | ||||
| -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 | ||||
| -rw-r--r-- | security/integrity/integrity.h | 7 |
6 files changed, 56 insertions, 7 deletions
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index dcff82205477..986946613542 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy | |||
| @@ -17,7 +17,7 @@ Description: | |||
| 17 | 17 | ||
| 18 | rule format: action [condition ...] | 18 | rule format: action [condition ...] |
| 19 | 19 | ||
| 20 | action: measure | dont_measure | appraise | dont_appraise | 20 | action: measure | dont_measure | appraise | dont_appraise | audit |
| 21 | condition:= base | lsm | 21 | condition:= base | lsm |
| 22 | base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]] | 22 | base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]] |
| 23 | lsm: [[subj_user=] [subj_role=] [subj_type=] | 23 | lsm: [[subj_user=] [subj_role=] [subj_type=] |
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 | ||
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 564ba7db5f6a..403ba319a06a 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
| @@ -22,12 +22,15 @@ | |||
| 22 | #define IMA_APPRAISED 0x0008 | 22 | #define IMA_APPRAISED 0x0008 |
| 23 | /*#define IMA_COLLECT 0x0010 do not use this flag */ | 23 | /*#define IMA_COLLECT 0x0010 do not use this flag */ |
| 24 | #define IMA_COLLECTED 0x0020 | 24 | #define IMA_COLLECTED 0x0020 |
| 25 | #define IMA_AUDIT 0x0040 | ||
| 26 | #define IMA_AUDITED 0x0080 | ||
| 25 | 27 | ||
| 26 | /* iint cache flags */ | 28 | /* iint cache flags */ |
| 27 | #define IMA_DIGSIG 0x0100 | 29 | #define IMA_DIGSIG 0x0100 |
| 28 | 30 | ||
| 29 | #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE) | 31 | #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT) |
| 30 | #define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_COLLECTED) | 32 | #define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED \ |
| 33 | | IMA_COLLECTED) | ||
| 31 | 34 | ||
| 32 | enum evm_ima_xattr_type { | 35 | enum evm_ima_xattr_type { |
| 33 | IMA_XATTR_DIGEST = 0x01, | 36 | IMA_XATTR_DIGEST = 0x01, |
