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>
This commit is contained in:
Родитель
45e2472e67
Коммит
e7c568e0fd
|
@ -17,7 +17,7 @@ Description:
|
|||
|
||||
rule format: action [condition ...]
|
||||
|
||||
action: measure | dont_measure | appraise | dont_appraise
|
||||
action: measure | dont_measure | appraise | dont_appraise | audit
|
||||
condition:= base | lsm
|
||||
base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]]
|
||||
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||
|
|
|
@ -114,6 +114,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
|||
struct file *file);
|
||||
void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
|
||||
const unsigned char *filename);
|
||||
void ima_audit_measurement(struct integrity_iint_cache *iint,
|
||||
const unsigned char *filename);
|
||||
int ima_store_template(struct ima_template_entry *entry, int violation,
|
||||
struct inode *inode);
|
||||
void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
|
||||
|
|
|
@ -114,7 +114,7 @@ err_out:
|
|||
*/
|
||||
int ima_get_action(struct inode *inode, int mask, int function)
|
||||
{
|
||||
int flags = IMA_MEASURE | IMA_APPRAISE;
|
||||
int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
|
||||
|
||||
if (!ima_appraise)
|
||||
flags &= ~IMA_APPRAISE;
|
||||
|
@ -207,3 +207,33 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
|
|||
if (result < 0)
|
||||
kfree(entry);
|
||||
}
|
||||
|
||||
void ima_audit_measurement(struct integrity_iint_cache *iint,
|
||||
const unsigned char *filename)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
char hash[(IMA_DIGEST_SIZE * 2) + 1];
|
||||
int i;
|
||||
|
||||
if (iint->flags & IMA_AUDITED)
|
||||
return;
|
||||
|
||||
for (i = 0; i < IMA_DIGEST_SIZE; i++)
|
||||
hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]);
|
||||
hash[i * 2] = '\0';
|
||||
|
||||
ab = audit_log_start(current->audit_context, GFP_KERNEL,
|
||||
AUDIT_INTEGRITY_RULE);
|
||||
if (!ab)
|
||||
return;
|
||||
|
||||
audit_log_format(ab, "file=");
|
||||
audit_log_untrustedstring(ab, filename);
|
||||
audit_log_format(ab, " hash=");
|
||||
audit_log_untrustedstring(ab, hash);
|
||||
|
||||
audit_log_task_info(ab, current);
|
||||
audit_log_end(ab);
|
||||
|
||||
iint->flags |= IMA_AUDITED;
|
||||
}
|
||||
|
|
|
@ -156,8 +156,8 @@ static int process_measurement(struct file *file, const unsigned char *filename,
|
|||
if (!ima_initialized || !S_ISREG(inode->i_mode))
|
||||
return 0;
|
||||
|
||||
/* Determine if in appraise/measurement policy,
|
||||
* returns IMA_MEASURE, IMA_APPRAISE bitmask. */
|
||||
/* Determine if in appraise/audit/measurement policy,
|
||||
* returns IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT bitmask. */
|
||||
action = ima_get_action(inode, mask, function);
|
||||
if (!action)
|
||||
return 0;
|
||||
|
@ -171,7 +171,8 @@ static int process_measurement(struct file *file, const unsigned char *filename,
|
|||
goto out;
|
||||
|
||||
/* Determine if already appraised/measured based on bitmask
|
||||
* (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED) */
|
||||
* (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED,
|
||||
* IMA_AUDIT, IMA_AUDITED) */
|
||||
iint->flags |= action;
|
||||
action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
|
||||
|
||||
|
@ -202,6 +203,8 @@ static int process_measurement(struct file *file, const unsigned char *filename,
|
|||
if (action & IMA_APPRAISE)
|
||||
rc = ima_appraise_measurement(iint, file,
|
||||
!pathname ? filename : pathname);
|
||||
if (action & IMA_AUDIT)
|
||||
ima_audit_measurement(iint, !pathname ? filename : pathname);
|
||||
kfree(pathbuf);
|
||||
out:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#define DONT_MEASURE 0x0002
|
||||
#define APPRAISE 0x0004 /* same as IMA_APPRAISE */
|
||||
#define DONT_APPRAISE 0x0008
|
||||
#define AUDIT 0x0040
|
||||
|
||||
#define MAX_LSM_RULES 6
|
||||
enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
|
||||
|
@ -277,6 +278,7 @@ enum {
|
|||
Opt_err = -1,
|
||||
Opt_measure = 1, Opt_dont_measure,
|
||||
Opt_appraise, Opt_dont_appraise,
|
||||
Opt_audit,
|
||||
Opt_obj_user, Opt_obj_role, Opt_obj_type,
|
||||
Opt_subj_user, Opt_subj_role, Opt_subj_type,
|
||||
Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner
|
||||
|
@ -287,6 +289,7 @@ static match_table_t policy_tokens = {
|
|||
{Opt_dont_measure, "dont_measure"},
|
||||
{Opt_appraise, "appraise"},
|
||||
{Opt_dont_appraise, "dont_appraise"},
|
||||
{Opt_audit, "audit"},
|
||||
{Opt_obj_user, "obj_user=%s"},
|
||||
{Opt_obj_role, "obj_role=%s"},
|
||||
{Opt_obj_type, "obj_type=%s"},
|
||||
|
@ -379,6 +382,14 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
|||
|
||||
entry->action = DONT_APPRAISE;
|
||||
break;
|
||||
case Opt_audit:
|
||||
ima_log_string(ab, "action", "audit");
|
||||
|
||||
if (entry->action != UNKNOWN)
|
||||
result = -EINVAL;
|
||||
|
||||
entry->action = AUDIT;
|
||||
break;
|
||||
case Opt_func:
|
||||
ima_log_string(ab, "func", args[0].from);
|
||||
|
||||
|
|
|
@ -22,12 +22,15 @@
|
|||
#define IMA_APPRAISED 0x0008
|
||||
/*#define IMA_COLLECT 0x0010 do not use this flag */
|
||||
#define IMA_COLLECTED 0x0020
|
||||
#define IMA_AUDIT 0x0040
|
||||
#define IMA_AUDITED 0x0080
|
||||
|
||||
/* iint cache flags */
|
||||
#define IMA_DIGSIG 0x0100
|
||||
|
||||
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE)
|
||||
#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_COLLECTED)
|
||||
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT)
|
||||
#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED \
|
||||
| IMA_COLLECTED)
|
||||
|
||||
enum evm_ima_xattr_type {
|
||||
IMA_XATTR_DIGEST = 0x01,
|
||||
|
|
Загрузка…
Ссылка в новой задаче