linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH 0/6] ima: support per-measurement templates
@ 2013-11-07 15:49 Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 1/6] ima: connect defined IMA templates through a linked list Roberto Sassu
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Roberto Sassu @ 2013-11-07 15:49 UTC (permalink / raw)
  To: linux-security-module
  Cc: linux-kernel, linux-ima-devel, zohar, d.kasatkin, james.l.morris,
	Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 3409 bytes --]

Hi everyone

one functionality that is missing in the new template management mechanism
is the possibility to specify a custom template format per-measurement entry.
Until now, once the template is determined from the kernel configuration
or from the kernel command line parameters 'ima_template' and ima_template_fmt',
this template is used to generate all measurements entries in the list.

However, it is desirable to differentiate information included in measurement
entries depending on the event type from which they are generated. To explain
the usefulness of the proposed modification, I'll make an example.

One feature coming soon is the addition of new template fields that represent
LSM labels applied either to the current process and to the inode being
measured. However, these information are not enough to capture the mapping
between the executable code loaded for a given subject. Indeed, for example
in SELinux, a type transition may occur if the type of the current process
and the type of the inode being executed are matched in a 'type_transition'
policy rule. In this case, the code should be mapped not to the label of the
current process but instead to the label in the credentials (stored in the
'linux_binprm' structure) being installed during the execution of the execve()
system call.

To correctly perform the mapping code - LSM label, it is needed to introduce
a new template field to represent the LSM label in the 'linux_binprm' structure
(e.g. with identifier 'bprm-label') and a new IMA policy action
(e.g. measure_log_all) to record a measurement for every event that match
rule criteria, although the accessed inode has already been measured. Then,
assuming that the format of the default template is "d-ng|n-ng|subj|obj"
(digest + hash algo, long event name, subject LSM label, object LSM label),
the policy to capture the mapping should be:

---
measure_log_all func=BPRM_CHECK mask=MAY_EXEC \
    ima_template_fmt=d-ng|n-ng|subj|obj|lsm-label
measure_log_all func=FILE_MMAP mask=MAY_EXEC
---

In the first rule, the default template is overridden with a template that
contains the label stored in the 'linux_binprm' structure. Thus, in the
resulting measurements list, all entries that record the execution of binaries
will include the additional template field, while those generated from the
mapping into memory of shared libraries will contain only fields listed
in the default template.

Roberto Sassu


Roberto Sassu (6):
  ima: connect defined IMA templates through a linked list
  ima: added new template helper lookup_template_desc_by_fmt()
  ima: added ima_get_template_desc() for templates dynamic registration
  ima: replace ima_template_desc_current() with ima_get_template_desc()
  ima: added ima_template and ima_template_fmt new policy options
  ima: use custom template obtained from a matched policy rule

 Documentation/ABI/testing/ima_policy     |  6 ++-
 Documentation/security/IMA-templates.txt | 19 +++++----
 security/integrity/ima/ima.h             | 14 ++++---
 security/integrity/ima/ima_api.c         | 22 +++++++----
 security/integrity/ima/ima_init.c        |  2 +-
 security/integrity/ima/ima_main.c        | 13 +++++--
 security/integrity/ima/ima_policy.c      | 52 ++++++++++++++++++++++++-
 security/integrity/ima/ima_template.c    | 67 +++++++++++++++++++++++++++++---
 8 files changed, 161 insertions(+), 34 deletions(-)

-- 
1.8.1.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC][PATCH 1/6] ima: connect defined IMA templates through a linked list
  2013-11-07 15:49 [RFC][PATCH 0/6] ima: support per-measurement templates Roberto Sassu
