|
@@ -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;
|