From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E856C433F5 for ; Fri, 24 Sep 2021 17:59:39 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A9357610C7 for ; Fri, 24 Sep 2021 17:59:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A9357610C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=redhat.com Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-102-rSz3RwV8O_ODDntnak7sYQ-1; Fri, 24 Sep 2021 13:59:35 -0400 X-MC-Unique: rSz3RwV8O_ODDntnak7sYQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3928D802935; Fri, 24 Sep 2021 17:59:27 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0FD186091B; Fri, 24 Sep 2021 17:59:27 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B24CE1803B30; Fri, 24 Sep 2021 17:59:26 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 18OHxOGU010190 for ; Fri, 24 Sep 2021 13:59:25 -0400 Received: by smtp.corp.redhat.com (Postfix) id D3B38200C0C8; Fri, 24 Sep 2021 17:59:24 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast06.extmail.prod.ext.rdu2.redhat.com [10.11.55.22]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CE0CA2039D51 for ; Fri, 24 Sep 2021 17:59:20 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 73313185A79C for ; Fri, 24 Sep 2021 17:59:20 +0000 (UTC) Received: from sonic317-38.consmr.mail.ne1.yahoo.com (sonic317-38.consmr.mail.ne1.yahoo.com [66.163.184.49]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-238-OYEDrLocPuGyyt6GbviEKQ-1; Fri, 24 Sep 2021 13:59:18 -0400 X-MC-Unique: OYEDrLocPuGyyt6GbviEKQ-1 X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506357; bh=nXOALhki1ySgsBY8RsE17RSwD1fxGYQP/fqkLOODPzV=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=G5aQphhVsROW6Z/MfaFmbXGbX675Jz802QIHHjpkR8V4GjGZF0Z90WzI5k5eFCqT4L8UhcBYCCsp4cUN1bfIyNg1AilpPLSJ4D5BNWMgM+UgwquWsCxCSm+MZbFTemVIp87zp2Rq0n95nqBhG732K+uTXd4egrd1w71scRHeaP3Qa0L5CMAaek8Xq/7uX/37A6xK+zCSyTv0Sp4e0ydcwnhJ2AQy5zl1AeSNmEClX7I/zXMvFEjz82fY7GXCtoy7FipEBiTwwxUK1UIdXUOSVvi6sA/1H3HpPFWAphx3gBRjnsaGaaXT+9AdNqZVgRFy4ErQkGSsCN6xfjqtECLedQ== X-YMail-OSG: gcGqTZAVM1n8e.hStoc7oohaohiDwmAri2fQpaO_QXFeZERAH7wHGHmIXb10ygM WT7HifJnI_P7bDVIIWQRxPvvXzo8nVqkA3jGGPjT2K_QERYuTLRUheUaSBXv14OClvPWAhP5SIhk eZo0Z2U.OnopkCpVgCdGR31WDHgDVYbRnVkqSGkVt5MbmWIq57Wj0sSU4eDr_OM.YVV.TeZtlmep Chk3aqfcOGhINzCCyHnHjpiZ6AZzufhtpumCLYRF4AaG.78e6OqVp0DiyNkY0yrZxRiYvSk7SzOT NxeXZeArtkvUsX63WNYV6TCN1qlBtIDC_xF3IMFMZdzNbNa3.kEoE0eY_WtBRRY692DOttxP.61Z p2IOcBqch48stwVb6KPm82UyglfLAEjS_pt1bdLsa15EaQyejzbvt2xO5IprDHGpFJki0pmpl2nm fK9gzjLHXfKrtdhzYpVH1cCnYeZ7wTqSSjHWEPb_B8E4EqjkEm7NJypTRJPerS2giXXTiNK7Mi6t bt2SxGz4NQcIwKeVlhUIvTSzYZxaOaJoMjGv9U7FRpJe7WWRB1OGt6YDLnE5IuxRdpPbrRpsAiSN ry_2iATcrtnVKUT19f2ztZT5yzrNi13f5pOVFUzeg45p.4UUrHgBzZfti_Bvan012.0Qk7U7lU5x .r53QuyzYKSygIQn8Jj.ml1NN6nkIzornLcUncQbnhQfg0qMTRsD0kh0HLBPao4RKjw.3uZC.rAI wOa9VurSAZnl9C5ligx.wHNYKwatK0qOY6WNKYDaRohZBhdE6R8SmgElD9T1ffb7p9aXjm9x.wtE 444ZcxbQbQMjoA246e6wxo28wXgTm.fQ7OfWNmLASZJ2Hkkl22HopzUF_Tmbu9YLXQUoBun8KHNe cG.z9jN7esicaDd68XKVTIrzuv7.IWH6uyfPavoq7FpNcTV_YWCGVwPZ2HOh.jK6ciP3aYhIa1uE 6gSlL_Zx7d3YtHtEQsxh6R.p9pyfLjBiegP.Gf2hzsqBG3pruBLMaDl4zLSBpHoO14VlhVGkEChR XUCfQfjRTkJyV5hTGa4.TYxKlXsdA96PdWKNUPIGpokrMLmNGLRzrTZi.QznrIKEmDBCqB5PLb.j S6aK8POk4ndwIVVbtmu5rLjpABxxg.X5bSrp6MYo.2L4RDKcIqvOvJAmD.azILG_b0bkRpB0Hk_B TUKOI2ePaGzOaG22nn66XYDix6_bXtAhyQRyghlVBNJnATlQscJ6DLOCok_0WXDFZZOIWsOkPEKE dUz.yv17dlc98Ib8z5uPNV8Bquv1Zr5pNfp4Oooy9VH56o8r9RCKfLRFldrI7tp.4Cd5qg78DmYY OAcdRNeVCKy01F.ATFheH0boN2T3KBz29.e8Io3eTtEKycJ6CfQHBpnAbN.PSltNrs5nFt2yU3h3 fEf2RMVs0sL6yGEFpchAefi5uZ0JVwj1mJH_1vfKeR6nAWrohaJ0ekJ0b3rFq.H8NGWeumEJGKbB BmjMkJ09t.nmJDE_cAS_Ctrgby9L3HNeg2asyLZz_gePcTdwJ23Oge7w0.k4TGBuQGAb80st0Xhx whWZfHjjZ96F6rCGazksMa1t4.6Hm3q7qcUt77.q_ajNgbL_joCP2OP5uO4ESiXTrCi_wpBAgcuV 5FnW_LlzrNOe2qhgaPQMmcaE0YSDMgH_hX9F70E1q0NjkPJWTKt.XsDPuMaNP63WDU9EdGEI4PAp zWcuAsxf1k.T6qTEXQxSgihlofFzBQAWJRENj46_bSOYVi900lfcwal6h_j.ZsZRJISK.8.j_Ogk VuYcex2exy2ipldGn4ni_6tl26jvGhQCA6g8kOl.4UQibKXcjF3RjJbNjEPlL.0HEp48WuqAonHG .axnMQguVl4_nxSFzjy0wg9TcCcvX23yKT4aGh.4PIIHAfKiOZv5RHQMd.6P805Hs6Gur0SPee1S 9mx35RlnrXOhyDkUx6kLdTZaDjgFUfCg5Qggt2l09Nq1q7MyKvhXPHstYcNL6YY4L1otV6HWxoyk LAFYCK9SCn6TXyrGWRNldA6G2cWfNHeukks2EaOYvbZXl9tzL0bXj4O5BFwvr_rrRZoccb2dbt8N NcQXi7hZzgbDz1q0K6tNtbaVNz1OQFkIoQoqihloQiH2DZ1i2GbAMpRkz7DqSxgVMEhvcAdK0mhJ Yz2Z3W_3YwTQN0GN3H0RTc_sQe3T266BHzjaicALWLKQT1oQ3VfszLRz_2HmuiAbCU7qlut3NLfk Nu6Be824p6MNLHM2ThLSHw7XViXF7MyF9BxE7_mW2FQ.B9xZW7IjtI03ng3JmnGOxkbmDuPMSoDO XLx4PZGMXf5Tzfb5F04QVRUwIkKJbNOwuP.Tg2xUFeA_c0A0JVs7BGS6Sb9Tlbtrh2SsytyWi7Li IoPrvT7y9GvmcdsIszHZr25lDi9WVK8e6ptC_eA-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 17:59:17 +0000 Received: by kubenode520.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID d92f82df13f171d3f133cc62319c1ca1; Fri, 24 Sep 2021 17:59:12 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Subject: [PATCH v29 04/28] IMA: avoid label collisions with stacked LSMs Date: Fri, 24 Sep 2021 10:54:17 -0700 Message-Id: <20210924175441.7943-5-casey@schaufler-ca.com> In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-1-casey@schaufler-ca.com> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: linux-audit@redhat.com Cc: john.johansen@canonical.com, linux-kernel@vger.kernel.org, linux-audit@redhat.com, sds@tycho.nsa.gov X-BeenThere: linux-audit@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Linux Audit Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-audit-bounces@redhat.com Errors-To: linux-audit-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=linux-audit-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Integrity measurement may filter on security module information and needs to be clear in the case of multiple active security modules which applies. Provide a boot option ima_rules_lsm= to allow the user to specify an active securty module to apply filters to. If not specified, use the first registered module that supports the audit_rule_match() LSM hook. Allow the user to specify in the IMA policy an lsm= option to specify the security module to use for a particular rule. Reviewed-by: Kees Cook Signed-off-by: Casey Schaufler To: Mimi Zohar To: linux-integrity@vger.kernel.org --- Documentation/ABI/testing/ima_policy | 8 ++- security/integrity/ima/ima_policy.c | 79 ++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index 5c2798534950..fb2b66b3c1e7 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -25,7 +25,7 @@ Description: base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=] [euid=] [fowner=] [fsname=]] lsm: [[subj_user=] [subj_role=] [subj_type=] - [obj_user=] [obj_role=] [obj_type=]] + [obj_user=] [obj_role=] [obj_type=] [lsm=]] option: [[appraise_type=]] [template=] [permit_directio] [appraise_flag=] [appraise_algos=] [keyrings=] base: @@ -122,6 +122,12 @@ Description: measure subj_user=_ func=FILE_CHECK mask=MAY_READ + It is possible to explicitly specify which security + module a rule applies to using lsm=. If the security + modules specified is not active on the system the rule + will be rejected. If lsm= is not specified the first + security module registered on the system will be assumed. + Example of measure rules using alternate PCRs:: measure func=KEXEC_KERNEL_CHECK pcr=4 diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index cbe6f1244e31..af278e225f9e 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -82,9 +82,10 @@ struct ima_rule_entry { bool (*uid_op)(kuid_t, kuid_t); /* Handlers for operators */ bool (*fowner_op)(kuid_t, kuid_t); /* uid_eq(), uid_gt(), uid_lt() */ int pcr; + int which_lsm; /* which of the rules to use */ unsigned int allowed_algos; /* bitfield of allowed hash algorithms */ struct { - void *rules[LSMBLOB_ENTRIES]; /* LSM file metadata specific */ + void *rule; /* LSM file metadata specific */ char *args_p; /* audit value */ int type; /* audit type */ } lsm[MAX_LSM_RULES]; @@ -96,17 +97,17 @@ struct ima_rule_entry { /** * ima_lsm_isset - Is a rule set for any of the active security modules - * @rules: The set of IMA rules to check + * @entry: the rule entry to examine + * @lsm_rule: the specific rule type in question * - * If a rule is set for any LSM return true, otherwise return false. + * If a rule is set return true, otherwise return false. */ -static inline bool ima_lsm_isset(void *rules[]) +static inline bool ima_lsm_isset(struct ima_rule_entry *entry, int lsm_rule) { - int i; - - for (i = 0; i < LSMBLOB_ENTRIES; i++) - if (rules[i]) - return true; + if (lsm_rule < 0 || lsm_rule > MAX_LSM_RULES) + return false; + if (entry->lsm[lsm_rule].rule) + return true; return false; } @@ -294,6 +295,20 @@ static int __init default_appraise_policy_setup(char *str) } __setup("ima_appraise_tcb", default_appraise_policy_setup); +static int ima_rules_lsm __ro_after_init; + +static int __init ima_rules_lsm_init(char *str) +{ + ima_rules_lsm = lsm_name_to_slot(str); + if (ima_rules_lsm < 0) { + ima_rules_lsm = 0; + pr_err("rule lsm \"%s\" not registered", str); + } + + return 1; +} +__setup("ima_rules_lsm=", ima_rules_lsm_init); + static struct ima_rule_opt_list *ima_alloc_rule_opt_list(const substring_t *src) { struct ima_rule_opt_list *opt_list; @@ -363,11 +378,10 @@ static void ima_free_rule_opt_list(struct ima_rule_opt_list *opt_list) static void ima_lsm_free_rule(struct ima_rule_entry *entry) { int i; - int r; for (i = 0; i < MAX_LSM_RULES; i++) { - for (r = 0; r < LSMBLOB_ENTRIES; r++) - ima_filter_rule_free(entry->lsm[i].rules[r]); + if (entry->lsm[i].rule) + ima_filter_rule_free(entry->lsm[i].rule); kfree(entry->lsm[i].args_p); } } @@ -418,8 +432,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) ima_filter_rule_init(nentry->lsm[i].type, Audit_equal, nentry->lsm[i].args_p, - &nentry->lsm[i].rules[0]); - if (!ima_lsm_isset(nentry->lsm[i].rules)) + &nentry->lsm[i].rule); + if (!ima_lsm_isset(nentry, i)) pr_warn("rule for LSM \'%s\' is undefined\n", nentry->lsm[i].args_p); } @@ -608,7 +622,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, int rc = 0; u32 osid; - if (!ima_lsm_isset(rule->lsm[i].rules)) { + if (!ima_lsm_isset(rule, i)) { if (!rule->lsm[i].args_p) continue; else @@ -621,14 +635,14 @@ static bool ima_match_rules(struct ima_rule_entry *rule, security_inode_getsecid(inode, &osid); rc = ima_filter_rule_match(osid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rules); + rule->lsm[i].rule); break; case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: rc = ima_filter_rule_match(secid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rules); + rule->lsm[i].rule); break; default: break; @@ -1017,7 +1031,7 @@ enum { Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, Opt_appraise_type, Opt_appraise_flag, Opt_appraise_algos, Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings, - Opt_label, Opt_err + Opt_lsm, Opt_label, Opt_err }; static const match_table_t policy_tokens = { @@ -1056,6 +1070,7 @@ static const match_table_t policy_tokens = { {Opt_template, "template=%s"}, {Opt_keyrings, "keyrings=%s"}, {Opt_label, "label=%s"}, + {Opt_lsm, "lsm=%s"}, {Opt_err, NULL} }; @@ -1064,7 +1079,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, { int result; - if (ima_lsm_isset(entry->lsm[lsm_rule].rules)) + if (ima_lsm_isset(entry, lsm_rule)) return -EINVAL; entry->lsm[lsm_rule].args_p = match_strdup(args); @@ -1074,8 +1089,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, entry->lsm[lsm_rule].type = audit_type; result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, entry->lsm[lsm_rule].args_p, - &entry->lsm[lsm_rule].rules[0]); - if (!ima_lsm_isset(entry->lsm[lsm_rule].rules)) { + &entry->lsm[lsm_rule].rule); + if (!ima_lsm_isset(entry, lsm_rule)) { pr_warn("rule for LSM \'%s\' is undefined\n", entry->lsm[lsm_rule].args_p); @@ -1680,6 +1695,19 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) &(template_desc->num_fields)); entry->template = template_desc; break; + case Opt_lsm: + result = lsm_name_to_slot(args[0].from); + if (result == LSMBLOB_INVALID) { + int i; + + for (i = 0; i < MAX_LSM_RULES; i++) + entry->lsm[i].args_p = NULL; + result = -EINVAL; + break; + } + entry->which_lsm = result; + result = 0; + break; case Opt_err: ima_log_string(ab, "UNKNOWN", p); result = -EINVAL; @@ -1716,6 +1744,7 @@ ssize_t ima_parse_add_rule(char *rule) struct ima_rule_entry *entry; ssize_t result, len; int audit_info = 0; + int i; p = strsep(&rule, "\n"); len = strlen(p) + 1; @@ -1733,6 +1762,9 @@ ssize_t ima_parse_add_rule(char *rule) INIT_LIST_HEAD(&entry->list); + for (i = 0; i < MAX_LSM_RULES; i++) + entry->which_lsm = ima_rules_lsm; + result = ima_parse_rule(p, entry); if (result) { ima_free_rule(entry); @@ -1972,7 +2004,7 @@ int ima_policy_show(struct seq_file *m, void *v) } for (i = 0; i < MAX_LSM_RULES; i++) { - if (ima_lsm_isset(entry->lsm[i].rules)) { + if (ima_lsm_isset(entry, i)) { switch (i) { case LSM_OBJ_USER: seq_printf(m, pt(Opt_obj_user), @@ -2014,6 +2046,9 @@ int ima_policy_show(struct seq_file *m, void *v) seq_puts(m, "appraise_flag=check_blacklist "); if (entry->flags & IMA_PERMIT_DIRECTIO) seq_puts(m, "permit_directio "); + if (entry->which_lsm >= 0) + seq_printf(m, pt(Opt_lsm), + lsm_slot_to_name(entry->which_lsm)); rcu_read_unlock(); seq_puts(m, "\n"); return 0; -- 2.31.1 -- Linux-audit mailing list Linux-audit@redhat.com https://listman.redhat.com/mailman/listinfo/linux-audit