summary refs log tree commit diff
path: root/security
diff options
context:
space:
mode:
authorEric Richter <erichte@linux.vnet.ibm.com>2016-06-01 13:14:01 -0500
committerMimi Zohar <zohar@linux.vnet.ibm.com>2016-06-30 01:14:20 -0400
commit0260643ce8047d2a58f76222d09f161149622465 (patch)
tree2d08485e5c54c13da4111c5932dadb5ea931a280 /security
parent96d450bbeccda6f32c70bbb9ee54057f68733cad (diff)
downloadlinux-0260643ce8047d2a58f76222d09f161149622465.tar.gz
ima: add policy support for extending different pcrs
This patch defines a new IMA measurement policy rule option "pcr=",
which allows extending different PCRs on a per rule basis. For example,
the system independent files could extend the default IMA Kconfig
specified PCR, while the system dependent files could extend a different
PCR.

The following is an example of this usage with an SELinux policy; the
rule would extend PCR 11 with system configuration files:

  measure func=FILE_CHECK mask=MAY_READ obj_type=system_conf_t pcr=11

Changelog v3:
- FIELD_SIZEOF returns bytes, not bits. Fixed INVALID_PCR

Signed-off-by: Eric Richter <erichte@linux.vnet.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima_policy.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 0f887a564a29..3d35fbe3be0b 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -32,6 +32,7 @@
 #define IMA_FSUUID	0x0020
 #define IMA_INMASK	0x0040
 #define IMA_EUID	0x0080
+#define IMA_PCR		0x0100
 
 #define UNKNOWN		0
 #define MEASURE		0x0001	/* same as IMA_MEASURE */
@@ -40,6 +41,9 @@
 #define DONT_APPRAISE	0x0008
 #define AUDIT		0x0040
 
+#define INVALID_PCR(a) (((a) < 0) || \
+	(a) >= (FIELD_SIZEOF(struct integrity_iint_cache, measured_pcrs) * 8))
+
 int ima_policy_flag;
 static int temp_ima_appraise;
 
@@ -60,6 +64,7 @@ struct ima_rule_entry {
 	u8 fsuuid[16];
 	kuid_t uid;
 	kuid_t fowner;
+	int pcr;
 	struct {
 		void *rule;	/* LSM file metadata specific */
 		void *args_p;	/* audit value */
@@ -478,7 +483,8 @@ enum {
 	Opt_subj_user, Opt_subj_role, Opt_subj_type,
 	Opt_func, Opt_mask, Opt_fsmagic,
 	Opt_fsuuid, Opt_uid, Opt_euid, Opt_fowner,
-	Opt_appraise_type, Opt_permit_directio
+	Opt_appraise_type, Opt_permit_directio,
+	Opt_pcr
 };
 
 static match_table_t policy_tokens = {
@@ -502,6 +508,7 @@ static match_table_t policy_tokens = {
 	{Opt_fowner, "fowner=%s"},
 	{Opt_appraise_type, "appraise_type=%s"},
 	{Opt_permit_directio, "permit_directio"},
+	{Opt_pcr, "pcr=%s"},
 	{Opt_err, NULL}
 };
 
@@ -774,6 +781,20 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 		case Opt_permit_directio:
 			entry->flags |= IMA_PERMIT_DIRECTIO;
 			break;
+		case Opt_pcr:
+			if (entry->action != MEASURE) {
+				result = -EINVAL;
+				break;
+			}
+			ima_log_string(ab, "pcr", args[0].from);
+
+			result = kstrtoint(args[0].from, 10, &entry->pcr);
+			if (result || INVALID_PCR(entry->pcr))
+				result = -EINVAL;
+			else
+				entry->flags |= IMA_PCR;
+
+			break;
 		case Opt_err:
 			ima_log_string(ab, "UNKNOWN", p);
 			result = -EINVAL;
@@ -1011,6 +1032,12 @@ int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, " ");
 	}
 
+	if (entry->flags & IMA_PCR) {
+		snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr);
+		seq_printf(m, pt(Opt_pcr), tbuf);
+		seq_puts(m, " ");
+	}
+
 	if (entry->flags & IMA_FSUUID) {
 		seq_printf(m, "fsuuid=%pU", entry->fsuuid);
 		seq_puts(m, " ");