@ 2013-11-07 15:49 ` Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 2/6] ima: added new template helper lookup_template_desc_by_fmt() Roberto Sassu
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2013-11-07 15:49 UTC (permalink / raw)
  To: linux-security-module
  Cc: linux-kernel, linux-ima-devel, zohar, d.kasatkin, james.l.morris,
	Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 1612 bytes --]

This patch connects defined templates through a linked list so that it
will be possible to append new descriptors when the functionality
of specifying a custom template in the policy will be introduced.
Template search by name is still performed by iterating over
'defined_templates' array items.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
 security/integrity/ima/ima.h          | 1 +
 security/integrity/ima/ima_template.c | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index bf03c6a..5cbe881 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -67,6 +67,7 @@ struct ima_template_field {
 
 /* IMA template descriptor definition */
 struct ima_template_desc {
+	struct list_head list;
 	char *name;
 	char *fmt;
 	int num_fields;
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 5a95d06..33c911a 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -204,6 +204,7 @@ static int init_defined_templates(void)
 	int result = 0;
 
 	/* Init defined templates. */
+	INIT_LIST_HEAD(&defined_templates[0].list);
 	for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
 		struct ima_template_desc *template = &defined_templates[i];
 
@@ -219,6 +220,10 @@ static int init_defined_templates(void)
 			       template->name : template->fmt), result);
 			return result;
 		}
+
+		if (i > 0)
+			list_add_tail(&defined_templates[i].list,
+				      &defined_templates[0].list);
 	}
 	return result;
 }
-- 
1.8.1.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC][PATCH 2/6] ima: added new template helper lookup_template_desc_by_fmt()
  2013-11-07 15:49 [RFC][PATCH 0/6] ima: support per-measurement templates Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 1/6] ima: connect defined IMA templates through a linked list Roberto Sassu
@ 2013-11-07 15:49 ` Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 3/6] ima: added ima_get_template_desc() for templates dynamic registration Roberto Sassu
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2013-11-07 15:49 UTC (permalink / raw)
  To: linux-security-module
  Cc: linux-kernel, linux-ima-devel, zohar, d.kasatkin, james.l.morris,
	Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 2456 bytes --]

This patch adds a new helper to search a template descriptor by its format.
Also, the old function lookup_template_desc(), which performs the search
by name, has been renamed to lookup_template_desc_by_name().

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
 security/integrity/ima/ima_template.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 33c911a..c849723 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -38,7 +38,7 @@ static struct ima_template_field supported_fields[] = {
 };
 
 static struct ima_template_desc *ima_template;
-static struct ima_template_desc *lookup_template_desc(const char *name);
+static struct ima_template_desc *lookup_template_desc_by_name(const char *name);
 static struct ima_template_field *lookup_template_field(const char *field_id);
 
 static int __init ima_template_setup(char *str)
@@ -53,7 +53,7 @@ static int __init ima_template_setup(char *str)
 	 * Verify that a template with the supplied name exists.
 	 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
 	 */
-	template_desc = lookup_template_desc(str);
+	template_desc = lookup_template_desc_by_name(str);
 	if (!template_desc) {
 		pr_err("IMA: template %s not found, using %s\n",
 		       str, CONFIG_IMA_DEFAULT_TEMPLATE);
@@ -117,7 +117,7 @@ static int __init ima_template_fmt_setup(char *str)
 }
 __setup("ima_template_fmt=", ima_template_fmt_setup);
 
-static struct ima_template_desc *lookup_template_desc(const char *name)
+static struct ima_template_desc *lookup_template_desc_by_name(const char *name)
 {
 	int i;
 
@@ -129,6 +129,18 @@ static struct ima_template_desc *lookup_template_desc(const char *name)
 	return NULL;
 }
 
+static struct ima_template_desc *lookup_template_desc_by_fmt(const char *fmt)
+{
+	struct ima_template_desc *desc;
+
+	list_for_each_entry(desc, &defined_templates[0].list, list) {
+		if (strcmp(desc->fmt, fmt) == 0)
+			return desc;
+	}
+
+	return NULL;
+}
+
 static struct ima_template_field *lookup_template_field(const char *field_id)
 {
 	int i;
@@ -232,7 +244,7 @@ struct ima_template_desc *ima_template_desc_current(void)
 {
 	if (!ima_template)
 		ima_template =
-		    lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE);
+		    lookup_template_desc_by_name(CONFIG_IMA_DEFAULT_TEMPLATE);
 	return ima_template;
 }
 
