diff options
author | Eric Richter <erichte@linux.vnet.ibm.com> | 2016-06-01 14:14:01 -0400 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2016-06-30 01:14:20 -0400 |
commit | 0260643ce8047d2a58f76222d09f161149622465 (patch) | |
tree | 2d08485e5c54c13da4111c5932dadb5ea931a280 /security/integrity/ima | |
parent | 96d450bbeccda6f32c70bbb9ee54057f68733cad (diff) |
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/integrity/ima')
-rw-r--r-- | security/integrity/ima/ima_policy.c | 29 |
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 @@ | |||
32 | #define IMA_FSUUID 0x0020 | 32 | #define IMA_FSUUID 0x0020 |
33 | #define IMA_INMASK 0x0040 | 33 | #define IMA_INMASK 0x0040 |
34 | #define IMA_EUID 0x0080 | 34 | #define IMA_EUID 0x0080 |
35 | #define IMA_PCR 0x0100 | ||
35 | 36 | ||
36 | #define UNKNOWN 0 | 37 | #define UNKNOWN 0 |
37 | #define MEASURE 0x0001 /* same as IMA_MEASURE */ | 38 | #define MEASURE 0x0001 /* same as IMA_MEASURE */ |
@@ -40,6 +41,9 @@ | |||
40 | #define DONT_APPRAISE 0x0008 | 41 | #define DONT_APPRAISE 0x0008 |
41 | #define AUDIT 0x0040 | 42 | #define AUDIT 0x0040 |
42 | 43 | ||
44 | #define INVALID_PCR(a) (((a) < 0) || \ | ||
45 | (a) >= (FIELD_SIZEOF(struct integrity_iint_cache, measured_pcrs) * 8)) | ||
46 | |||
43 | int ima_policy_flag; | 47 | int ima_policy_flag; |
44 | static int temp_ima_appraise; | 48 | static int temp_ima_appraise; |
45 | 49 | ||
@@ -60,6 +64,7 @@ struct ima_rule_entry { | |||
60 | u8 fsuuid[16]; | 64 | u8 fsuuid[16]; |
61 | kuid_t uid; | 65 | kuid_t uid; |
62 | kuid_t fowner; | 66 | kuid_t fowner; |
67 | int pcr; | ||
63 | struct { | 68 | struct { |
64 | void *rule; /* LSM file metadata specific */ | 69 | void *rule; /* LSM file metadata specific */ |
65 | void *args_p; /* audit value */ | 70 | void *args_p; /* audit value */ |
@@ -478,7 +483,8 @@ enum { | |||
478 | Opt_subj_user, Opt_subj_role, Opt_subj_type, | 483 | Opt_subj_user, Opt_subj_role, Opt_subj_type, |
479 | Opt_func, Opt_mask, Opt_fsmagic, | 484 | Opt_func, Opt_mask, Opt_fsmagic, |
480 | Opt_fsuuid, Opt_uid, Opt_euid, Opt_fowner, | 485 | Opt_fsuuid, Opt_uid, Opt_euid, Opt_fowner, |
481 | Opt_appraise_type, Opt_permit_directio | 486 | Opt_appraise_type, Opt_permit_directio, |
487 | Opt_pcr | ||
482 | }; | 488 | }; |
483 | 489 | ||
484 | static match_table_t policy_tokens = { | 490 | static match_table_t policy_tokens = { |
@@ -502,6 +508,7 @@ static match_table_t policy_tokens = { | |||
502 | {Opt_fowner, "fowner=%s"}, | 508 | {Opt_fowner, "fowner=%s"}, |
503 | {Opt_appraise_type, "appraise_type=%s"}, | 509 | {Opt_appraise_type, "appraise_type=%s"}, |
504 | {Opt_permit_directio, "permit_directio"}, | 510 | {Opt_permit_directio, "permit_directio"}, |
511 | {Opt_pcr, "pcr=%s"}, | ||
505 | {Opt_err, NULL} | 512 | {Opt_err, NULL} |
506 | }; | 513 | }; |
507 | 514 | ||
@@ -774,6 +781,20 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
774 | case Opt_permit_directio: | 781 | case Opt_permit_directio: |
775 | entry->flags |= IMA_PERMIT_DIRECTIO; | 782 | entry->flags |= IMA_PERMIT_DIRECTIO; |
776 | break; | 783 | break; |
784 | case Opt_pcr: | ||
785 | if (entry->action != MEASURE) { | ||
786 | result = -EINVAL; | ||
787 | break; | ||
788 | } | ||
789 | ima_log_string(ab, "pcr", args[0].from); | ||
790 | |||
791 | result = kstrtoint(args[0].from, 10, &entry->pcr); | ||
792 | if (result || INVALID_PCR(entry->pcr)) | ||
793 | result = -EINVAL; | ||
794 | else | ||
795 | entry->flags |= IMA_PCR; | ||
796 | |||
797 | break; | ||
777 | case Opt_err: | 798 | case Opt_err: |
778 | ima_log_string(ab, "UNKNOWN", p); | 799 | ima_log_string(ab, "UNKNOWN", p); |
779 | result = -EINVAL; | 800 | result = -EINVAL; |
@@ -1011,6 +1032,12 @@ int ima_policy_show(struct seq_file *m, void *v) | |||
1011 | seq_puts(m, " "); | 1032 | seq_puts(m, " "); |
1012 | } | 1033 | } |
1013 | 1034 | ||
1035 | if (entry->flags & IMA_PCR) { | ||
1036 | snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr); | ||
1037 | seq_printf(m, pt(Opt_pcr), tbuf); | ||
1038 | seq_puts(m, " "); | ||
1039 | } | ||
1040 | |||
1014 | if (entry->flags & IMA_FSUUID) { | 1041 | if (entry->flags & IMA_FSUUID) { |
1015 | seq_printf(m, "fsuuid=%pU", entry->fsuuid); | 1042 | seq_printf(m, "fsuuid=%pU", entry->fsuuid); |
1016 | seq_puts(m, " "); | 1043 | seq_puts(m, " "); |