summaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_policy.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 16:53:59 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 16:53:59 -0700
commitf8cf2f16a7c95acce497bfafa90e7c6d8397d653 (patch)
tree6451abed2025593015cde6fdc6edd54844eb15d3 /security/integrity/ima/ima_policy.c
parent4b3f1a151571985f7c9964260db1c31e056a67e4 (diff)
parentab60368ab6a452466885ef4edf0cefd089465132 (diff)
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull integrity updates from James Morris: "A mixture of bug fixes, code cleanup, and continues to close IMA-measurement, IMA-appraisal, and IMA-audit gaps. Also note the addition of a new cred_getsecid LSM hook by Matthew Garrett: For IMA purposes, we want to be able to obtain the prepared secid in the bprm structure before the credentials are committed. Add a cred_getsecid hook that makes this possible. which is used by a new CREDS_CHECK target in IMA: In ima_bprm_check(), check with both the existing process credentials and the credentials that will be committed when the new process is started. This will not change behaviour unless the system policy is extended to include CREDS_CHECK targets - BPRM_CHECK will continue to check the same credentials that it did previously" * 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: ima: Fallback to the builtin hash algorithm ima: Add smackfs to the default appraise/measure list evm: check for remount ro in progress before writing ima: Improvements in ima_appraise_measurement() ima: Simplify ima_eventsig_init() integrity: Remove unused macro IMA_ACTION_RULE_FLAGS ima: drop vla in ima_audit_measurement() ima: Fix Kconfig to select TPM 2.0 CRB interface evm: Constify *integrity_status_msg[] evm: Move evm_hmac and evm_hash from evm_main.c to evm_crypto.c fuse: define the filesystem as untrusted ima: fail signature verification based on policy ima: clear IMA_HASH ima: re-evaluate files on privileged mounted filesystems ima: fail file signature verification on non-init mounted filesystems IMA: Support using new creds in appraisal policy security: Add a cred_getsecid hook
Diffstat (limited to 'security/integrity/ima/ima_policy.c')
-rw-r--r--security/integrity/ima/ima_policy.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 915f5572c6ff..d89bebf85421 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -96,6 +96,7 @@ static struct ima_rule_entry dont_measure_rules[] __ro_after_init = {
{.action = DONT_MEASURE, .fsmagic = BINFMTFS_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 = SMACK_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC,
.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC,
@@ -141,6 +142,7 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
{.action = DONT_APPRAISE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE, .fsmagic = SMACK_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC},
@@ -188,6 +190,7 @@ __setup("ima_tcb", default_measure_policy_setup);
static bool ima_use_appraise_tcb __initdata;
static bool ima_use_secure_boot __initdata;
+static bool ima_fail_unverifiable_sigs __ro_after_init;
static int __init policy_setup(char *str)
{
char *p;
@@ -201,6 +204,8 @@ static int __init policy_setup(char *str)
ima_use_appraise_tcb = true;
else if (strcmp(p, "secure_boot") == 0)
ima_use_secure_boot = true;
+ else if (strcmp(p, "fail_securely") == 0)
+ ima_fail_unverifiable_sigs = true;
}
return 1;
@@ -243,16 +248,17 @@ static void ima_lsm_update_rules(void)
* ima_match_rules - determine whether an inode matches the measure rule.
* @rule: a pointer to a rule
* @inode: a pointer to an inode
+ * @cred: a pointer to a credentials structure for user validation
+ * @secid: the secid of the task to be validated
* @func: LIM hook identifier
* @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
*
* Returns true on rule match, false on failure.
*/
static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
+ const struct cred *cred, u32 secid,
enum ima_hooks func, int mask)
{
- struct task_struct *tsk = current;
- const struct cred *cred = current_cred();
int i;
if ((rule->flags & IMA_FUNC) &&
@@ -287,7 +293,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
return false;
for (i = 0; i < MAX_LSM_RULES; i++) {
int rc = 0;
- u32 osid, sid;
+ u32 osid;
int retried = 0;
if (!rule->lsm[i].rule)
@@ -307,8 +313,7 @@ retry:
case LSM_SUBJ_USER:
case LSM_SUBJ_ROLE:
case LSM_SUBJ_TYPE:
- security_task_getsecid(tsk, &sid);
- rc = security_filter_rule_match(sid,
+ rc = security_filter_rule_match(secid,
rule->lsm[i].type,
Audit_equal,
rule->lsm[i].rule,
@@ -341,6 +346,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
return IMA_MMAP_APPRAISE;
case BPRM_CHECK:
return IMA_BPRM_APPRAISE;
+ case CREDS_CHECK:
+ return IMA_CREDS_APPRAISE;
case FILE_CHECK:
case POST_SETATTR:
return IMA_FILE_APPRAISE;
@@ -353,6 +360,9 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
/**
* ima_match_policy - decision based on LSM and other conditions
* @inode: pointer to an inode for which the policy decision is being made
+ * @cred: pointer to a credentials structure for which the policy decision is
+ * being made
+ * @secid: LSM secid of the task to be validated
* @func: IMA hook identifier
* @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
* @pcr: set the pcr to extend
@@ -364,8 +374,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
* list when walking it. Reads are many orders of magnitude more numerous
* than writes so ima_match_policy() is classical RCU candidate.
*/
-int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
- int flags, int *pcr)
+int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
+ enum ima_hooks func, int mask, int flags, int *pcr)
{
struct ima_rule_entry *entry;
int action = 0, actmask = flags | (flags << 1);
@@ -376,7 +386,7 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
if (!(entry->action & actmask))
continue;
- if (!ima_match_rules(entry, inode, func, mask))
+ if (!ima_match_rules(entry, inode, cred, secid, func, mask))
continue;
action |= entry->flags & IMA_ACTION_FLAGS;
@@ -384,7 +394,9 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
action |= entry->action & IMA_DO_MASK;
if (entry->action & IMA_APPRAISE) {
action |= get_subaction(entry, func);
- action ^= IMA_HASH;
+ action &= ~IMA_HASH;
+ if (ima_fail_unverifiable_sigs)
+ action |= IMA_FAIL_UNVERIFIABLE_SIGS;
}
if (entry->action & IMA_DO_MASK)
@@ -713,6 +725,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
entry->func = MMAP_CHECK;
else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
entry->func = BPRM_CHECK;
+ else if (strcmp(args[0].from, "CREDS_CHECK") == 0)
+ entry->func = CREDS_CHECK;
else if (strcmp(args[0].from, "KEXEC_KERNEL_CHECK") ==
0)
entry->func = KEXEC_KERNEL_CHECK;