-- 
1.8.1.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC][PATCH 3/6] ima: added ima_get_template_desc() for templates dynamic registration
  2013-11-07 15:49 [RFC][PATCH 0/6] ima: support per-measurement templates Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 1/6] ima: connect defined IMA templates through a linked list Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 2/6] ima: added new template helper lookup_template_desc_by_fmt() Roberto Sassu
@ 2013-11-07 15:49 ` Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 4/6] ima: replace ima_template_desc_current() with ima_get_template_desc() Roberto Sassu
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2013-11-07 15:49 UTC (permalink / raw)
  To: linux-security-module
  Cc: linux-kernel, linux-ima-devel, zohar, d.kasatkin, james.l.morris,
	Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 2684 bytes --]

This patch introduces the ima_get_template_desc() function which returns
a template descriptor depending on the template name and format passed
as arguments. If the first argument is not NULL, the new function
searches an existing template descriptor by name among those defined
and returns it to the caller. Instead, if the second argument is not
NULL and the first is NULL, it does a template lookup by format and,
if not found, creates a new one before returning the pointer to the
caller. Finally, if both arguments are NULL or the template creation
failed, it returns the default template descriptor.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
 security/integrity/ima/ima.h          |  2 ++
 security/integrity/ima/ima_template.c | 40 +++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 5cbe881..d7b4c19 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -107,6 +107,8 @@ int ima_init_crypto(void);
 void ima_putc(struct seq_file *m, void *data, int datalen);
 void ima_print_digest(struct seq_file *m, u8 *digest, int size);
 struct ima_template_desc *ima_template_desc_current(void);
+struct ima_template_desc *ima_get_template_desc(char *template_name,
+						char *template_fmt);
 int ima_init_template(void);
 
 int ima_init_template(void);
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index c849723..7daf2ba 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -248,6 +248,46 @@ struct ima_template_desc *ima_template_desc_current(void)
 	return ima_template;
 }
 
+struct ima_template_desc *ima_get_template_desc(char *template_name,
+						char *template_fmt)
+{
+	struct ima_template_desc *desc = NULL;
+	int result;
+
+	if (template_name == NULL && template_fmt == NULL)
+		goto out;
+
+	if (template_name) {
+		desc = lookup_template_desc_by_name(template_name);
+	} else {
+		desc = lookup_template_desc_by_fmt(template_fmt);
+		if (desc == NULL) {
+			desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+			if (desc == NULL)
+				goto out;
+		}
+		desc->name = "";
+		desc->fmt = kstrdup(template_fmt, GFP_KERNEL);
+		if (desc->fmt == NULL)
+			goto out_free;
+
+		result = template_desc_init_fields(desc->fmt, &(desc->fields),
+						   &(desc->num_fields));
+		if (result < 0)
+			goto out_free_fmt;
+	}
+out:
+	if (desc == NULL)
+		desc = ima_template_desc_current();
+	return desc;
+out_free_fmt:
+	kfree(desc->fmt);
+out_free:
+	kfree(desc);
+	desc = NULL;
+	goto out;
+}
+
 int ima_init_template(void)
 {
 	int result;
-- 
1.8.1.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC][PATCH 4/6] ima: replace ima_template_desc_current() with ima_get_template_desc()
  2013-11-07 15:49 [RFC][PATCH 0/6] ima: support per-measurement templates Roberto Sassu
                   ` (2 preceding siblings ...)
  2013-11-07 15:49 ` [RFC][PATCH 3/6] ima: added ima_get_template_desc() for templates dynamic registration Roberto Sassu
@ 2013-11-07 15:49 ` Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 5/6] ima: added ima_template and ima_template_fmt new policy options Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 6/6] ima: use custom template obtained from a matched policy rule Roberto Sassu
  5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2013-11-07 15:49 UTC (permalink / raw)
  To: linux-security-module
  Cc: linux-kernel, linux-ima-devel, zohar, d.kasatkin, james.l.morris,
	Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 3736 bytes --]

