Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp1278353pxf; Fri, 9 Apr 2021 04:45:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzym0KN+zrfwneMYZ5A/XKFvyvZeLFGzZgE+dpg5TiYR2A9A+R1jbvwbYYmfAhDpaLKJukM X-Received: by 2002:a05:6402:35c9:: with SMTP id z9mr17139072edc.94.1617968740328; Fri, 09 Apr 2021 04:45:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617968740; cv=none; d=google.com; s=arc-20160816; b=Ni9EAHnUxy9D/zB3UvifAuFeey+Wz+Q683jRJfP1zMLN3NRiWgT7X+5WNPbOdc96gJ THDUqNmgWpBQn2Zj+lpJ9iDySfN6ggiKwPtWzw5pQCT3ftI1i2lEHshdcXS1KeOp7aC/ Jw60ykwpM15BKshR0HrBGX8f+qv47NSdvtzK/nMgfJSEgAKM+H3bZkH4EMb3seLjw0As PB8Z6XHtGs3LfDONQ1kgMl1yCQThxXsxT4A99upg3P4hLZN1v0S3Jcg/XMq2RVBjNtci 82z+liOGs/rNoJ1XBorX166BrH22HDtiLtUDm0DXRn966CXDx9AdANT3OB6zuxAmmJPe tgHA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=xqXUM4oBBgG5rNAdA9UUVzQCuXNE7kuXOrAMnHLwx9Y=; b=Jj/zi4IFmf6ZQwwK0IFSjV1cXCisCal7/Rq8mbiAce2ziUV5Rw6lt6k1ev+3bk0mBg OqmQdcyMv8TJXuj3EbxJJrnTEWky+6nZQDaPa2Nh2S48XRoHJtHDeYMPj4ubxq2ZcgWG isCKCHs8rtijdVAAW1ybDL7+R32+aQRy0kybV8vqT3oD4KTvB4lW+cmC/r3ComZcYrBl NJ6U6Q1Y3hleSiQfR6OXEPO5BkHY+e6sodbCRYr8ARuuN4bIIRpcdZVu0KLRKBErhw0a bn8Fpxw6iuyIuYMB0QHzZdpQ1fW+XuWPrD+6vYWzjrG72A6TurqtR52vko31X1+BMhVp PbUA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dp16si1929729ejc.480.2021.04.09.04.45.16; Fri, 09 Apr 2021 04:45:40 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233631AbhDILoG (ORCPT + 99 others); Fri, 9 Apr 2021 07:44:06 -0400 Received: from frasgout.his.huawei.com ([185.176.79.56]:2821 "EHLO frasgout.his.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231756AbhDILn6 (ORCPT ); Fri, 9 Apr 2021 07:43:58 -0400 Received: from fraeml714-chm.china.huawei.com (unknown [172.18.147.200]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4FGwy82K94z680Yb; Fri, 9 Apr 2021 19:34:08 +0800 (CST) Received: from fraphisprd00473.huawei.com (7.182.8.141) by fraeml714-chm.china.huawei.com (10.206.15.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Fri, 9 Apr 2021 13:43:44 +0200 From: Roberto Sassu To: CC: , , , Roberto Sassu Subject: [PATCH 3/7] ima: Introduce exec_tcb and tmpfs policies Date: Fri, 9 Apr 2021 13:43:09 +0200 Message-ID: <20210409114313.4073-4-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210409114313.4073-1-roberto.sassu@huawei.com> References: <20210409114313.4073-1-roberto.sassu@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [7.182.8.141] X-ClientProxiedBy: lhreml754-chm.china.huawei.com (10.201.108.204) To fraeml714-chm.china.huawei.com (10.206.15.33) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch introduces two new hard-coded policies, named exec_tcb and tmpfs. The first excludes the FILE_CHECK rules to measure only files executed and mmapped. The second excludes the dont_measure rule for the tmpfs filesystem for the ima_tcb, tcb and exec_tcb policies, as this could be used as a way for an attacker to hide his actions. The new policies can be selected by specifying them as a value of ima_policy= in the kernel command line. The benefit of using the exec_tcb policy, as opposed to the tcb policy, is that most likely the measurement list will contain only immutable files, recognizable from a set of reference values from software vendors. However, this policy provides a less accurate view of the integrity of the system, as opened files are excluded from measurement. Signed-off-by: Roberto Sassu --- .../admin-guide/kernel-parameters.txt | 7 ++++ security/integrity/ima/ima_policy.c | 42 ++++++++++++------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 04545725f187..88c2ba679c92 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1765,6 +1765,13 @@ mode bit set by either the effective uid (euid=0) or uid=0. + The "exec_tcb" policy is similar to the "tcb" policy + except for opened files, which are not measured. + + The "tmpfs" policy excludes the dont_measure rule for + the tmpfs filesystem, for the "ima_tcb", "tcb" and + "exec_tcb" policies. + The "appraise_tcb" policy appraises the integrity of all files owned by root. diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 33b5133645b3..fff178abb004 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -35,6 +35,8 @@ #define IMA_FSNAME 0x0200 #define IMA_KEYRINGS 0x0400 #define IMA_LABEL 0x0800 +#define IMA_SKIP_TMPFS 0x1000 +#define IMA_SKIP_OPEN 0x2000 #define UNKNOWN 0 #define MEASURE 0x0001 /* same as IMA_MEASURE */ @@ -105,7 +107,8 @@ static struct ima_rule_entry dont_measure_rules[] __ro_after_init = { {.action = DONT_MEASURE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_MEASURE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_MEASURE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE, .fsmagic = TMPFS_MAGIC, .flags = IMA_FSMAGIC}, + {.action = DONT_MEASURE, .fsmagic = TMPFS_MAGIC, + .flags = IMA_FSMAGIC | IMA_SKIP_TMPFS}, {.action = DONT_MEASURE, .fsmagic = DEVPTS_SUPER_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_MEASURE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_MEASURE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, @@ -126,7 +129,7 @@ static struct ima_rule_entry original_measurement_rules[] __ro_after_init = { .flags = IMA_FUNC | IMA_MASK}, {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, .uid_op = &uid_eq, - .flags = IMA_FUNC | IMA_MASK | IMA_UID}, + .flags = IMA_FUNC | IMA_MASK | IMA_UID | IMA_SKIP_OPEN}, {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, }; @@ -138,10 +141,10 @@ static struct ima_rule_entry default_measurement_rules[] __ro_after_init = { .flags = IMA_FUNC | IMA_MASK}, {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, .uid_op = &uid_eq, - .flags = IMA_FUNC | IMA_INMASK | IMA_EUID}, + .flags = IMA_FUNC | IMA_INMASK | IMA_EUID | IMA_SKIP_OPEN}, {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, .uid_op = &uid_eq, - .flags = IMA_FUNC | IMA_INMASK | IMA_UID}, + .flags = IMA_FUNC | IMA_INMASK | IMA_UID | IMA_SKIP_OPEN}, {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, {.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC}, @@ -230,6 +233,7 @@ static int __init default_measure_policy_setup(char *str) } __setup("ima_tcb", default_measure_policy_setup); +static unsigned int ima_measure_skip_flags __initdata; static bool ima_use_appraise_tcb __initdata; static bool ima_use_secure_boot __initdata; static bool ima_use_critical_data __initdata; @@ -243,7 +247,12 @@ static int __init policy_setup(char *str) continue; if ((strcmp(p, "tcb") == 0) && !ima_policy) ima_policy = DEFAULT_TCB; - else if (strcmp(p, "appraise_tcb") == 0) + else if ((strcmp(p, "tmpfs") == 0)) + ima_measure_skip_flags |= IMA_SKIP_TMPFS; + else if ((strcmp(p, "exec_tcb") == 0) && !ima_policy) { + ima_policy = DEFAULT_TCB; + ima_measure_skip_flags |= IMA_SKIP_OPEN; + } else if (strcmp(p, "appraise_tcb") == 0) ima_use_appraise_tcb = true; else if (strcmp(p, "secure_boot") == 0) ima_use_secure_boot = true; @@ -739,13 +748,16 @@ static int ima_appraise_flag(enum ima_hooks func) } static void add_rules(struct ima_rule_entry *entries, int count, - enum policy_rule_list policy_rule) + enum policy_rule_list policy_rule, int skip_flags) { int i = 0; for (i = 0; i < count; i++) { struct ima_rule_entry *entry; + if (entries[i].flags & skip_flags) + continue; + if (policy_rule & IMA_DEFAULT_POLICY) list_add_tail(&entries[i].list, &ima_default_rules); @@ -824,18 +836,18 @@ void __init ima_init_policy(void) /* if !ima_policy, we load NO default rules */ if (ima_policy) add_rules(dont_measure_rules, ARRAY_SIZE(dont_measure_rules), - IMA_DEFAULT_POLICY); + IMA_DEFAULT_POLICY, ima_measure_skip_flags); switch (ima_policy) { case ORIGINAL_TCB: add_rules(original_measurement_rules, ARRAY_SIZE(original_measurement_rules), - IMA_DEFAULT_POLICY); + IMA_DEFAULT_POLICY, ima_measure_skip_flags); break; case DEFAULT_TCB: add_rules(default_measurement_rules, ARRAY_SIZE(default_measurement_rules), - IMA_DEFAULT_POLICY); + IMA_DEFAULT_POLICY, ima_measure_skip_flags); default: break; } @@ -851,7 +863,7 @@ void __init ima_init_policy(void) pr_info("No architecture policies found\n"); else add_rules(arch_policy_entry, arch_entries, - IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY); + IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY, 0); /* * Insert the builtin "secure_boot" policy rules requiring file @@ -859,7 +871,7 @@ void __init ima_init_policy(void) */ if (ima_use_secure_boot) add_rules(secure_boot_rules, ARRAY_SIZE(secure_boot_rules), - IMA_DEFAULT_POLICY); + IMA_DEFAULT_POLICY, 0); /* * Insert the build time appraise rules requiring file signatures @@ -871,21 +883,21 @@ void __init ima_init_policy(void) if (build_appraise_entries) { if (ima_use_secure_boot) add_rules(build_appraise_rules, build_appraise_entries, - IMA_CUSTOM_POLICY); + IMA_CUSTOM_POLICY, 0); else add_rules(build_appraise_rules, build_appraise_entries, - IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY); + IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY, 0); } if (ima_use_appraise_tcb) add_rules(default_appraise_rules, ARRAY_SIZE(default_appraise_rules), - IMA_DEFAULT_POLICY); + IMA_DEFAULT_POLICY, 0); if (ima_use_critical_data) add_rules(critical_data_rules, ARRAY_SIZE(critical_data_rules), - IMA_DEFAULT_POLICY); + IMA_DEFAULT_POLICY, 0); ima_update_policy_flag(); } -- 2.26.2