|
From: Mimi Z. <zo...@li...> - 2010-06-07 12:43:49
|
This patch defines a new template type called ima-nglong, initially
containing uid/gid in addition to the existing hash alogithm, digest,
and filename.
Signed-off-by: Mimi Zohar <zo...@us...>
---
Documentation/kernel-parameters.txt | 2 +-
security/integrity/ima/ima.h | 12 ++++++---
security/integrity/ima/ima_api.c | 47 ++++++++++++++++++++++++++---------
security/integrity/ima/ima_fs.c | 16 +++++++++---
security/integrity/ima/ima_init.c | 2 +-
security/integrity/ima/ima_queue.c | 4 +-
6 files changed, 59 insertions(+), 24 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 987fa8e..0b72227 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -990,7 +990,7 @@ and is between 256 and 4096 characters. It is defined in the file
ima_template= [IMA]
Support additional runtime measurement formats.
- Format: { "ima" | "ima-ng" }
+ Format: { "ima" | "ima-ng" | "ima-nglong" }
default: "ima"
ima_template_hash= [IMA] Choose an IMA template data hash algorithm
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 4c7d1a4..4be13fa 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -24,7 +24,7 @@
#include <linux/tpm.h>
#include <linux/audit.h>
-enum ima_template_t { IMA_TEMPLATE, IMA_NG_TEMPLATE };
+enum ima_template_t { IMA_TEMPLATE, IMA_NG_TEMPLATE, IMA_NGLONG_TEMPLATE };
extern int ima_template;
enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
@@ -82,9 +82,13 @@ int ima_calc_template_hash(int template_len, void *template, char *digest);
int ima_calc_boot_aggregate(char *digest);
void ima_add_violation(struct inode *inode, const unsigned char *filename,
const char *op, const char *cause);
-extern void ima_ng_get_offsets(unsigned short *o_digest,
- unsigned short *o_filename);
-extern struct ima_template_entry *ima_ng_alloc_init_entry(const unsigned char
+extern void ima_ng_get_offsets(struct ima_template_entry *entry,
+ unsigned short *o_digest,
+ unsigned short *o_filename,
+ unsigned short *o_uid,
+ unsigned short *o_gid);
+extern struct ima_template_entry *ima_ng_alloc_init_entry(struct inode *inode,
+ const unsigned char
*filename,
u8 *digest);
extern struct ima_template_entry *ima_alloc_init_entry(const unsigned char
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index a3d0029..b3fd469 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -18,6 +18,7 @@
#include "ima.h"
static const char *IMA_TEMPLATE_NAME = "ima";
static const char *IMA_NG_TEMPLATE_NAME = "ima-ng";
+static const char *IMA_NGLONG_TEMPLATE_NAME = "ima-nglong";
/*
* ima_store_template - store ima template measurements
@@ -78,7 +79,7 @@ void ima_add_violation(struct inode *inode, const unsigned char *filename,
entry = ima_template == IMA_TEMPLATE ?
ima_alloc_init_entry(filename, NULL) :
- ima_ng_alloc_init_entry(filename, NULL);
+ ima_ng_alloc_init_entry(inode, filename, NULL);
if (!entry) {
result = -ENOMEM;
goto err_out;
@@ -173,37 +174,51 @@ out:
return entry;
}
-void ima_ng_get_offsets(unsigned short *o_digest, unsigned short *o_filename)
+void ima_ng_get_offsets(struct ima_template_entry *entry,
+ unsigned short *o_digest, unsigned short *o_filename,
+ unsigned short *o_uid, unsigned short *o_gid)
{
+ int filename_len = *o_filename;
+
*o_digest = strlen(ima_template_hash) + 1;
*o_filename = *o_digest + ima_template_hash_size;
+ if (filename_len > 0)
+ *o_uid = *o_filename + filename_len + 1;
+ else
+ *o_uid = *o_filename + strlen((char *)entry + *o_filename) + 1;
+ *o_gid = *o_uid + sizeof(uid_t);
}
/* ima_ng_alloc_init_entry - allocate and initialize the new entry
*
- * The ima-ng template is variable length. Calculate the ima_ng
- * template size, allocate contigous memory for ima_template_entry
- * + ima_ng template data, and initialize it.
+ * The ima-ng/nglong templates are variable length. Calculate the
+ * ima_ng/nglong template sizes, allocate contigous memory for
+ * ima_template_entry + ima_ng/nglong template data, and initialize it.
*
- * Format:
+ * Format: ima_ng template
* char algname[] - null terminated hash algorithm name
* u8 digest[] - digest size based on algorithm
* char file_name[] - null terminated file name
+ * additional: ima_nglong template
+ * uid_t - file's uid
+ * gid_t - file's gid
*/
-struct ima_template_entry *ima_ng_alloc_init_entry(const unsigned char
+struct ima_template_entry *ima_ng_alloc_init_entry(struct inode *inode,
+ const unsigned char
*filename, u8 *digest)
{
struct ima_template_entry *entry;
- unsigned short o_digest, o_filename;
+ unsigned short o_digest, o_filename, o_uid, o_gid;
unsigned short template_data_size;
- ima_ng_get_offsets(&o_digest, &o_filename);
- template_data_size = o_filename + strlen(filename) + 1;
+ o_filename = strlen(filename);
+ ima_ng_get_offsets(NULL, &o_digest, &o_filename, &o_uid, &o_gid);
+ template_data_size = ima_template == IMA_NG_TEMPLATE ?
+ o_filename + strlen(filename) + 1 : o_gid + sizeof(gid_t);
entry = kzalloc(sizeof(*entry) + template_data_size, GFP_KERNEL);
if (!entry)
goto out;
- entry->template_name = IMA_NG_TEMPLATE_NAME;
entry->template_len = template_data_size;
strcpy(entry->template, ima_template_hash);
@@ -211,6 +226,14 @@ struct ima_template_entry *ima_ng_alloc_init_entry(const unsigned char
memcpy(entry->template + o_digest, digest,
ima_template_hash_size);
strcpy(entry->template + o_filename, filename);
+ if (ima_template == IMA_NGLONG_TEMPLATE) {
+ entry->template_name = IMA_NGLONG_TEMPLATE_NAME;
+ if (inode) {
+ *(uid_t *) (entry->template + o_uid) = inode->i_uid;
+ *(gid_t *) (entry->template + o_gid) = inode->i_gid;
+ }
+ } else
+ entry->template_name = IMA_NG_TEMPLATE_NAME;
out:
return entry;
}
@@ -242,7 +265,7 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
entry = ima_template == IMA_TEMPLATE ?
ima_alloc_init_entry(filename, iint->digest) :
- ima_ng_alloc_init_entry(filename, iint->digest);
+ ima_ng_alloc_init_entry(inode, filename, iint->digest);
if (!entry) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 85491d4..4965485 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -29,7 +29,9 @@
int ima_template = IMA_NG_TEMPLATE;
static int __init ima_template_setup(char *str)
{
- if (strncmp(str, "ima", 3) == 0) {
+ if (strncmp(str, "ima-nglong", 10) == 0)
+ ima_template = IMA_NGLONG_TEMPLATE;
+ else if (strncmp(str, "ima", 3) == 0) {
ima_template = IMA_TEMPLATE;
if (strncmp(ima_template_hash, "sha256", 6) == 0) {
ima_template_hash = "sha1";
@@ -195,7 +197,7 @@ void ima_template_show(struct seq_file *m, int e_len, void *e,
enum ima_show_type show)
{
struct ima_template_data *entry = e;
- unsigned short o_digest, o_filename;
+ unsigned short o_digest, o_filename, o_uid, o_gid;
int namelen;
switch (show) {
@@ -205,11 +207,17 @@ void ima_template_show(struct seq_file *m, int e_len, void *e,
ima_template_hash_size);
seq_printf(m, " %s\n", entry->file_name);
} else {
- ima_ng_get_offsets(&o_digest, &o_filename);
+ ima_ng_get_offsets(e, &o_digest, &o_filename,
+ &o_uid, &o_gid);
seq_printf(m, "%s ", (char *)e);
ima_print_digest(m, e + o_digest,
ima_template_hash_size);
- seq_printf(m, " %s\n", (char *)e + o_filename);
+ seq_printf(m, " %s", (char *)e + o_filename);
+ if (ima_template == IMA_NGLONG_TEMPLATE) {
+ seq_printf(m, " %u", *(uid_t *) (e + o_uid));
+ seq_printf(m, " %u", *(gid_t *) (e + o_gid));
+ }
+ seq_putc(m, '\n');
}
break;
case IMA_SHOW_BINARY:
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 9701db2..675141b 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -63,7 +63,7 @@ static void __init ima_add_boot_aggregate(void)
}
entry = ima_template == IMA_TEMPLATE ?
ima_alloc_init_entry(boot_aggregate_name, digest) :
- ima_ng_alloc_init_entry(boot_aggregate_name, digest);
+ ima_ng_alloc_init_entry(NULL, boot_aggregate_name, digest);
kfree(digest);
if (!entry)
goto err_out;
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index a8c0b12..70fa993 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -107,7 +107,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
u8 digest[IMA_DIGEST_SIZE];
const char *audit_cause = "hash_added";
int audit_info = 1;
- unsigned short o_digest, o_filename;
+ unsigned short o_digest, o_filename, o_uid, o_gid;
int result = 0;
mutex_lock(&ima_extend_list_mutex);
@@ -136,7 +136,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
}
out:
mutex_unlock(&ima_extend_list_mutex);
- ima_ng_get_offsets(&o_digest, &o_filename);
+ ima_ng_get_offsets(entry, &o_digest, &o_filename, &o_uid, &o_gid);
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
entry->template + o_filename,
op, audit_cause, result, audit_info);
--
1.6.6.1
|