This patch replaces calls to ima_template_desc_current() in ima_api.c
and ima_main.c with ima_get_template_desc() as the former function
is called by the latter when passed arguments are both NULL. The patch
also declares the former function as static so that it will not be
longer available outside ima_template.c.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
 security/integrity/ima/ima.h          | 1 -
 security/integrity/ima/ima_api.c      | 3 ++-
 security/integrity/ima/ima_main.c     | 6 ++++--
 security/integrity/ima/ima_template.c | 2 +-
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index d7b4c19..f72c488 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -106,7 +106,6 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 int ima_init_crypto(void);
 void ima_putc(struct seq_file *m, void *data, int datalen);
 void ima_print_digest(struct seq_file *m, u8 *digest, int size);
-struct ima_template_desc *ima_template_desc_current(void);
 struct ima_template_desc *ima_get_template_desc(char *template_name,
 						char *template_fmt);
 int ima_init_template(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 0e75408..f10328d 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -29,9 +29,10 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
 			    struct evm_ima_xattr_data *xattr_value,
 			    int xattr_len, struct ima_template_entry **entry)
 {
-	struct ima_template_desc *template_desc = ima_template_desc_current();
+	struct ima_template_desc *template_desc;
 	int i, result = 0;
 
+	template_desc = ima_get_template_desc(NULL, NULL);
 	*entry = kzalloc(sizeof(**entry) + template_desc->num_fields *
 			 sizeof(struct ima_field_data), GFP_NOFS);
 	if (!*entry)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 149ee11..6e1d3db 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -41,12 +41,13 @@ static int hash_setup_done;
 
 static int __init hash_setup(char *str)
 {
-	struct ima_template_desc *template_desc = ima_template_desc_current();
+	struct ima_template_desc *template_desc;
 	int i;
 
 	if (hash_setup_done)
 		return 1;
 
+	template_desc = ima_get_template_desc(NULL, NULL);
 	if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
 		if (strncmp(str, "sha1", 4) == 0)
 			ima_hash_algo = HASH_ALGO_SHA1;
@@ -166,7 +167,7 @@ static int process_measurement(struct file *file, const char *filename,
 {
 	struct inode *inode = file_inode(file);
 	struct integrity_iint_cache *iint;
-	struct ima_template_desc *template_desc = ima_template_desc_current();
+	struct ima_template_desc *template_desc;
 	char *pathbuf = NULL;
 	const char *pathname = NULL;
 	int rc = -ENOMEM, action, must_appraise, _func;
@@ -210,6 +211,7 @@ static int process_measurement(struct file *file, const char *filename,
 		goto out_digsig;
 	}
 
+	template_desc = ima_get_template_desc(NULL, NULL);
 	if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
 		if (action & IMA_APPRAISE_SUBMASK)
 			xattr_ptr = &xattr_value;
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 7daf2ba..f66e06d 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -240,7 +240,7 @@ static int init_defined_templates(void)
 	return result;
 }
 
-struct ima_template_desc *ima_template_desc_current(void)
+static struct ima_template_desc *ima_template_desc_current(void)
 {
 	if (!ima_template)
 		ima_template =
-- 
1.8.1.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC][PATCH 5/6] ima: added ima_template and ima_template_fmt new policy options
  2013-11-07 15:49 [RFC][PATCH 0/6] ima: support per-measurement templates Roberto Sassu
                   ` (3 preceding siblings ...)
  2013-11-07 15:49 ` [RFC][PATCH 4/6] ima: replace ima_template_desc_current() with ima_get_template_desc() Roberto Sassu
@ 2013-11-07 15:49 ` Roberto Sassu
  2013-11-07 15:49 ` [RFC][PATCH 6/6] ima: use custom template obtained from a matched policy rule Roberto Sassu
  5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2013-11-07 15:49 UTC (permalink / raw)
  To: linux-security-module
  Cc: linux-kernel, linux-ima-devel, zohar, d.kasatkin, james.l.morris,
	Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 6973 bytes --]

This patch adds the support for 'ima_template' and 'ima_template_fmt'
policy options. They allow to define which template and, thus, which
information should be included in measurements entries generated from
events that match other rules' criteria.

With this feature, it is possible to include for each measurement entry
only relevant information. For example, while measurements that report
the execution of the execve() system call may contain the credentials
being installed on the current process (stored in the 'cred' field of the
'linux_binprm' structure), others should not include it (also because
the pointer to the above structure is not available from other IMA hooks).

A sample policy to produce measurements the way is described above may be:

---
measure func=BPRM_CHECK mask=MAY_EXEC ima_template_fmt=d-ng|n-ng|bprm-type
measure func=FILE_MMAP mask=MAY_EXEC
---

where 'bprm-type' is the identifier of a field (whose code is not yet
upstreamed) which displays the type part of a LSM label from credentials
stored in the 'linux_binprm' structure.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
 Documentation/ABI/testing/ima_policy     |  6 ++++-
 Documentation/security/IMA-templates.txt | 19 ++++++++------
 security/integrity/ima/ima_policy.c      | 45 +++++++++++++++++++++++++++++++-
 3 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index f1c5cc9..7fbe47d 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -23,7 +23,7 @@ Description:
 				 [fowner]]
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
 				 [obj_user=] [obj_role=] [obj_type=]]
