This list is closed, nobody may subscribe to it.
| 2007 |
Jan
|
Feb
(10) |
Mar
(26) |
Apr
(8) |
May
(3) |
Jun
|
Jul
(26) |
Aug
(10) |
Sep
|
Oct
|
Nov
(2) |
Dec
(4) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
|
Feb
(13) |
Mar
(4) |
Apr
(3) |
May
(5) |
Jun
|
Jul
(7) |
Aug
(8) |
Sep
(5) |
Oct
(16) |
Nov
|
Dec
(6) |
| 2009 |
Jan
(2) |
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
(19) |
Jul
(4) |
Aug
|
Sep
(13) |
Oct
(10) |
Nov
(12) |
Dec
(2) |
| 2010 |
Jan
|
Feb
(2) |
Mar
(17) |
Apr
(28) |
May
|
Jun
(17) |
Jul
(11) |
Aug
(12) |
Sep
(2) |
Oct
|
Nov
|
Dec
(1) |
| 2011 |
Jan
|
Feb
|
Mar
(20) |
Apr
(10) |
May
(1) |
Jun
|
Jul
|
Aug
(15) |
Sep
(14) |
Oct
(2) |
Nov
|
Dec
|
| 2012 |
Jan
(1) |
Feb
(53) |
Mar
(15) |
Apr
(4) |
May
(2) |
Jun
(13) |
Jul
|
Aug
|
Sep
(12) |
Oct
|
Nov
|
Dec
(6) |
| 2013 |
Jan
(7) |
Feb
(8) |
Mar
(4) |
Apr
(5) |
May
|
Jun
|
Jul
|
Aug
(5) |
Sep
(6) |
Oct
|
Nov
(5) |
Dec
(8) |
| 2014 |
Jan
(17) |
Feb
(24) |
Mar
(8) |
Apr
(7) |
May
(18) |
Jun
(15) |
Jul
(5) |
Aug
(2) |
Sep
(49) |
Oct
(28) |
Nov
(7) |
Dec
(30) |
| 2015 |
Jan
(40) |
Feb
|
Mar
(9) |
Apr
(2) |
May
(9) |
Jun
(31) |
Jul
(33) |
Aug
(5) |
Sep
(20) |
Oct
|
Nov
(3) |
Dec
(12) |
| 2016 |
Jan
(14) |
Feb
(29) |
Mar
(10) |
Apr
(4) |
May
(4) |
Jun
|
Jul
(5) |
Aug
(19) |
Sep
(21) |
Oct
(2) |
Nov
(36) |
Dec
(30) |
| 2017 |
Jan
(101) |
Feb
(12) |
Mar
(7) |
Apr
(2) |
May
(29) |
Jun
(22) |
Jul
(7) |
Aug
(93) |
Sep
(27) |
Oct
(39) |
Nov
|
Dec
|
|
From: Roberto S. <rob...@po...> - 2010-07-06 15:08:30
|
This patch modifies the default policy shipped with IMA, in order to avoid measurements
of files in the initial ramdisk. Those files can be measured early in the boot process
by the bootloader.
The patch applies to latest version of the mainline kernel 2.6.35-rc4.
Signed-off-by: Roberto Sassu <rob...@po...>
---
security/integrity/ima/ima_policy.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index aef8c0a..92d8d0e 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -64,6 +64,7 @@ static struct ima_measure_rule_entry default_rules[] = {
{.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
.flags = IMA_FUNC | IMA_MASK},
{.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
--
1.7.1
|
|
From: Shaz <sha...@gm...> - 2010-07-01 07:11:42
|
Dear all, I want to read/load a configuration file but I don't want it to get measured. It has an SELinux label that makes ima to measure it while load and it is not possible to give it another label due the access control model being employed. How can this one file be excluded from measurement? thanks, -- Shaz |
|
From: Mimi Z. <zo...@li...> - 2010-06-30 14:47:15
|
On Wed, 2010-06-30 at 14:15 +0100, chloé Fouquet wrote: > Hi, > I have compile a kernel 2.6.32 on my ubuntu 9.04. My menu.lst is : > > > title Linux kernel 2.6.32 > root (hd0,1) > kernel /boot/vmlinuz-2.6.32 root=/dev/mapper/systemvg-root > initrd /boot/initrd.img-2.6.32 ima_tcb=1 selinux=1 > > > But the command : /sys/kernel/security/ima/ascii_runtime_measurements > gives me only the boot aggregate > > > 10 bcaa719b82183ba8276ae77ddb1d870ce4e1a1dc ima > 4daed4d737ce85a26da3841274da3e6d857db514 boot_aggregate > > > What I'm missing ? I tried on my virtual machine without tpm chip and > it was working, I could get the value of executables and libraries... > Do I need to use this function : ima_appraise, I didn't really > understand what it was for... > > > Chloe Hi Choloe, To enable the default measurement policy, you need to specify on the boot command line the option 'ima_tcb=1'. Mimi |
|
From: chloé F. <fou...@gm...> - 2010-06-30 13:15:41
|
Hi, I have compile a kernel 2.6.32 on my ubuntu 9.04. My menu.lst is : title Linux kernel 2.6.32 root (hd0,1) kernel /boot/vmlinuz-2.6.32 root=/dev/mapper/systemvg-root initrd /boot/initrd.img-2.6.32 ima_tcb=1 selinux=1 But the command : /sys/kernel/security/ima/ascii_runtime_measurements gives me only the boot aggregate 10 bcaa719b82183ba8276ae77ddb1d870ce4e1a1dc ima 4daed4d737ce85a26da3841274da3e6d857db514 boot_aggregate What I'm missing ? I tried on my virtual machine without tpm chip and it was working, I could get the value of executables and libraries... Do I need to use this function : ima_appraise, I didn't really understand what it was for... Chloe |
|
From: Shaz <sha...@gm...> - 2010-06-28 15:26:01
|
On Mon, Jun 28, 2010 at 6:04 PM, chloé Fouquet <fou...@gm...>wrote: > Hi, > I would like to know how is used ima practically. In fact how is used the > TPM at the moment ? > If I want to verify that a certain application on your computer is genuine > do I need you to run it and send me after your "ima digests" file and after > I check if the .exe value has a good hash ? > If you could give me some examples of how is used the TPM, the trusted boot > and the ima architecture practically I will be very grateful ! > Hi Chloe, Please go through http://linux-ima/sourceforge.net. You might find EVM interesting but what you are asking for is remote attestation. This means that I have to send you my ima measurement list which you will check against known good hashes and then recompute the PCR composite that I send along with the ima measurements in the form of PCR10 quote. So you have to open the quote and and remeasure the composite to verify that tpm extended values and IMA hashes are the same. Have a look at http://domino.research.ibm.com/comm/research_people.nsf/pages/sailer.ima.htmland follow some of the resources mentioned on it. You will also need to understand the creation of AIK and also might want to have some form of protocol for you usecase. -- Shaz |
|
From: chloé F. <fou...@gm...> - 2010-06-28 13:04:21
|
Hi, I would like to know how is used ima practically. In fact how is used the TPM at the moment ? If I want to verify that a certain application on your computer is genuine do I need you to run it and send me after your "ima digests" file and after I check if the .exe value has a good hash ? If you could give me some examples of how is used the TPM, the trusted boot and the ima architecture practically I will be very grateful ! Chloe |
|
From: Shaz <sha...@gm...> - 2010-06-25 12:03:54
|
On Thu, Jun 24, 2010 at 5:45 PM, chloé Fouquet <fou...@gm...>wrote: > Hi, > I'm new in using IMA with a TPM. Is there somewhere a good tutorial from > the installation to the use ? > I have a ubuntu version 9.04 with a kernel 2.6.28. I didn't find any patch > for that kernel on sourceforge, do I need to compile a more recent kernel > like 2.6.30 that has the IMA option ? > Do I need TrustedGrub to have IMA ? In that case it will only work with > grub1 and not grub2 right ? > > Trusted grub gives you a complete chian of trust so it is important but you can skip it if you are just having fun with IMA because IMA does not depend on it. Trusted grub implements IMA as well. Not sure what you mean by grub1 and grub2 but you will be using trusted grub instead of standard distro provided grub if you go for the complete chain of trust. The backporting will work but it will be difficult to handle as the patches need to be applied from multiple sources. The filesystem code is also a bit different between 2.6.30 and the earlier kernels so go for a more recent kernel that is available from Ubuntu repositories like the 2.6.32. Good luck. -- Shaz |
|
From: Mimi Z. <zo...@li...> - 2010-06-24 14:15:47
|
On Thu, 2010-06-24 at 13:45 +0100, chloé Fouquet wrote: > Hi, > I'm new in using IMA with a TPM. Is there somewhere a good tutorial > from the installation to the use ? > I have a ubuntu version 9.04 with a kernel 2.6.28. I didn't find any > patch for that kernel on sourceforge, do I need to compile a more > recent kernel like 2.6.30 that has the IMA option ? > Do I need TrustedGrub to have IMA ? In that case it will only work > with grub1 and not grub2 right ? Hi Chloe, Probably the earliest backport of IMA was to 2.6.29-rc3 for OpenMoko (http://waqarafridi.wordpress.com/2009/10/15/porting-ima-plus-selinux-on-openmoko/). If you're already building a new kernel, you might as well go with the latest stable version, which can be downloaded from www.kernel.org. There were some major changes between 2.6.33 and 2.6.34. The IMA sf site, http://linux-ima.sourceforge.net/, is the right place to start. thanks, Mimi |
|
From: chloé F. <fou...@gm...> - 2010-06-24 12:45:30
|
Hi, I'm new in using IMA with a TPM. Is there somewhere a good tutorial from the installation to the use ? I have a ubuntu version 9.04 with a kernel 2.6.28. I didn't find any patch for that kernel on sourceforge, do I need to compile a more recent kernel like 2.6.30 that has the IMA option ? Do I need TrustedGrub to have IMA ? In that case it will only work with grub1 and not grub2 right ? Thanks for looking Chloe |
|
From: Mimi Z. <zo...@li...> - 2010-06-07 12:44:07
|
There are a variety of criteria that can be used to determine if a
file must be measured or not. A useful feature of recent versions
of IMA is the ability of making measurement decisions based on the
label assigned by a "Mandatory Access Control" to a process, which
is accessing a file, or based on the object LSM label itself. In
general this data, i.e. LSM subject/object labels, can be used during
the "Remote Attestation" by a verifier to better evaluate if a trust
relationship should be established with the remote peer.
This patch adds LSM object/subject labels to the ima-nglong template,
used in remote attestation.
Signed-off-by: Roberto Sassu <rob...@po...>
Signed-off-by: Mimi Zohar <zo...@us...>
---
security/integrity/ima/ima.h | 4 +-
security/integrity/ima/ima_api.c | 80 +++++++++++++++++++++++++++++-------
security/integrity/ima/ima_fs.c | 36 ++++++++++++----
security/integrity/ima/ima_queue.c | 5 ++-
4 files changed, 100 insertions(+), 25 deletions(-)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 4be13fa..26c830e 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -86,7 +86,9 @@ 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);
+ unsigned short *o_gid,
+ u32 *o_obj_lsm_label_len,
+ u32 *o_subj_lsm_label_len);
extern struct ima_template_entry *ima_ng_alloc_init_entry(struct inode *inode,
const unsigned char
*filename,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index b3fd469..cb67f21 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2008 IBM Corporation
+ * Copyright (C) 2008 - 2010 IBM Corporation
+ * Copyright (C) 2010 Politecnico di Torino, Italy,
+ * Roberto Sassu <rob...@po...>
*
* Author: Mimi Zohar <zo...@us...>
*
@@ -176,17 +178,27 @@ out:
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)
+ unsigned short *o_uid, unsigned short *o_gid,
+ u32 *o_obj_label_len, u32 *o_subj_label_len)
{
int filename_len = *o_filename;
+ u32 obj_label_len = *o_obj_label_len;
*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
+
+ if (ima_template == IMA_NG_TEMPLATE)
+ return;
+ if (entry)
*o_uid = *o_filename + strlen((char *)entry + *o_filename) + 1;
+ else
+ *o_uid = *o_filename + filename_len + 1;
*o_gid = *o_uid + sizeof(uid_t);
+
+ *o_obj_label_len = *o_gid + sizeof(gid_t);
+ if (entry)
+ obj_label_len = *(u32 *) ((char *)entry + *o_obj_label_len);
+ *o_subj_label_len = *o_obj_label_len + sizeof(u32) + obj_label_len + 1;
}
/* ima_ng_alloc_init_entry - allocate and initialize the new entry
@@ -202,6 +214,10 @@ void ima_ng_get_offsets(struct ima_template_entry *entry,
* additional: ima_nglong template
* uid_t - file's uid
* gid_t - file's gid
+ * u32 obj_label len
+ * char obj_label[] - null terminated LSM object label
+ * u32 subj_label len
+ * char subj_label[] - null terminated LSM subject label
*/
struct ima_template_entry *ima_ng_alloc_init_entry(struct inode *inode,
const unsigned char
@@ -209,12 +225,31 @@ struct ima_template_entry *ima_ng_alloc_init_entry(struct inode *inode,
{
struct ima_template_entry *entry;
unsigned short o_digest, o_filename, o_uid, o_gid;
- unsigned short template_data_size;
+ u32 o_obj_label_len = 0, o_subj_label_len = 0;
+ u32 obj_label_len = 0, subj_label_len = 0;
+ char *obj_label = NULL;
+ char *subj_label = NULL;
+ int template_data_size;
+
+ if ((ima_template == IMA_NGLONG_TEMPLATE) && inode) {
+ u32 osid, sid;
+ int rc;
+
+ security_inode_getsecid(inode, &osid);
+ rc = security_secid_to_secctx(osid, &obj_label, &obj_label_len);
+ o_obj_label_len = obj_label_len;
+ security_task_getsecid(current, &sid);
+ rc = security_secid_to_secctx(sid, &subj_label,
+ &subj_label_len);
+ o_subj_label_len = subj_label_len;
+ }
o_filename = strlen(filename);
- ima_ng_get_offsets(NULL, &o_digest, &o_filename, &o_uid, &o_gid);
+ ima_ng_get_offsets(NULL, &o_digest, &o_filename, &o_uid, &o_gid,
+ &o_obj_label_len, &o_subj_label_len);
template_data_size = ima_template == IMA_NG_TEMPLATE ?
- o_filename + strlen(filename) + 1 : o_gid + sizeof(gid_t);
+ o_filename + strlen(filename) + 1 :
+ o_subj_label_len + sizeof(u32) + subj_label_len + 1;
entry = kzalloc(sizeof(*entry) + template_data_size, GFP_KERNEL);
if (!entry)
@@ -226,14 +261,29 @@ struct ima_template_entry *ima_ng_alloc_init_entry(struct inode *inode,
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
+ if (ima_template == IMA_NG_TEMPLATE) {
entry->template_name = IMA_NG_TEMPLATE_NAME;
+ goto out;
+ }
+
+ 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;
+ }
+ *(entry->template + o_obj_label_len) = obj_label_len;
+ if (obj_label_len > 0) {
+ memcpy(entry->template + o_obj_label_len +
+ sizeof obj_label_len, obj_label, obj_label_len);
+ security_release_secctx(obj_label, obj_label_len);
+ }
+
+ *(entry->template + o_subj_label_len) = subj_label_len;
+ if (subj_label_len > 0) {
+ memcpy(entry->template + o_subj_label_len +
+ sizeof subj_label_len, subj_label, subj_label_len);
+ security_release_secctx(subj_label, subj_label_len);
+ }
out:
return entry;
}
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 4965485..e921f38 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -1,10 +1,12 @@
/*
- * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ * Copyright (C) 2005 - 2010 IBM Corporation
+ * Copyright (C) 2010 Politecnico di Torino, Italy,
+ * Roberto Sassu <rob...@po...>
*
* Authors:
- * Kylene Hall <kj...@us...>
- * Reiner Sailer <sa...@us...>
- * Mimi Zohar <zo...@us...>
+ * Kylene Hall <kj...@us...>
+ * Reiner Sailer <sa...@us...>
+ * Mimi Zohar <zo...@us...>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -198,6 +200,8 @@ void ima_template_show(struct seq_file *m, int e_len, void *e,
{
struct ima_template_data *entry = e;
unsigned short o_digest, o_filename, o_uid, o_gid;
+ u32 o_obj_lsm_label_len, o_subj_lsm_label_len;
+ u32 lsm_label_len;
int namelen;
switch (show) {
@@ -208,15 +212,31 @@ void ima_template_show(struct seq_file *m, int e_len, void *e,
seq_printf(m, " %s\n", entry->file_name);
} else {
ima_ng_get_offsets(e, &o_digest, &o_filename,
- &o_uid, &o_gid);
+ &o_uid, &o_gid,
+ &o_obj_lsm_label_len,
+ &o_subj_lsm_label_len);
seq_printf(m, "%s ", (char *)e);
ima_print_digest(m, e + o_digest,
ima_template_hash_size);
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));
+ if (ima_template == IMA_NG_TEMPLATE) {
+ seq_putc(m, '\n');
+ break;
}
+ seq_printf(m, " %u", *(uid_t *) (e + o_uid));
+ seq_printf(m, " %u", *(gid_t *) (e + o_gid));
+
+ lsm_label_len = *(u32 *) (e + o_obj_lsm_label_len);
+ if (lsm_label_len > 0)
+ seq_printf(m, " %s",
+ (char *)e + o_obj_lsm_label_len
+ + sizeof(lsm_label_len));
+
+ lsm_label_len = *(u32 *) (e + o_subj_lsm_label_len);
+ if (lsm_label_len > 0)
+ seq_printf(m, " %s",
+ (char *)(e + o_subj_lsm_label_len
+ + sizeof(lsm_label_len)));
seq_putc(m, '\n');
}
break;
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 70fa993..168d3e3 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -108,6 +108,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
const char *audit_cause = "hash_added";
int audit_info = 1;
unsigned short o_digest, o_filename, o_uid, o_gid;
+ u32 o_obj_label_len = 0, o_subj_label_len = 0;
int result = 0;
mutex_lock(&ima_extend_list_mutex);
@@ -136,7 +137,9 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
}
out:
mutex_unlock(&ima_extend_list_mutex);
- ima_ng_get_offsets(entry, &o_digest, &o_filename, &o_uid, &o_gid);
+ ima_ng_get_offsets(entry, &o_digest, &o_filename, &o_uid, &o_gid,
+ &o_obj_label_len, &o_subj_label_len);
+
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
entry->template + o_filename,
op, audit_cause, result, audit_info);
--
1.6.6.1
|
|
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
|
|
From: Mimi Z. <zo...@li...> - 2010-06-07 12:43:45
|
The current maximum template-data digest size is limited to 20 bytes.
This patch adds support for larger template-data digests and introduces
the command line option 'ima_template_hash=' used to specify the
template hash algorithm.
Signed-off-by: Mimi Zohar <zo...@us...>
---
Documentation/kernel-parameters.txt | 4 ++
include/linux/tpm.h | 1 +
security/integrity/ima/Kconfig | 2 +
security/integrity/ima/ima.h | 16 +++++-
security/integrity/ima/ima_api.c | 87 ++++++++++++++++++++++++++++++-----
security/integrity/ima/ima_crypto.c | 22 ++++----
security/integrity/ima/ima_fs.c | 50 ++++++++++++++------
security/integrity/ima/ima_iint.c | 5 +-
security/integrity/ima/ima_init.c | 19 +++++---
security/integrity/ima/ima_main.c | 31 ++++++++++++-
security/integrity/ima/ima_queue.c | 4 +-
11 files changed, 188 insertions(+), 53 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 009b6ab..987fa8e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -993,6 +993,10 @@ and is between 256 and 4096 characters. It is defined in the file
Format: { "ima" | "ima-ng" }
default: "ima"
+ ima_template_hash= [IMA] Choose an IMA template data hash algorithm
+ Format: { "sha1" | "sha256" | "sha512" }
+ default: "sha1"
+
in2000= [HW,SCSI]
See header of drivers/scsi/in2000.c.
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index ac5d1c1..00bd423 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -26,6 +26,7 @@
* Chip num is this value or a valid tpm idx
*/
#define TPM_ANY_NUM 0xFFFF
+#define TPM_DIGEST_SIZE 20
#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index b6ecfd4..da249ea 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -8,6 +8,8 @@ config IMA
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_SHA1
+ select CRYPTO_SHA256
+ select CRYPTO_SHA512
select TCG_TPM if !S390
select TCG_TIS if TCG_TPM
help
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 6a6c80c..4c7d1a4 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -41,6 +41,9 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
extern int ima_initialized;
extern int ima_used_chip;
extern char *ima_hash;
+extern int ima_hash_size;
+extern char *ima_template_hash;
+extern int ima_template_hash_size;
/* IMA inode template definition */
struct ima_template_data {
@@ -52,7 +55,7 @@ struct ima_template_entry {
u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */
const char *template_name;
int template_len;
- struct ima_template_data template;
+ u8 template[0]; /* ima, ima_ng template data */
};
struct ima_queue_entry {
@@ -79,6 +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
+ *filename,
+ u8 *digest);
+extern struct ima_template_entry *ima_alloc_init_entry(const unsigned char
+ *filename, u8 *digest);
/*
* used to protect h_table and sha_table
@@ -104,13 +114,13 @@ static inline unsigned long ima_hash_key(u8 *digest)
struct ima_iint_cache {
u64 version; /* track inode changes */
unsigned long flags;
- u8 digest[IMA_DIGEST_SIZE];
struct mutex mutex; /* protects: version, flags, digest */
long readcount; /* measured files readcount */
long writecount; /* measured files writecount */
long opencount; /* opens reference count */
struct kref refcount; /* ima_iint_cache reference count */
struct rcu_head rcu;
+ u8 digest[0];
};
/* LIM API function definitions */
@@ -121,7 +131,7 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
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,
+void ima_template_show(struct seq_file *m, int e_len, void *e,
enum ima_show_type show);
/* radix tree calls to lookup, insert, delete
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 3eb2f22..a3d0029 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -43,11 +43,6 @@ int ima_store_template(struct ima_template_entry *entry,
int result;
memset(entry->digest, 0, sizeof(entry->digest));
- if (ima_template == IMA_NG_TEMPLATE)
- entry->template_name = IMA_NG_TEMPLATE_NAME;
- else
- entry->template_name = IMA_TEMPLATE_NAME;
- entry->template_len = sizeof(entry->template);
if (!violation) {
result = ima_calc_template_hash(entry->template_len,
@@ -81,13 +76,13 @@ void ima_add_violation(struct inode *inode, const unsigned char *filename,
/* can overflow, only indicator */
atomic_long_inc(&ima_htable.violations);
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ entry = ima_template == IMA_TEMPLATE ?
+ ima_alloc_init_entry(filename, NULL) :
+ ima_ng_alloc_init_entry(filename, NULL);
if (!entry) {
result = -ENOMEM;
goto err_out;
}
- memset(&entry->template, 0, sizeof(entry->template));
- strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
result = ima_store_template(entry, violation, inode);
if (result < 0)
kfree(entry);
@@ -152,6 +147,74 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file)
return result;
}
+/* ima_alloc_init_entry - allocate and initialize a template entry
+ *
+ * Allocate contigous memory for ima_template_entry + ima_template_data.
+ */
+struct ima_template_entry *ima_alloc_init_entry(const unsigned char *filename,
+ u8 *digest)
+{
+ struct ima_template_entry *entry;
+ struct ima_template_data *data;
+
+ entry = kmalloc(sizeof(*entry) + sizeof(*data), GFP_KERNEL);
+ if (!entry)
+ goto out;
+ entry->template_name = IMA_TEMPLATE_NAME;
+ entry->template_len = sizeof(*data);
+
+ data = (struct ima_template_data *)entry->template;
+ memset(data, 0, sizeof(*data));
+ strncpy(data->file_name, filename, IMA_EVENT_NAME_LEN_MAX);
+ memset(data->digest, 0, sizeof data->digest);
+ if (digest)
+ memcpy(data->digest, digest, IMA_DIGEST_SIZE);
+out:
+ return entry;
+}
+
+void ima_ng_get_offsets(unsigned short *o_digest, unsigned short *o_filename)
+{
+ *o_digest = strlen(ima_template_hash) + 1;
+ *o_filename = *o_digest + ima_template_hash_size;
+}
+
+/* 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.
+ *
+ * Format:
+ * char algname[] - null terminated hash algorithm name
+ * u8 digest[] - digest size based on algorithm
+ * char file_name[] - null terminated file name
+ */
+struct ima_template_entry *ima_ng_alloc_init_entry(const unsigned char
+ *filename, u8 *digest)
+{
+ struct ima_template_entry *entry;
+ unsigned short o_digest, o_filename;
+ unsigned short template_data_size;
+
+ ima_ng_get_offsets(&o_digest, &o_filename);
+ template_data_size = o_filename + strlen(filename) + 1;
+
+ 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);
+ if (digest)
+ memcpy(entry->template + o_digest, digest,
+ ima_template_hash_size);
+ strcpy(entry->template + o_filename, filename);
+out:
+ return entry;
+}
+
/*
* ima_store_measurement - store file measurement
*
@@ -177,15 +240,15 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
struct ima_template_entry *entry;
int violation = 0;
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ entry = ima_template == IMA_TEMPLATE ?
+ ima_alloc_init_entry(filename, iint->digest) :
+ ima_ng_alloc_init_entry(filename, iint->digest);
+
if (!entry) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
op, audit_cause, result, 0);
return;
}
- memset(&entry->template, 0, sizeof(entry->template));
- memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE);
- strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
result = ima_store_template(entry, violation, inode);
if (!result)
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 9b3ade7..ef289e3 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -21,14 +21,14 @@
#include <linux/slab.h>
#include "ima.h"
-static int init_desc(struct hash_desc *desc)
+static int init_desc(struct hash_desc *desc, char *alg)
{
int rc;
- desc->tfm = crypto_alloc_hash(ima_hash, 0, CRYPTO_ALG_ASYNC);
+ desc->tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(desc->tfm)) {
pr_info("IMA: failed to load %s transform: %ld\n",
- ima_hash, PTR_ERR(desc->tfm));
+ alg, PTR_ERR(desc->tfm));
rc = PTR_ERR(desc->tfm);
return rc;
}
@@ -40,7 +40,7 @@ static int init_desc(struct hash_desc *desc)
}
/*
- * Calculate the MD5/SHA1 file digest
+ * Calculate the file digest
*/
int ima_calc_hash(struct file *file, char *digest)
{
@@ -50,7 +50,7 @@ int ima_calc_hash(struct file *file, char *digest)
char *rbuf;
int rc;
- rc = init_desc(&desc);
+ rc = init_desc(&desc, ima_template_hash);
if (rc != 0)
return rc;
@@ -94,7 +94,7 @@ int ima_calc_template_hash(int template_len, void *template, char *digest)
struct scatterlist sg[1];
int rc;
- rc = init_desc(&desc);
+ rc = init_desc(&desc, ima_hash);
if (rc != 0)
return rc;
@@ -122,19 +122,19 @@ int __init ima_calc_boot_aggregate(char *digest)
{
struct hash_desc desc;
struct scatterlist sg;
- u8 pcr_i[IMA_DIGEST_SIZE];
+ u8 pcr_i[TPM_DIGEST_SIZE];
int rc, i;
- rc = init_desc(&desc);
+ rc = init_desc(&desc, ima_template_hash);
if (rc != 0)
return rc;
- /* cumulative sha1 over tpm registers 0-7 */
+ /* cumulative hash over TPM registers 0-7 */
for (i = TPM_PCR0; i < TPM_PCR8; i++) {
ima_pcrread(i, pcr_i);
/* now accumulate with current aggregate */
- sg_init_one(&sg, pcr_i, IMA_DIGEST_SIZE);
- rc = crypto_hash_update(&desc, &sg, IMA_DIGEST_SIZE);
+ sg_init_one(&sg, pcr_i, TPM_DIGEST_SIZE);
+ rc = crypto_hash_update(&desc, &sg, TPM_DIGEST_SIZE);
}
if (!rc)
crypto_hash_final(&desc, digest);
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 5221c83..85491d4 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -22,14 +22,20 @@
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/parser.h>
+#include <crypto/sha.h>
#include "ima.h"
int ima_template = IMA_NG_TEMPLATE;
static int __init ima_template_setup(char *str)
{
- if (strncmp(str, "ima", 3) == 0)
+ if (strncmp(str, "ima", 3) == 0) {
ima_template = IMA_TEMPLATE;
+ if (strncmp(ima_template_hash, "sha256", 6) == 0) {
+ ima_template_hash = "sha1";
+ ima_template_hash_size = SHA1_DIGEST_SIZE;
+ }
+ }
return 1;
}
__setup("ima_template=", ima_template_setup);
@@ -154,8 +160,7 @@ static int ima_measurements_show(struct seq_file *m, void *v)
ima_putc(m, &e->template_len, sizeof e->template_len);
/* 5th: template specific data */
- ima_template_show(m, (struct ima_template_data *)&e->template,
- IMA_SHOW_BINARY);
+ ima_template_show(m, e->template_len, &e->template, IMA_SHOW_BINARY);
return 0;
}
@@ -178,30 +183,44 @@ static const struct file_operations ima_measurements_ops = {
.release = seq_release,
};
-static void ima_print_digest(struct seq_file *m, u8 *digest)
+static void ima_print_digest(struct seq_file *m, u8 *digest, int digest_size)
{
int i;
- for (i = 0; i < IMA_DIGEST_SIZE; i++)
+ for (i = 0; i < digest_size; i++)
seq_printf(m, "%02x", *(digest + i));
}
-void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show)
+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;
int namelen;
switch (show) {
case IMA_SHOW_ASCII:
- ima_print_digest(m, entry->digest);
- seq_printf(m, " %s\n", entry->file_name);
+ if (ima_template == IMA_TEMPLATE) {
+ ima_print_digest(m, entry->digest,
+ ima_template_hash_size);
+ seq_printf(m, " %s\n", entry->file_name);
+ } else {
+ ima_ng_get_offsets(&o_digest, &o_filename);
+ 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);
+ }
break;
case IMA_SHOW_BINARY:
- ima_putc(m, entry->digest, IMA_DIGEST_SIZE);
-
- namelen = strlen(entry->file_name);
- ima_putc(m, &namelen, sizeof namelen);
- ima_putc(m, entry->file_name, namelen);
+ if (ima_template == IMA_TEMPLATE) {
+ ima_putc(m, entry->digest, IMA_DIGEST_SIZE);
+
+ namelen = strlen(entry->file_name);
+ ima_putc(m, &namelen, sizeof namelen);
+ ima_putc(m, entry->file_name, namelen);
+ } else
+ ima_putc(m, e, e_len);
default:
break;
}
@@ -223,14 +242,13 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX);
/* 2nd: SHA1 template hash */
- ima_print_digest(m, e->digest);
+ ima_print_digest(m, e->digest, ima_hash_size);
/* 3th: template name */
seq_printf(m, " %s ", e->template_name);
/* 4th: template specific data */
- ima_template_show(m, (struct ima_template_data *)&e->template,
- IMA_SHOW_ASCII);
+ ima_template_show(m, e->template_len, &e->template, IMA_SHOW_ASCII);
return 0;
}
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index 7625b85..0b5619b 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -139,8 +139,9 @@ static void init_once(void *foo)
static int __init ima_iintcache_init(void)
{
iint_cache =
- kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
- SLAB_PANIC, init_once);
+ kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache)
+ + ima_template_hash_size,
+ 0, SLAB_PANIC, init_once);
return 0;
}
security_initcall(ima_iintcache_init);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 17f1f06..9701db2 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -46,23 +46,28 @@ static void __init ima_add_boot_aggregate(void)
const char *audit_cause = "ENOMEM";
int result = -ENOMEM;
int violation = 1;
+ u8 *digest;
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
+ digest = kzalloc(ima_template_hash_size, GFP_KERNEL);
+ if (!digest)
goto err_out;
- memset(&entry->template, 0, sizeof(entry->template));
- strncpy(entry->template.file_name, boot_aggregate_name,
- IMA_EVENT_NAME_LEN_MAX);
if (ima_used_chip) {
violation = 0;
- result = ima_calc_boot_aggregate(entry->template.digest);
+ result = ima_calc_boot_aggregate(digest);
if (result < 0) {
audit_cause = "hashing_error";
- kfree(entry);
+ kfree(digest);
goto err_out;
}
}
+ entry = ima_template == IMA_TEMPLATE ?
+ ima_alloc_init_entry(boot_aggregate_name, digest) :
+ ima_ng_alloc_init_entry(boot_aggregate_name, digest);
+ kfree(digest);
+ if (!entry)
+ goto err_out;
+
result = ima_store_template(entry, violation, NULL);
if (result < 0)
kfree(entry);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index f936413..414f642 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -22,20 +22,49 @@
#include <linux/mount.h>
#include <linux/mman.h>
#include <linux/slab.h>
+#include <crypto/sha.h>
+#include <crypto/md5.h>
#include "ima.h"
int ima_initialized;
char *ima_hash = "sha1";
+int ima_hash_size = SHA1_DIGEST_SIZE;
static int __init hash_setup(char *str)
{
- if (strncmp(str, "md5", 3) == 0)
+ if (strncmp(str, "md5", 3) == 0) {
ima_hash = "md5";
+ ima_hash_size = MD5_DIGEST_SIZE;
+ }
return 1;
}
__setup("ima_hash=", hash_setup);
+char *ima_template_hash = "sha256";
+int ima_template_hash_size = SHA256_DIGEST_SIZE;
+static int __init template_hash_setup(char *str)
+{
+ if (strncmp(str, "md5", 3) == 0) {
+ ima_template_hash = "md5";
+ ima_template_hash_size = MD5_DIGEST_SIZE;
+ }
+ if (strncmp(str, "sha1", 4) == 0) {
+ ima_template_hash = "sha1";
+ ima_template_hash_size = SHA1_DIGEST_SIZE;
+ }
+ if (ima_template == IMA_TEMPLATE)
+ goto out;
+
+ if (strncmp(str, "sha512", 6) == 0) {
+ ima_template_hash = "sha512";
+ ima_template_hash_size = SHA512_DIGEST_SIZE;
+ }
+out:
+ return 1;
+}
+__setup("ima_template_hash=", template_hash_setup);
+
struct ima_imbalance {
struct hlist_node node;
unsigned long fsmagic;
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 8e28f04..a8c0b12 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -107,6 +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;
int result = 0;
mutex_lock(&ima_extend_list_mutex);
@@ -135,8 +136,9 @@ 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);
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
- entry->template.file_name,
+ entry->template + o_filename,
op, audit_cause, result, audit_info);
return result;
}
--
1.6.6.1
|
|
From: Mimi Z. <zo...@li...> - 2010-06-07 12:43:40
|
Adding the template length to the binary_runtime_measurement list,
simplifies userspace support for different template types.
This patch introduces the command line option 'ima_template='
for backward compatibility.
Signed-off-by: Mimi Zohar <zo...@us...>
---
Documentation/kernel-parameters.txt | 5 +++++
security/integrity/ima/ima.h | 3 +++
security/integrity/ima/ima_api.c | 6 +++++-
security/integrity/ima/ima_fs.c | 16 ++++++++++++++--
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 1808f11..009b6ab 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -988,6 +988,11 @@ and is between 256 and 4096 characters. It is defined in the file
programs exec'd, files mmap'd for exec, and all files
opened for read by uid=0.
+ ima_template= [IMA]
+ Support additional runtime measurement formats.
+ Format: { "ima" | "ima-ng" }
+ default: "ima"
+
in2000= [HW,SCSI]
See header of drivers/scsi/in2000.c.
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 16d100d..6a6c80c 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -24,6 +24,9 @@
#include <linux/tpm.h>
#include <linux/audit.h>
+enum ima_template_t { IMA_TEMPLATE, IMA_NG_TEMPLATE };
+extern int ima_template;
+
enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 52015d0..3eb2f22 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -17,6 +17,7 @@
#include "ima.h"
static const char *IMA_TEMPLATE_NAME = "ima";
+static const char *IMA_NG_TEMPLATE_NAME = "ima-ng";
/*
* ima_store_template - store ima template measurements
@@ -42,7 +43,10 @@ int ima_store_template(struct ima_template_entry *entry,
int result;
memset(entry->digest, 0, sizeof(entry->digest));
- entry->template_name = IMA_TEMPLATE_NAME;
+ if (ima_template == IMA_NG_TEMPLATE)
+ entry->template_name = IMA_NG_TEMPLATE_NAME;
+ else
+ entry->template_name = IMA_TEMPLATE_NAME;
entry->template_len = sizeof(entry->template);
if (!violation) {
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 8fe736a..5221c83 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -25,6 +25,15 @@
#include "ima.h"
+int ima_template = IMA_NG_TEMPLATE;
+static int __init ima_template_setup(char *str)
+{
+ if (strncmp(str, "ima", 3) == 0)
+ ima_template = IMA_TEMPLATE;
+ return 1;
+}
+__setup("ima_template=", ima_template_setup);
+
static int valid_policy = 1;
#define TMPBUFLEN 12
static ssize_t ima_show_htable_value(char __user *buf, size_t count,
@@ -86,8 +95,7 @@ static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
* against concurrent list-extension
*/
rcu_read_lock();
- qe = list_entry_rcu(qe->later.next,
- struct ima_queue_entry, later);
+ qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
rcu_read_unlock();
(*pos)++;
@@ -109,6 +117,7 @@ static void ima_putc(struct seq_file *m, void *data, int datalen)
* char[20]=template digest
* 32bit-le=template name size
* char[n]=template name
+ * [eventdata length]
* eventdata[n]=template specific data
*/
static int ima_measurements_show(struct seq_file *m, void *v)
@@ -141,6 +150,9 @@ static int ima_measurements_show(struct seq_file *m, void *v)
/* 4th: template name */
ima_putc(m, (void *)e->template_name, namelen);
+ if (ima_template != IMA_TEMPLATE)
+ ima_putc(m, &e->template_len, sizeof e->template_len);
+
/* 5th: template specific data */
ima_template_show(m, (struct ima_template_data *)&e->template,
IMA_SHOW_BINARY);
--
1.6.6.1
|
|
From: Mimi Z. <zo...@li...> - 2010-06-07 12:43:37
|
As the current ima template digest is a fixed size, new templates are required to support the larger digest sizes. This patch set adds limited template support, not the complete support as originally posted in the LIM patches. Three templates are defined: ima, ima-ng, and ima-nglong. ima-ng adds larger digest sizes for sha256/sha512. In additon to the larger digest sizes, ima-nglong adds LSM object/subject labels. Before posting these patches on LSM, I'd like to discuss what other information, if any, should be included in the ima-nglong template. This patch set applies to the security-testing-2.6/#next tree. The patches are also available for 2.6.34.y stable from: git://linux-ima.git.sourceforge.net/gitroot/linux-ima/2.6.34.y/#ima-template thanks, Mimi Mimi Zohar (4): ima: add template length to binary_runtime_measurements log ima: add support for additional template hash algorithms ima: define ima-nglong template ima: add LSM labels to the ima-nglong template Documentation/kernel-parameters.txt | 9 ++ include/linux/tpm.h | 1 + security/integrity/ima/Kconfig | 2 + security/integrity/ima/ima.h | 25 +++++- security/integrity/ima/ima_api.c | 160 ++++++++++++++++++++++++++++++++-- security/integrity/ima/ima_crypto.c | 22 +++--- security/integrity/ima/ima_fs.c | 100 +++++++++++++++++----- security/integrity/ima/ima_iint.c | 5 +- security/integrity/ima/ima_init.c | 19 +++-- security/integrity/ima/ima_main.c | 31 +++++++- security/integrity/ima/ima_queue.c | 7 ++- 11 files changed, 325 insertions(+), 56 deletions(-) |
|
From: Al V. <vi...@Ze...> - 2010-06-04 08:15:18
|
On Thu, Jun 03, 2010 at 10:06:27AM -0400, Eric Paris wrote: > Al, > > Can you add the following and push this along to Linus on your next go? Applied with trivial modification, but... that's not going to make kABI lovers happy; it's a genuine silent ABI change. Oh, well... |
|
From: Eric P. <ep...@pa...> - 2010-06-03 15:59:02
|
On Tue, Jun 1, 2010 at 1:05 PM, Roberto Sassu <rob...@po...> wrote:
> Description of the issue:
>
> The function 'simple_fill_super()' in the path 'fs/libfs.c' takes the 'magic' argument as int.
> In the include file 'include/linux/fs.h' the 's_magic' field of the 'super_block' structure is
> declared as unsigned long.
> This causes a misbehaviour in the 'Integrity Measurement Architecture' security module,
> since the 's_magic' field is used as criteria to determine if the inode must be measured.
>
> This patch applies to the mainline kernel repository.
>
>
> From a9f6d9bc7b2259ac025977f4b28a8b90784caf62 Mon Sep 17 00:00:00 2001
> From: Roberto Sassu <rob...@po...>
> Date: Tue, 1 Jun 2010 18:28:13 +0200
> Subject: [PATCH] BUG: wrong type for magic argument in simple_fill_super(), fs/libfs.c
>
>
> Signed-off-by: Roberto Sassu <rob...@po...>
Al,
Can you add the following and push this along to Linus on your next go?
Reviewed-by: Mimi Zohar <zo...@us...>
Signed-off-by: Eric Paris <ep...@re...>
CC: st...@ke...
-Eric
> ---
> fs/libfs.c | 2 +-
> include/linux/fs.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/fs/libfs.c b/fs/libfs.c
> index 09e1016..7d966e8 100644
> --- a/fs/libfs.c
> +++ b/fs/libfs.c
> @@ -489,7 +489,7 @@ int simple_write_end(struct file *file, struct address_space *mapping,
> * unique inode values later for this filesystem, then you must take care
> * to pass it an appropriate max_reserved value to avoid collisions.
> */
> -int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
> +int simple_fill_super(struct super_block *s, unsigned long magic, struct tree_descr *files)
> {
> struct inode *inode;
> struct dentry *root;
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 3428393..471e1ff 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2388,7 +2388,7 @@ extern const struct file_operations simple_dir_operations;
> extern const struct inode_operations simple_dir_inode_operations;
> struct tree_descr { char *name; const struct file_operations *ops; int mode; };
> struct dentry *d_alloc_name(struct dentry *, const char *);
> -extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
> +extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
> extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
> extern void simple_release_fs(struct vfsmount **mount, int *count);
>
> --
> 1.6.6.1
>
|
|
From: Roberto S. <rob...@po...> - 2010-06-03 09:59:11
|
Sorry for resending, the previous was rejected by some mailing list.
On Wednesday 02 June 2010 20:44:25 Mimi Zohar wrote:
> On Tue, 2010-06-01 at 19:05 +0200, Roberto Sassu wrote:
> > Description of the issue:
> >
> > The function 'simple_fill_super()' in the path 'fs/libfs.c' takes the 'magic' argument as int.
> > In the include file 'include/linux/fs.h' the 's_magic' field of the 'super_block' structure is
> > declared as unsigned long.
> > This causes a misbehaviour in the 'Integrity Measurement Architecture' security module,
> > since the 's_magic' field is used as criteria to determine if the inode must be measured.
>
> There aren't any magic numbers today greater than 32 bits. Out of
> curiosity, which magic number on which platform are you having a
> problem?
>
I'm using a Fedora 12 64-bit KVM virtual machine. I do some tests on the 'ima_must_measure()'
function and i noted that the result for inodes with superblock magic SELINUX_MAGIC is to
measure, when the action specified in the default policy is don't measure. So i modified
the code to display the superblock's magic of measured inodes adding this line in the function
'process_measurement()' in 'security/integrity/ima/ima_main.c' after 'ima_must_measure()':
printk("file %s: magic: %lx\n", file->f_dentry->d_name.name, inode->i_sb->s_magic);
I obtained this result:
...
file access: magic 0xfffffffff97cff8c
...
The magic that i'm expecting is 0xf97cff8c. I think this is why the IMA policy is not applied
correctly.
I investigated further the selinux's code to understand how the super_block structure is
instantiated in memory and i found this code in 'security/selinux/selinuxfs.c' , line 1601:
ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
In the prototype of the above function the type of the second argument is 'int', when the
's_magic' type of the 'super_block' structure is 'unsigned long'.
In the patch i modified the type of the second argument of the function 'simple_fill_super()'.
This solves my problem but, since this is used by other filesystems, i don't known if this
solution is valid in general.
> > This patch applies to the mainline kernel repository.
> >
> >
> > >From a9f6d9bc7b2259ac025977f4b28a8b90784caf62 Mon Sep 17 00:00:00 2001
> > From: Roberto Sassu <rob...@po...>
> > Date: Tue, 1 Jun 2010 18:28:13 +0200
> > Subject: [PATCH] BUG: wrong type for magic argument in simple_fill_super(), fs/libfs.c
> >
> >
> > Signed-off-by: Roberto Sassu <rob...@po...>
>
> Reviewed-by: Mimi Zohar <zo...@us...>
>
> > ---
> > fs/libfs.c | 2 +-
> > include/linux/fs.h | 2 +-
> > 2 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/libfs.c b/fs/libfs.c
> > index 09e1016..7d966e8 100644
> > --- a/fs/libfs.c
> > +++ b/fs/libfs.c
> > @@ -489,7 +489,7 @@ int simple_write_end(struct file *file, struct address_space *mapping,
> > * unique inode values later for this filesystem, then you must take care
> > * to pass it an appropriate max_reserved value to avoid collisions.
> > */
> > -int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
> > +int simple_fill_super(struct super_block *s, unsigned long magic, struct tree_descr *files)
> > {
> > struct inode *inode;
> > struct dentry *root;
> > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > index 3428393..471e1ff 100644
> > --- a/include/linux/fs.h
> > +++ b/include/linux/fs.h
> > @@ -2388,7 +2388,7 @@ extern const struct file_operations simple_dir_operations;
> > extern const struct inode_operations simple_dir_inode_operations;
> > struct tree_descr { char *name; const struct file_operations *ops; int mode; };
> > struct dentry *d_alloc_name(struct dentry *, const char *);
> > -extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
> > +extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
> > extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
> > extern void simple_release_fs(struct vfsmount **mount, int *count);
> >
>
>
>
|
|
From: Roberto S. <rob...@po...> - 2010-06-03 09:37:02
|
On Wed, 2010-06-02 at 14:44 -0400, Mimi Zohar wrote:
> On Tue, 2010-06-01 at 19:05 +0200, Roberto Sassu wrote:
> > Description of the issue:
> >
> > The function 'simple_fill_super()' in the path 'fs/libfs.c' takes the 'magic' argument as int.
> > In the include file 'include/linux/fs.h' the 's_magic' field of the 'super_block' structure is
> > declared as unsigned long.
> > This causes a misbehaviour in the 'Integrity Measurement Architecture' security module,
> > since the 's_magic' field is used as criteria to determine if the inode must be measured.
>
> There aren't any magic numbers today greater than 32 bits. Out of
> curiosity, which magic number on which platform are you having a
> problem?
>
I'm using a Fedora 12 64-bit KVM virtual machine. I do some tests on
the 'ima_must_measure()' function and i noted that the result for
inodes with superblock magic SELINUX_MAGIC is to measure, when the
action specified in the default policy is don't measure. So i modified
the code to display the superblock's magic of measured inodes adding
this line in the function 'process_measurement()' in
'security/integrity/ima/ima_main.c' after 'ima_must_measure()':
printk("file %s: magic: %lx\n", file->f_dentry->d_name.name,
inode->i_sb->s_magic);
I obtained this result:
...
file access: magic 0xfffffffff97cff8c
...
The magic that i'm expecting is 0xf97cff8c. I think this is why the IMA
policy is not applied correctly.
I investigated further the selinux's code to understand how the
super_block structure is instantiated in memory and i found this code
in 'security/selinux/selinuxfs.c' , line 1601:
ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
In the prototype of the above function the type of the second argument
is 'int', when the 's_magic' type of the 'super_block' structure is
'unsigned long'.
In the patch i modified the type of the second argument of the function
'simple_fill_super('. This solves my problem but, since this is used by
other filesystems, i don't known if this solution is valid in general.
> > This patch applies to the mainline kernel repository.
> >
> >
> > >From a9f6d9bc7b2259ac025977f4b28a8b90784caf62 Mon Sep 17 00:00:00 2001
> > From: Roberto Sassu <rob...@po...>
> > Date: Tue, 1 Jun 2010 18:28:13 +0200
> > Subject: [PATCH] BUG: wrong type for magic argument in simple_fill_super(), fs/libfs.c
> >
> >
> > Signed-off-by: Roberto Sassu <rob...@po...>
>
> Reviewed-by: Mimi Zohar <zo...@us...>
>
> > ---
> > fs/libfs.c | 2 +-
> > include/linux/fs.h | 2 +-
> > 2 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/libfs.c b/fs/libfs.c
> > index 09e1016..7d966e8 100644
> > --- a/fs/libfs.c
> > +++ b/fs/libfs.c
> > @@ -489,7 +489,7 @@ int simple_write_end(struct file *file, struct address_space *mapping,
> > * unique inode values later for this filesystem, then you must take care
> > * to pass it an appropriate max_reserved value to avoid collisions.
> > */
> > -int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
> > +int simple_fill_super(struct super_block *s, unsigned long magic, struct tree_descr *files)
> > {
> > struct inode *inode;
> > struct dentry *root;
> > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > index 3428393..471e1ff 100644
> > --- a/include/linux/fs.h
> > +++ b/include/linux/fs.h
> > @@ -2388,7 +2388,7 @@ extern const struct file_operations simple_dir_operations;
> > extern const struct inode_operations simple_dir_inode_operations;
> > struct tree_descr { char *name; const struct file_operations *ops; int mode; };
> > struct dentry *d_alloc_name(struct dentry *, const char *);
> > -extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
> > +extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
> > extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
> > extern void simple_release_fs(struct vfsmount **mount, int *count);
> >
>
>
|
|
From: Roberto S. <rob...@po...> - 2010-06-01 17:06:31
|
Description of the issue:
The function 'simple_fill_super()' in the path 'fs/libfs.c' takes the 'magic' argument as int.
In the include file 'include/linux/fs.h' the 's_magic' field of the 'super_block' structure is
declared as unsigned long.
This causes a misbehaviour in the 'Integrity Measurement Architecture' security module,
since the 's_magic' field is used as criteria to determine if the inode must be measured.
This patch applies to the mainline kernel repository.
From a9f6d9bc7b2259ac025977f4b28a8b90784caf62 Mon Sep 17 00:00:00 2001
From: Roberto Sassu <rob...@po...>
Date: Tue, 1 Jun 2010 18:28:13 +0200
Subject: [PATCH] BUG: wrong type for magic argument in simple_fill_super(), fs/libfs.c
Signed-off-by: Roberto Sassu <rob...@po...>
---
fs/libfs.c | 2 +-
include/linux/fs.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/libfs.c b/fs/libfs.c
index 09e1016..7d966e8 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -489,7 +489,7 @@ int simple_write_end(struct file *file, struct address_space *mapping,
* unique inode values later for this filesystem, then you must take care
* to pass it an appropriate max_reserved value to avoid collisions.
*/
-int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
+int simple_fill_super(struct super_block *s, unsigned long magic, struct tree_descr *files)
{
struct inode *inode;
struct dentry *root;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3428393..471e1ff 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2388,7 +2388,7 @@ extern const struct file_operations simple_dir_operations;
extern const struct inode_operations simple_dir_inode_operations;
struct tree_descr { char *name; const struct file_operations *ops; int mode; };
struct dentry *d_alloc_name(struct dentry *, const char *);
-extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
+extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
extern void simple_release_fs(struct vfsmount **mount, int *count);
--
1.6.6.1
|
|
From: Mimi Z. <zo...@li...> - 2010-04-29 13:37:06
|
On Tue, 2010-04-27 at 18:49 +0200, Roberto Sassu wrote: > For me, LSM labels can be useful only by accepting these restrictions: > > 1) the target system is running EVM to protect labels against offline attacks; > 2) the system is running SELInux as Mandatory access control (SMACK doesn't have > a reference policy); > 3) the policy enforced is that shipped with the distribution or it is a particular > version of the refpolicy downloaded from Tresys; in this way its digest can be > recognized by the verifier; > 4) the relabeling procedure is executed each time the policy is updated. > > These additional information can give to verifier the possibility to distinguish > between violations and to determine if the integrity of the overall system must be > considered compromised or if the supposed attack involved uncritical components. > For example, if the violation has a subject label like "local_login_t" or "sshd_t", we > can assert that we are in the first case Ok, so this additional information might be useful in some situations, but not all. How about a verbose/long template format option? What else needs to be included? thanks, Mimi |
|
From: Roberto S. <rob...@po...> - 2010-04-27 16:49:31
|
For me, LSM labels can be useful only by accepting these restrictions:
1) the target system is running EVM to protect labels against offline attacks;
2) the system is running SELInux as Mandatory access control (SMACK doesn't have
a reference policy);
3) the policy enforced is that shipped with the distribution or it is a particular
version of the refpolicy downloaded from Tresys; in this way its digest can be
recognized by the verifier;
4) the relabeling procedure is executed each time the policy is updated.
These additional information can give to verifier the possibility to distinguish
between violations and to determine if the integrity of the overall system must be
considered compromised or if the supposed attack involved uncritical components.
For example, if the violation has a subject label like "local_login_t" or "sshd_t", we
can assert that we are in the first case.
On Monday 26 April 2010 14:44:41 Mimi Zohar wrote:
> On Tue, 2010-04-20 at 18:03 +0200, Roberto Sassu wrote:
>
> < snip >
>
> > /* IMA inode template definition */
> > struct ima_template_data {
> > u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */
> > char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */
> > + char subj_label[IMA_LABEL_LEN_MAX + 1]; /* subj_label + \0 */
> > + char obj_label[IMA_LABEL_LEN_MAX + 1]; /* obj_label + \0 */
> > };
>
> As you noted, LSMs have differing size labels. The maximum SMACK label,
> for example, is 23 bytes, so hard coding the size here just doesn't seem
> like the right idea. But before making changes, I think we need to step
> back and discuss what the template data should contain.
>
> To begin the discussion, we know that the template data should not
> contain system specific information, such as inode numbers, as there is
> no way to remotely verify it. LSM labels are system dependent. So do
> they fall into this category? We do know that we need to support
> additional digest types with differing sizes.
>
> Mimi
>
>
|
|
From: Mimi Z. <zo...@li...> - 2010-04-26 12:45:09
|
On Tue, 2010-04-20 at 18:03 +0200, Roberto Sassu wrote:
< snip >
> /* IMA inode template definition */
> struct ima_template_data {
> u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */
> char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */
> + char subj_label[IMA_LABEL_LEN_MAX + 1]; /* subj_label + \0 */
> + char obj_label[IMA_LABEL_LEN_MAX + 1]; /* obj_label + \0 */
> };
As you noted, LSMs have differing size labels. The maximum SMACK label,
for example, is 23 bytes, so hard coding the size here just doesn't seem
like the right idea. But before making changes, I think we need to step
back and discuss what the template data should contain.
To begin the discussion, we know that the template data should not
contain system specific information, such as inode numbers, as there is
no way to remotely verify it. LSM labels are system dependent. So do
they fall into this category? We do know that we need to support
additional digest types with differing sizes.
Mimi
|
|
From: Roberto S. <rob...@po...> - 2010-04-20 16:32:46
|
Hi all i modified the ima_measure utility to work with the patched version of IMA (the patch has been sent in the email with subject: "[RFC][PATCH V2][1/1] ima: extending the format of the measurement list"). I added a new parameter to specify the format that ima_measure will use to parse the measurements list: "-r, --ima_report_format = ima | ima-ng". Further, the management of parameters passed through the command line has been improved. More details can be seen by executing the command "./ima_measure -h". This patch applies on the package "ltp-full-20100331.tgz" downloadable at the url: http://sourceforge.net/projects/ltp/. To use the modified version of ima_measure, these command must be performed: 1) Save the patch included in this mail in a file ima_measure_patch.diff 2) Decompress the ltp package: tar zxf ltp-full-20100331.tgz 3) Enter the directory ltp-full-20100331 4) Apply the patch: cat ../ima_measure_patch.diff | patch -p1 -------------- ima_measure_patch.diff -------------- --- ltp-full-20100331/testcases/kernel/security/integrity/ima/src/ima_measure.c.orig 2010-04-20 18:10:10.588090056 +0200 +++ ltp-full-20100331/testcases/kernel/security/integrity/ima/src/ima_measure.c 2010-04-20 18:15:12.996783044 +0200 @@ -1,9 +1,12 @@ /* * Copyright (c) International Business Machines Corp., 2008 + * Copyright (C) 2009-2010 Politecnico di Torino, Italy, + * TORSEC group -- http://security.polito.it * * Authors: * Reiner Sailer <sa...@wa...> * Mimi Zohar <zo...@us...> + * Roberto Sassu <rob...@po...> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,6 +25,7 @@ #include <fcntl.h> #include <string.h> #include <unistd.h> +#include <getopt.h> //#include "config.h" #include "test.h" #if HAVE_OPENSSL_SHA_H @@ -29,6 +33,14 @@ #endif #define TCG_EVENT_NAME_LEN_MAX 255 +#define IMA_LABEL_LEN_MAX 127 + +#define IMA_REPORT_FORMAT_CURRENT 0 +#define IMA_REPORT_FORMAT_CURRENT_LEN offsetof(struct ima_template_data, subj_label) +#define IMA_REPORT_FORMAT_NG 1 +#define IMA_REPORT_FORMAT_NG_LEN sizeof(struct ima_template_data) + +#define IMA_BINARY_RUNTIME_MEASUREMENTS_PATH "/sys/kernel/security/ima/binary_runtime_measurements" char *TCID = "ima_measure"; int TST_TOTAL = 1; @@ -41,6 +53,17 @@ int TST_TOTAL = 1; static u_int8_t zero[SHA_DIGEST_LENGTH]; static u_int8_t fox[SHA_DIGEST_LENGTH]; +static int verbose = 0; +static int validate = 0; +static int verify = 0; +static int format = 0; + +typedef struct ima_template_data { + u_int8_t digest[SHA_DIGEST_LENGTH]; + char filename[TCG_EVENT_NAME_LEN_MAX + 1]; + char subj_label[IMA_LABEL_LEN_MAX + 1]; + char obj_label[IMA_LABEL_LEN_MAX + 1]; +} ima_template_data; struct event { struct { @@ -49,11 +72,10 @@ struct event { u_int32_t name_len; } header; char name[TCG_EVENT_NAME_LEN_MAX + 1]; - struct { - u_int8_t digest[SHA_DIGEST_LENGTH]; - char filename[TCG_EVENT_NAME_LEN_MAX + 1]; - } ima_data; + struct ima_template_data ima_data; int filename_len; + int subj_label_len; + int obj_label_len; }; static void display_sha1_digest(u_int8_t *digest) @@ -67,14 +89,22 @@ static void display_sha1_digest(u_int8_t /* * Calculate the sha1 hash of data */ -static void calc_digest(u_int8_t *digest, int len, void *data ) +static void calc_digest(u_int8_t *digest, void *data ) { SHA_CTX c; /* Calc template hash for an ima entry */ memset(digest, 0, sizeof *digest); SHA1_Init(&c); - SHA1_Update(&c, data, len); + + SHA1_Update(&c, (u_int8_t *) data, IMA_REPORT_FORMAT_CURRENT_LEN); + if(format == IMA_REPORT_FORMAT_CURRENT) + goto calc_digest_final; + + SHA1_Update(&c, data + IMA_REPORT_FORMAT_CURRENT_LEN, + IMA_REPORT_FORMAT_NG_LEN - IMA_REPORT_FORMAT_CURRENT_LEN); + +calc_digest_final: SHA1_Final(digest, &c); } @@ -87,8 +117,7 @@ static int verify_template_hash(struct e u_int8_t digest[SHA_DIGEST_LENGTH]; memset(digest, 0, sizeof digest); - calc_digest(digest, sizeof template->ima_data, - &template->ima_data); + calc_digest(digest, &template->ima_data); rc = memcmp(digest, template->header.digest, sizeof digest); return rc != 0 ? 1 : 0; } @@ -101,32 +130,83 @@ static int verify_template_hash(struct e * ima_measurements.c - calculate the SHA1 aggregate-pcr value based * on the IMA runtime binary measurements. * - * format: ima_measurement [--validate] [--verify] [--verbose] + * format: ima_measurement [ -xyv ] [--ima_report_format = ima | ima-ng] * - * --validate: forces validation of the aggregrate pcr value - * for an invalidated PCR. Replace all entries in the - * runtime binary measurement list with 0x00 hash values, - * which indicate the PCR was invalidated, either for - * "a time of measure, time of use"(ToMToU) error, or a - * file open for read was already open for write, with - * 0xFF's hash value, when calculating the aggregate - * pcr value. - * - * --verify: for all IMA template entries in the runtime binary - * measurement list, calculate the template hash value - * and compare it with the actual template hash value. - * Return the number of incorrect hash measurements. + * -x, --validate: forces validation of the aggregrate pcr value + * for an invalidated PCR. Replace all entries in the + * runtime binary measurement list with 0x00 hash values, + * which indicate the PCR was invalidated, either for + * "a time of measure, time of use"(ToMToU) error, or a + * file open for read was already open for write, with + * 0xFF's hash value, when calculating the aggregate + * pcr value. * - * --verbose: For all entries in the runtime binary measurement - * list, display the template information. + * -y, --verify: for all IMA template entries in the runtime binary + * measurement list, calculate the template hash value + * and compare it with the actual template hash value. + * Return the number of incorrect hash measurements. + * + * -v, --verbose: For all entries in the runtime binary measurement + * list, display the template information. + * + * -r, --ima_report_format = ima | ima-ng + * Select the format of the measurement list displayed + * through the securityfs filesystem. The first value + * means the actual format is kept; the second one adds + * to each item of the list the subject and object MAC + * labels, if existent. * * template info: list #, PCR-register #, template hash, template name - * IMA info: IMA hash, filename hint + * IMA info: IMA hash, filename hint [, subject_label, object_label ] * * Ouput: displays the aggregate-pcr value * Return code: if verification enabled, returns number of verification * errors. */ + +struct option opts[] = { + {"validate", no_argument, 0, 'x'}, + {"verify", no_argument, 0, 'y'}, + {"verbose", no_argument, 0, 'v'}, + {"ima_report_format", required_argument, 0, 'r'}, + {"ima_pathname", required_argument, 0, 'f'}, +}; + +void +usage(char *argv0) +{ + fprintf(stderr, "%s: calculate the SHA1 aggregate-pcr value based " + "on the IMA runtime binary measurements\n" + "Usage: %s [options]\n" + "Options:\n" + "\t-x,--validate\tforces validation of the aggregrate pcr value\n" + "\t\t\tor an invalidated PCR. Replace all entries in the\n" + "\t\t\truntime binary measurement list with 0x00 hash values,\n" + "\t\t\twhich indicate the PCR was invalidated, either for\n" + "\t\t\t\"a time of measure, time of use\"(ToMToU) error, or a\n" + "\t\t\tfile open for read was already open for write, with\n" + "\t\t\t0xFF's hash value, when calculating the aggregate\n" + "\t\t\tpcr value.\n" + "\t-y,--verify\tfor all IMA template entries in the runtime binary\n" + "\t\t\tmeasurement list, calculate the template hash value\n" + "\t\t\tand compare it with the actual template hash value.\n" + "\t\t\tReturn the number of incorrect hash measurements.\n" + "\t-v,--verbose\tfor all entries in the runtime binary measurement\n" + "\t\t\tlist, display the template information.\n" + "\t-r,--ima_report_format = ima | ima-ng\n" + "\t\t\tselect the format of the measurement list displayed\n" + "\t\t\tthrough the securityfs filesystem. The first value\n" + "\t\t\tmeans the actual format is kept; the second one adds\n" + "\t\t\tto each item of the list the subject and object MAC\n" + "\t\t\tlabels, if existent.\n" + "\t-f,--ima_pathname = pathname\n" + "\t\t\tspecify the path of the \"binary_runtime_measurements\"\n" + "\t\t\tfile from which the list of measurements is obtained\n" + "\t-h,--help\tdisplay this message.\n", + argv0, argv0); + exit(-1); +} + int main(int argc, char *argv[]) { @@ -135,31 +215,51 @@ main(int argc, char *argv[]) FILE *fp; struct event template; u_int8_t pcr[SHA_DIGEST_LENGTH]; - int i, count = 0, len; - - int verbose = 0; - int validate = 0; - int verify = 0; - - if (argc < 2) { - printf("format: %s binary_runtime_measurements" \ - " [--validate] [--verbose] [--verify]\n", argv[0]); - return 1; + int count = 0; + char c; + char *path = NULL; + + while ((c = getopt_long(argc, argv, "hxyvr:f:", opts, 0)) != -1) { + switch (c) { + case 'x': + validate = 1; + break; + case 'v': + verbose = 1; + break; + case 'y': + verify = 1; + break; + case 'r': + if(strncmp(optarg, "ima-ng", 6) == 0) + format = IMA_REPORT_FORMAT_NG; + break; + case 'f': + path = strdup(optarg); + break; + case 'h': + usage(argv[0]);; + break; + default: + printf("Bad option %c\n", c); + usage(argv[0]); + return -1; + } } - - for (i = 2; i < argc; i++) { - if (strncmp(argv[i], "--validate", 8) == 0) - validate = 1; - if (strncmp(argv[i], "--verbose", 7) == 0) - verbose = 1; - if (strncmp(argv[i], "--verify", 6) == 0) - verify = 1; + + if(!path) { + path = strdup(IMA_BINARY_RUNTIME_MEASUREMENTS_PATH); + if(!path) { + perror("Out of memory\n"); + return 1; + } } - fp = fopen(argv[1], "r"); + fp = fopen(path, "r"); if (!fp) { printf("fn: %s\n", argv[1]); perror("Unable to open file\n"); + free(path); return 1; } memset(pcr, 0, SHA_DIGEST_LENGTH); /* initial PCR content 0..0 */ @@ -187,6 +287,7 @@ main(int argc, char *argv[]) if (template.header.name_len > TCG_EVENT_NAME_LEN_MAX) { printf("%d ERROR: event name too long!\n", template.header.name_len); + free(path); exit(1); } memset(template.name, 0, sizeof template.name); @@ -201,7 +302,20 @@ main(int argc, char *argv[]) fread(&template.filename_len, sizeof template.filename_len, 1, fp); fread(template.ima_data.filename, template.filename_len, 1, fp); - print_info(" %s\n", template.ima_data.filename); + print_info(" %s", template.ima_data.filename); + + if (format != IMA_REPORT_FORMAT_CURRENT) { + fread(&template.subj_label_len, + sizeof template.filename_len, 1, fp); + fread(template.ima_data.subj_label, template.subj_label_len, 1, fp); + print_info(" %s", template.ima_data.subj_label); + + fread(&template.obj_label_len, + sizeof template.obj_label_len, 1, fp); + fread(template.ima_data.obj_label, template.obj_label_len, 1, fp); + print_info(" %s", template.ima_data.obj_label); + } + print_info("\n"); if (verify) if (verify_template_hash(&template) != 0) { @@ -210,9 +324,11 @@ main(int argc, char *argv[]) } fclose(fp); + free(path); verbose=1; print_info("PCRAggr (re-calculated):"); display_sha1_digest(pcr); + print_info("\n"); #else tst_resm(TCONF, "System doesn't have openssl/sha.h"); #endif |
|
From: Roberto S. <rob...@po...> - 2010-04-20 16:03:40
|
Description of the issue:
There is a variety of criteria that can be used to determine if a file must be
measured or not; an useful feature of recent versions of IMA is the ability
of take measure decisions depending on the label assigned by a "Mandatory
Access Control" to a process which is accessing a file or depending on the
object label itself.
In general these data, i.e. the subject and the object labels, can be used
during the "Remote Attestation" by a verifier to better evaluate if a trust
relationship should be established with the remote peer: for example if
it wants to check the integrity only of the sshd server, it can
examine the executable and libraries mapped in the process assigned memory by
selecting, from the list of measurements with enhanced format, the rows
with subject label "sshd_t".
This is just a possible check that can be done: to evaluate the integrity
of a generic software component, the verifier must know what Mandatory Access
Control is being executed on the remote system and the relative policy since
the latter is where labels and rules are defined.
The current format of the measurement list is:
| PCR extended | template digest | ima | event digest | event name |
Solution proposed:
The new format proposed adds two new fields:
| PCR extended | template digest | ima | event digest | event name | subject label | object label |
The added data is retrieved in "ima_store_measurement" by calling the function
"security_secid_to_secctx".
Since the template digest is obtained by performing the SHA1 of "event digest"
and "event name", in the patched code even the two added fields have been
included in the hash operation.
In this patch a new kernel parameter has been introduced, "ima_report_format", to
specify the format that IMA will use for the measurement list. Allowed values are:
- "ima": select the current format [default];
- "ima-ng": select the new format with MAC labels.
This patch set applies to kernel 2.6.32 series and 2.6.33 series.
Signed-off-by: Roberto Sassu <rob...@po...>
Acked-by: Gianluca Ramunno <ra...@po...>
Acked-by: Mimi Zohar <zo...@us...>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e2c7487..19c268f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -970,6 +970,16 @@ and is between 256 and 4096 characters. It is defined in the file
programs exec'd, files mmap'd for exec, and all files
opened for read by uid=0.
+ ima_report_format=
+ [IMA]
+ Format: { "ima" | "ima-ng" }
+ default: "ima"
+ Select the format of the measurement list displayed
+ through the securityfs filesystem. The first value
+ means the actual format is kept; the second one adds
+ to each item of the list the subject and object MAC
+ labels, if existent.
+
in2000= [HW,SCSI]
See header of drivers/scsi/in2000.c.
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 47fb65d..10f2410 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -1,9 +1,12 @@
/*
* Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ * Copyright (C) 2009-2010 Politecnico di Torino, Italy,
+ * TORSEC group -- http://security.polito.it
*
* Authors:
* Reiner Sailer <sa...@wa...>
* Mimi Zohar <zo...@us...>
+ * Roberto Sassu <rob...@po...>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -30,19 +33,28 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
/* digest size for IMA, fits SHA1 or MD5 */
#define IMA_DIGEST_SIZE 20
#define IMA_EVENT_NAME_LEN_MAX 255
+#define IMA_LABEL_LEN_MAX 127
#define IMA_HASH_BITS 9
#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
+#define IMA_REPORT_FORMAT_CURRENT 0
+#define IMA_REPORT_FORMAT_CURRENT_LEN offsetof(struct ima_template_data, subj_label)
+#define IMA_REPORT_FORMAT_NG 1
+#define IMA_REPORT_FORMAT_NG_LEN sizeof(struct ima_template_data)
+
/* set during initialization */
extern int ima_initialized;
extern int ima_used_chip;
extern char *ima_hash;
+extern int ima_format;
/* IMA inode template definition */
struct ima_template_data {
u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */
char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */
+ char subj_label[IMA_LABEL_LEN_MAX + 1]; /* subj_label + \0 */
+ char obj_label[IMA_LABEL_LEN_MAX + 1]; /* obj_label + \0 */
};
struct ima_template_entry {
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 2a5e0bc..9848212 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -1,7 +1,11 @@
/*
* Copyright (C) 2008 IBM Corporation
+ * Copyright (C) 2009-2010 Politecnico di Torino, Italy,
+ * TORSEC group -- http://security.polito.it
*
- * Author: Mimi Zohar <zo...@us...>
+ * Authors:
+ * Mimi Zohar <zo...@us...>
+ * Roberto Sassu <rob...@po...>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -171,7 +175,13 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
struct inode *inode = file->f_dentry->d_inode;
struct ima_template_entry *entry;
int violation = 0;
-
+ char *subj_label = NULL;
+ char *obj_label = NULL;
+ int obj_label_len = 0;
+ int subj_label_len = 0;
+ struct task_struct *tsk = current;
+ u32 osid, sid;
+
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
@@ -181,6 +191,22 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
memset(&entry->template, 0, sizeof(entry->template));
memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE);
strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
+
+ if (file->f_dentry->d_inode) {
+ security_inode_getsecid(file->f_dentry->d_inode, &osid);
+ if (!security_secid_to_secctx(osid, &obj_label, &obj_label_len)) {
+ strncpy(entry->template.obj_label, obj_label, obj_label_len < IMA_LABEL_LEN_MAX ?
+ obj_label_len : IMA_LABEL_LEN_MAX);
+ security_release_secctx(obj_label, obj_label_len);
+ }
+ }
+
+ security_task_getsecid(tsk, &sid);
+ if (!security_secid_to_secctx(sid, &subj_label, &subj_label_len)) {
+ strncpy(entry->template.subj_label, subj_label, subj_label_len < IMA_LABEL_LEN_MAX ?
+ subj_label_len : IMA_LABEL_LEN_MAX);
+ security_release_secctx(subj_label, subj_label_len);
+ }
result = ima_store_template(entry, violation, inode);
if (!result)
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 46642a1..9f1dc9b 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -96,9 +96,19 @@ int ima_calc_template_hash(int template_len, void *template, char *digest)
rc = init_desc(&desc);
if (rc != 0)
return rc;
+
+ sg_init_table(sg, 1);
- sg_init_one(sg, template, template_len);
- rc = crypto_hash_update(&desc, sg, template_len);
+ sg_set_buf(sg, template, IMA_REPORT_FORMAT_CURRENT_LEN);
+ rc = crypto_hash_update(&desc, sg, IMA_REPORT_FORMAT_CURRENT_LEN);
+ if (ima_format == IMA_REPORT_FORMAT_CURRENT)
+ goto hash_final;
+
+ sg_set_buf(sg, template + IMA_REPORT_FORMAT_CURRENT_LEN,
+ IMA_REPORT_FORMAT_NG_LEN - IMA_REPORT_FORMAT_CURRENT_LEN);
+ rc = crypto_hash_update(&desc, sg, IMA_REPORT_FORMAT_NG_LEN - IMA_REPORT_FORMAT_CURRENT_LEN);
+
+hash_final:
if (!rc)
rc = crypto_hash_final(&desc, digest);
crypto_free_hash(desc.tfm);
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 0c72c9c..a6c0f0a 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -1,10 +1,13 @@
/*
* Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ * Copyright (C) 2009-2010 Politecnico di Torino, Italy,
+ * TORSEC group -- http://security.polito.it
*
* Authors:
* Kylene Hall <kj...@us...>
* Reiner Sailer <sa...@us...>
* Mimi Zohar <zo...@us...>
+ * Roberto Sassu <rob...@po...>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -26,6 +29,18 @@
static int valid_policy = 1;
#define TMPBUFLEN 12
+
+int ima_format = IMA_REPORT_FORMAT_CURRENT;
+
+static int __init ima_report_format_setup(char *str)
+{
+ if (strncmp(str, "ima-ng", 6) == 0)
+ ima_format = IMA_REPORT_FORMAT_NG;
+ return 1;
+}
+__setup("ima_report_format=", ima_report_format_setup);
+
+
static ssize_t ima_show_htable_value(char __user *buf, size_t count,
loff_t *ppos, atomic_long_t *val)
{
@@ -177,11 +192,20 @@ void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show)
{
struct ima_template_data *entry = e;
int namelen;
-
+ int obj_label_len = strlen(entry->obj_label);
+ int subj_label_len = strlen(entry->subj_label);
+
switch (show) {
case IMA_SHOW_ASCII:
ima_print_digest(m, entry->digest);
- seq_printf(m, " %s\n", entry->file_name);
+ seq_printf(m, " %s", entry->file_name);
+ if (ima_format == IMA_REPORT_FORMAT_NG) {
+ if (subj_label_len)
+ seq_printf(m, " %s", entry->subj_label);
+ if (obj_label_len)
+ seq_printf(m, " %s", entry->obj_label);
+ }
+ seq_printf(m, "\n");
break;
case IMA_SHOW_BINARY:
ima_putc(m, entry->digest, IMA_DIGEST_SIZE);
@@ -189,6 +213,14 @@ void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show)
namelen = strlen(entry->file_name);
ima_putc(m, &namelen, sizeof namelen);
ima_putc(m, entry->file_name, namelen);
+ if (ima_format == IMA_REPORT_FORMAT_NG) {
+ ima_putc(m, &subj_label_len, sizeof subj_label_len);
+ if (subj_label_len)
+ ima_putc(m, entry->subj_label, subj_label_len);
+ ima_putc(m, &obj_label_len, sizeof obj_label_len);
+ if (obj_label_len)
+ ima_putc(m, entry->obj_label, obj_label_len);
+ }
default:
break;
}
|
|
From: Mimi Z. <zo...@li...> - 2010-04-18 03:15:36
|
On Sat, 2010-04-17 at 12:22 -0400, Eric Paris wrote:
> On Fri, Apr 16, 2010 at 11:12 AM, Roberto Sassu <rob...@po...> wrote:
> > On Thursday 15 April 2010 00:20:00 Mimi Zohar wrote:
> >> On Wed, 2010-04-14 at 15:32 -0400, Eric Paris wrote:
> >> > On Wed, Apr 14, 2010 at 5:51 AM, Roberto Sassu <rob...@po...> wrote:
> >> > > Description of the issue:
> >> >
> >> > > The parsing function is used only when custom rules must be loaded to replace
> >> > > the default ones, but a different behavior can be observed in respect to the
> >> > > first case: only one element is allocated and it is populated by the parsing
> >> > > function that recognizes the tokens ' ' and '\n'.
> >> > > So, having multiple lines in the file passed through the exported interface
> >> > > doesn't lead to the same number of rules in the list, since only one allocated
> >> > > item is available. If a directive spans two different lines, only the last
> >> > > value is taken and the first one is overwritten.
> >> >
> >> > I admit I haven't looked at the loading code before and it does seem
> >> > 'special.' It looks to me on first glance like the kernel accepts
> >> > one rule per write() rather than one rule per line. If you send it
> >> > two rules in a single write you are going to get a rather
> >> > unpredictable result.
> >>
> >> Similar to smack, one rule per write. Keeps it nice and simple.
> >>
> >> > Your change is a good start to allow single writes which contain
> >> > multiple rules. I'm guessing that's a good idea, I though I think the
> >> > parser should get a little smarter. Does it ever make sense to have 2
> >> > actions in a single rule, with the last one winning? You also added
> >> > support for some sort of commenting in the rule set didn't you? That
> >> > probably needs to be a lot stronger too....
> >> >
> >> > I'm not acking or nacking here, just trying to understand exactly the
> >> > problem we are trying to solve. Loading rules using
> >> >
> >> > cat rule > /sys/kernel/security/ima/policy
> >> >
> >> > seems like a good direction to head.
> >>
> >> hm, I was under the impression we wanted to minimize any
> >> policy/configuration parsing done in the kernel.
> >>
> >
> > In my thinking, actually the behaviour of the code that loads the policy through the /sys interface
> > is different from the one that handles hardcoded rules. In the last case these are stored as array of structures
> > and each element is added to the list by the "list_add_tail" function. I past here the few lines of the code
> > involved:
> >
> > void __init ima_init_policy(void)
> > {
> > int i, entries;
> >
> > /* if !ima_use_tcb set entries = 0 so we load NO default rules */
> > if (ima_use_tcb)
> > entries = ARRAY_SIZE(default_rules);
> > else
> > entries = 0;
> >
> > for (i = 0; i < entries; i++)
> > list_add_tail(&default_rules[i].list, &measure_default_rules);
> > ima_measure = &measure_default_rules;
> > }
>
> You get the same behaviour with your loaded rules if you load them the
> 'right' way (which is non-obvious, IMHO) You need to
>
> open(sysfs file)
> write(rule one)
> write(rule two)
> write(rule three)
> write(rule four)
> close(sysfs_file)
>
> I'm guessing you used cat file > sysfs_file which resulted in
>
> open(sysfs_file)
> write(rule one rule two rule th);
> write(ree rule four)
> close(sysfs_file)
>
> Which resulted in the crap behaviour you got. I suggested to Mimi off
> list that maybe the best solution would be to change the parser a
> little such that we stop parsing on \n on return a short write equal
> to the length of the one rule we parsed. Thus the way cat handles
> things we would get:
>
Sorry, definitely should have documented it. The IMA ltp testsuite
contains an example of loading a policy.
(<ltp>/testcases/kernel/security/integrity/ima/tests/ima_policy.sh)
> open(sysfs_file)
> write(rule one rule two rule_th)
> which would return 8 (length of "rule one") so cat would next try
> write (rule two rule three rul)
> which would return 8 (length of "rule two") so cat would next try
> write (rule three rule four)
> which would return 10 (length of "rule three") so cat would next try
> write (rule four)
> which would return a full write 9 (length of "rule four)
> close (sysfs_file)
>
> I think that solves the problem you were trying to suggest by relying
> on a properly implemented userspace.
>
> Mimi suggest we also add parsing for comments, which I'm ok with.
I mentioned using 'cat' to load a policy containing comments could cause
problems, as it isn't a rule. The current code would probably reject the
entire policy, thinking the comment was an invalid rule.
> I'm also think if we go this way we should check 2 other things:
>
> 1) make sure that we never have the same options set twice (aka can't
> set action to both measure and don't measure in the same rule)
Agreed, as only the last one is used.
> 2) make sure that rules ALWAYS end in \n, so if userspace doesn't
> write the full rule we have some clue and can reject it.
>
> I don't know if #2 is backwards compatible with how whatever utility
> IBM uses to loads rules works, but seeing as how noone else has hit
> this until now, I'm guess it can't bite many people in the rump.....
>
> -Eric
The assumption was one rule per line.
Mimi
|