-			option:	[[appraise_type=]]
+			option:	[[appraise_type=] [ima_template=] [ima_template_fmt=]]
 
 		base: 	func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
 			mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
@@ -33,6 +33,10 @@ Description:
 			fowner:=decimal value
 		lsm:  	are LSM specific
 		option:	appraise_type:= [imasig]
+			ima_template:= an already defined template
+			ima_template_fmt:= a custom template format
+					   (see Documentation/security/IMA-templates.txt
+					   for more details)
 
 		default policy:
 			# PROC_SUPER_MAGIC
diff --git a/Documentation/security/IMA-templates.txt b/Documentation/security/IMA-templates.txt
index 08ea2da..61d9f0d 100644
--- a/Documentation/security/IMA-templates.txt
+++ b/Documentation/security/IMA-templates.txt
@@ -36,13 +36,14 @@ from the set of the supported ones.
 After the initialization step, IMA will call ima_alloc_init_template()
 (new function defined within the patches for the new template management
 mechanism) to generate a new measurement entry by using the template
-descriptor chosen through the kernel configuration or through the newly
-introduced 'ima_template' and 'ima_template_fmt' kernel command line parameters.
-It is during this phase that the advantages of the new architecture are
-clearly shown: the latter function will not contain specific code to handle
-a given template but, instead, it simply calls the init() method of the template
-fields associated to the chosen template descriptor and store the result
-(pointer to allocated data and data length) in the measurement entry structure.
+descriptor chosen through the kernel configuration, the newly introduced
+'ima_template' and 'ima_template_fmt' kernel command line parameters and
+new policy options with the same names. It is during this phase that the
+advantages of the new architecture are clearly shown: the latter function
+will not contain specific code to handle a given template but, instead, it
+simply calls the init() method of the template fields associated to the
+chosen template descriptor and store the result (pointer to allocated data
+and data length) in the measurement entry structure.
 
 The same mechanism is employed to display measurements entries.
 The functions ima[_ascii]_measurements_show() retrieve, for each entry,
@@ -83,4 +84,6 @@ currently the following methods are supported:
  - specify a template descriptor name from the kernel command line through
    the 'ima_template=' parameter;
  - register a new template descriptor with custom format through the kernel
-   command line parameter 'ima_template_fmt='.
+   command line parameter 'ima_template_fmt=';
+ - provide desired template name or custom format for specific events through
+   the new policy options 'ima_template=' and 'ima_template_fmt='.
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index a9c3d3c..df852ec 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -50,6 +50,8 @@ struct ima_rule_entry {
 	u8 fsuuid[16];
 	kuid_t uid;
 	kuid_t fowner;
+	char *template_name;
+	char *template_fmt;
 	struct {
 		void *rule;	/* LSM file metadata specific */
 		void *args_p;	/* audit value */
@@ -351,7 +353,8 @@ enum {
 	Opt_obj_user, Opt_obj_role, Opt_obj_type,
 	Opt_subj_user, Opt_subj_role, Opt_subj_type,
 	Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
-	Opt_appraise_type, Opt_fsuuid
+	Opt_appraise_type, Opt_fsuuid,
+	Opt_ima_template, Opt_ima_template_fmt
 };
 
 static match_table_t policy_tokens = {
@@ -373,6 +376,8 @@ static match_table_t policy_tokens = {
 	{Opt_uid, "uid=%s"},
 	{Opt_fowner, "fowner=%s"},
 	{Opt_appraise_type, "appraise_type=%s"},
+	{Opt_ima_template, "ima_template=%s"},
+	{Opt_ima_template_fmt, "ima_template_fmt=%s"},
 	{Opt_err, NULL}
 };
 
@@ -421,6 +426,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 	entry->action = UNKNOWN;
 	while ((p = strsep(&rule, " \t")) != NULL) {
 		substring_t args[MAX_OPT_ARGS];
+		struct ima_template_desc *desc;
 		int token;
 		unsigned long lnum;
 
@@ -621,6 +627,43 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			else
 				result = -EINVAL;
 			break;
+		case Opt_ima_template:
+			ima_log_string(ab, "ima_template", args[0].from);
+
+			if (entry->template_name || entry->template_fmt) {
+				result = -EINVAL;
+				break;
+			}
+
+			desc = ima_get_template_desc(args[0].from, NULL);
+			if (strcmp(desc->name, args[0].from) != 0) {
+				result = -EINVAL;
+				break;
+			}
+
+			entry->template_name = kstrdup(args[0].from,
+						       GFP_KERNEL);
+			if (!entry->template_name)
+				result = -EINVAL;
+			break;
+		case Opt_ima_template_fmt:
+			ima_log_string(ab, "ima_template_fmt", args[0].from);
+
+			if (entry->template_fmt || entry->template_name) {
+				result = -EINVAL;
+				break;
+			}
+
+			desc = ima_get_template_desc(NULL, args[0].from);
+			if (strcmp(desc->fmt, args[0].from) != 0) {
+				result = -EINVAL;
+				break;
+			}
+
+			entry->template_fmt = kstrdup(args[0].from, GFP_KERNEL);
+			if (!entry->template_fmt)
+				result = -EINVAL;
+			break;
 		case Opt_err:
 			ima_log_string(ab, "UNKNOWN", p);
 			result = -EINVAL;
-- 
1.8.1.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC][PATCH 6/6] ima: use custom template obtained from a matched policy rule
  2013-11-07 15:49 [RFC][PATCH 0/6] ima: support per-measurement templates Roberto Sassu
                   ` (4 preceding siblings ...)
  2013-11-07 15:49 ` [RFC][PATCH 5/6] ima: added ima_template and ima_template_fmt new policy options Roberto Sassu
@ 2013-11-07 15:49 ` Roberto Sassu
  5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2013-11-07 15:49 UTC (permalink / raw)
  To: linux-security-module
  Cc: linux-kernel, linux-ima-devel, zohar, d.kasatkin, james.l.morris,
	Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 8518 bytes --]

This patch modifies existing IMA functions to retrieve the template name
or format specified in a matched policy rule and provide it to
ima_alloc_init_template(). The latter calls ima_get_template_desc()
to obtain the template descriptor to use for creating a new measurement
entry.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
 security/integrity/ima/ima.h        | 10 ++++++----
 security/integrity/ima/ima_api.c    | 23 ++++++++++++++---------
 security/integrity/ima/ima_init.c   |  2 +-
 security/integrity/ima/ima_main.c   |  9 ++++++---
 security/integrity/ima/ima_policy.c |  7 ++++++-
 5 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index f72c488..bc7668d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -130,7 +130,8 @@ static inline unsigned long ima_hash_key(u8 *digest)
 }
 
 /* LIM API function definitions */
-int ima_get_action(struct inode *inode, int mask, int function);
+int ima_get_action(struct inode *inode, int mask, int function,
+		   char **template_name, char **template_fmt);
 int ima_must_measure(struct inode *inode, int mask, int function);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
 			    struct file *file,
@@ -139,13 +140,14 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
 			   const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
-			   int xattr_len);
+			   int xattr_len, struct ima_template_desc *desc);
 void ima_audit_measurement(struct integrity_iint_cache *iint,
 			   const unsigned char *filename);
 int ima_alloc_init_template(struct integrity_iint_cache *iint,
 			    struct file *file, const unsigned char *filename,
 			    struct evm_ima_xattr_data *xattr_value,
-			    int xattr_len, struct ima_template_entry **entry);
+			    int xattr_len, struct ima_template_desc *desc,
+			    struct ima_template_entry **entry);
 int ima_store_template(struct ima_template_entry *entry, int violation,
 		       struct inode *inode, const unsigned char *filename);
 const char *ima_d_path(struct path *path, char **pathbuf);
@@ -160,7 +162,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, POST_SETATTR };
 
 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
-		     int flags);
+		     int flags, char **template_name, char **template_fmt);
 void ima_init_policy(void);
 void ima_update_policy(void);
 ssize_t ima_parse_add_rule(char *);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index f10328d..da70074 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -27,12 +27,15 @@
 int ima_alloc_init_template(struct integrity_iint_cache *iint,
 			    struct file *file, const unsigned char *filename,
 			    struct evm_ima_xattr_data *xattr_value,
-			    int xattr_len, struct ima_template_entry **entry)
+			    int xattr_len, struct ima_template_desc *desc,
+			    struct ima_template_entry **entry)
 {
-	struct ima_template_desc *template_desc;
+	struct ima_template_desc *template_desc = desc;
 	int i, result = 0;
 
-	template_desc = ima_get_template_desc(NULL, NULL);
+	if (template_desc == NULL)
+		template_desc = ima_get_template_desc(NULL, NULL);
+
 	*entry = kzalloc(sizeof(**entry) + template_desc->num_fields *
 			 sizeof(struct ima_field_data), GFP_NOFS);
 	if (!*entry)
@@ -127,7 +130,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 	atomic_long_inc(&ima_htable.violations);
 
 	result = ima_alloc_init_template(NULL, file, filename,
-					 NULL, 0, &entry);
+					 NULL, 0, NULL, &entry);
 	if (result < 0) {
 		result = -ENOMEM;
 		goto err_out;
@@ -156,19 +159,21 @@ err_out:
  * Returns IMA_MEASURE, IMA_APPRAISE mask.
  *
  */
-int ima_get_action(struct inode *inode, int mask, int function)
+int ima_get_action(struct inode *inode, int mask, int function,
+		   char **template_name, char **template_fmt)
 {
 	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
 
 	if (!ima_appraise)
 		flags &= ~IMA_APPRAISE;
 
-	return ima_match_policy(inode, function, mask, flags);
+	return ima_match_policy(inode, function, mask, flags,
+				template_name, template_fmt);
 }
 
 int ima_must_measure(struct inode *inode, int mask, int function)
 {
-	return ima_match_policy(inode, function, mask, IMA_MEASURE);
+	return ima_match_policy(inode, function, mask, IMA_MEASURE, NULL, NULL);
 }
 
 /*
@@ -245,7 +250,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 void ima_store_measurement(struct integrity_iint_cache *iint,
 			   struct file *file, const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
-			   int xattr_len)
+			   int xattr_len, struct ima_template_desc *desc)
 {
 	const char *op = "add_template_measure";
 	const char *audit_cause = "ENOMEM";
@@ -258,7 +263,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
 		return;
 
 	result = ima_alloc_init_template(iint, file, filename,
-					 xattr_value, xattr_len, &entry);
+					 xattr_value, xattr_len, desc, &entry);
 	if (result < 0) {
 		integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
 				    op, audit_cause, result, 0);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 15f34bd..8059ec9 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -69,7 +69,7 @@ static void __init ima_add_boot_aggregate(void)
 	}
 
 	result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
-					 NULL, 0, &entry);
+					 NULL, 0, NULL, &entry);
 	if (result < 0)
 		return;
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 6e1d3db..d1f372e 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -172,6 +172,7 @@ static int process_measurement(struct file *file, const char *filename,
 	const char *pathname = NULL;
 	int rc = -ENOMEM, action, must_appraise, _func;
 	struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
+	char *custom_template_name = NULL, *custom_template_fmt = NULL;
 	int xattr_len = 0;
 
 	if (!ima_initialized || !S_ISREG(inode->i_mode))
@@ -181,7 +182,8 @@ static int process_measurement(struct file *file, const char *filename,
 	 * bitmask based on the appraise/audit/measurement policy.
 	 * Included is the appraise submask.
 	 */
-	action = ima_get_action(inode, mask, function);
+	action = ima_get_action(inode, mask, function,
+				&custom_template_name, &custom_template_fmt);
 	if (!action)
 		return 0;
 
@@ -211,7 +213,8 @@ static int process_measurement(struct file *file, const char *filename,
 		goto out_digsig;
 	}
 
-	template_desc = ima_get_template_desc(NULL, NULL);
+	template_desc = ima_get_template_desc(custom_template_name,
+					      custom_template_fmt);
 	if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
 		if (action & IMA_APPRAISE_SUBMASK)
 			xattr_ptr = &xattr_value;
@@ -228,7 +231,7 @@ static int process_measurement(struct file *file, const char *filename,
 
 	if (action & IMA_MEASURE)
 		ima_store_measurement(iint, file, pathname,
-				      xattr_value, xattr_len);
+				      xattr_value, xattr_len, template_desc);
 	if (action & IMA_APPRAISE_SUBMASK)
 		rc = ima_appraise_measurement(_func, iint, file, pathname,
 					      xattr_value, xattr_len);
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index df852ec..fee3dc1 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -261,7 +261,7 @@ static int get_subaction(struct ima_rule_entry *rule, int func)
  * change.)
  */
 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
-		     int flags)
+		     int flags, char **template_name, char **template_fmt)
 {
 	struct ima_rule_entry *entry;
 	int action = 0, actmask = flags | (flags << 1);
@@ -274,6 +274,11 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
 		if (!ima_match_rules(entry, inode, func, mask))
 			continue;
 
+		if (template_name)
+			*template_name = entry->template_name;
+		if (template_fmt)
+			*template_fmt = entry->template_fmt;
+
 		action |= entry->flags & IMA_ACTION_FLAGS;
 
 		action |= entry->action & IMA_DO_MASK;
-- 
1.8.1.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-11-07 15:52 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-07 15:49 [RFC][PATCH 0/6] ima: support per-measurement templates Roberto Sassu
2013-11-07 15:49 ` [RFC][PATCH 1/6] ima: connect defined IMA templates through a linked list Roberto Sassu
2013-11-07 15:49 ` [RFC][PATCH 2/6] ima: added new template helper lookup_template_desc_by_fmt() Roberto Sassu
2013-11-07 15:49 ` [RFC][PATCH 3/6] ima: added ima_get_template_desc() for templates dynamic registration Roberto Sassu
2013-11-07 15:49 ` [RFC][PATCH 4/6] ima: replace ima_template_desc_current() with ima_get_template_desc() Roberto Sassu
2013-11-07 15:49 ` [RFC][PATCH 5/6] ima: added ima_template and ima_template_fmt new policy options Roberto Sassu
2013-11-07 15:49 ` [RFC][PATCH 6/6] ima: use custom template obtained from a matched policy rule Roberto Sassu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).