Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp2481403pxa; Mon, 24 Aug 2020 15:47:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzRonTYKNU6Et+JpNC6rIpHEGoTcXJ22FNYB7k5vfYSGDUJyXbXI+tem0glsUjNDAAuSldR X-Received: by 2002:a17:906:aad7:: with SMTP id kt23mr7565194ejb.124.1598309277346; Mon, 24 Aug 2020 15:47:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598309277; cv=none; d=google.com; s=arc-20160816; b=q1K++6BocjBL6nm8H+Kfja7EW4LNpczcAgJ+0xUz9BmWOxHbsunmT7jw61R1IP0coc DrE2eCYmtsqrAkvIsH6wktu08x62YAazAd44n34z78cnfpagqCBK9In8Nm1wUp6bVOPi 9vfiNzdpNghz0zqgY+quI+3u2Ai+wc08zsh90v5v1xVMs2aVmsEBw/rBIJfVGJCjTUh3 JM+T1CQ7bLIzEXq/T/x6cv13wD2wQf/Ixcn4z7tGNUyXCN3xwUYTsbgNh1vfZMqaIajx 3gFmtYSFnqO1KeBQN0u0qIQSKzqmjB/oJ3L/npjWKi3r0onrxQbUyCWUf/9KnMd4eMZL ew0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:date:cc:to:from:subject:message-id :dkim-signature; bh=8tTDOoPs33Nyna5Is9frTMZ2BO8eMhLytpXXTM+m5Xs=; b=e0HOOSALhkfN8Rt0Onc9CZ4EcVlrIpaNGfV8hCpvzcDakcvRMSuWmE8igvylUbL5mE ppQGq2qMk0KvKDbr7Fb8/R/RID7DNXFfj1QKlj12tJlnas4akPUvK2lmiVxdD7d0hH46 kocfL/iUx6MC5njEGXejNasM/l6pVULFlF5wMdb1HlMPdoT02PJYkzX403+v4yiiMWJf ibgHMY/aJfLx9NdSamF4H8tc26toe8VLRCa9f2efNYrtpQDddRHVSbXv+hZB/rNZy29O ADgVn6qhlaVKAuVx/L+i4X2gLgWGL23EProq9d8XLTmBHVUUInMB0S5lrAXqpXfDpn0+ 5B4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b=JvcSuahj; 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=pass (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ci27si8709998ejc.655.2020.08.24.15.47.33; Mon, 24 Aug 2020 15:47:57 -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; dkim=pass header.i=@ibm.com header.s=pp1 header.b=JvcSuahj; 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=pass (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728083AbgHXWq6 (ORCPT + 99 others); Mon, 24 Aug 2020 18:46:58 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:6202 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726531AbgHXWq5 (ORCPT ); Mon, 24 Aug 2020 18:46:57 -0400 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 07OMVpKk040142; Mon, 24 Aug 2020 18:46:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=message-id : subject : from : to : cc : date : in-reply-to : references : content-type : mime-version : content-transfer-encoding; s=pp1; bh=8tTDOoPs33Nyna5Is9frTMZ2BO8eMhLytpXXTM+m5Xs=; b=JvcSuahj0oDP8xgIiVZwryyALkwDY5bCkMPq1/5NM6VkVOs0MUTEQifkn/ZSSEtbMHYZ rH20d1Loh8JQqOSu2rDi4ffVV/f6jpwuOG6vjMkfts01lPuINhlBGOu8cbRUYleTx410 3xxOjh2Qt57nTCCHqo+K3YFM/6bhPPRc+PMHt6Guh5bs8hcmLx8yquaBegObYUD4OjLF 7cT36syxpeOUUFngTzWLXrhzsxf/tulKxEqmrZR1VbvOHQcDduoG1xBohrm4ie3fg4nM sPeOHSEB52WozskoCdHzDKx7gS2T4DSR/S7zIyRvtMFJL1cqbDkLShaPaQo5/WaT62ra Rw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 334m6jvagu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Aug 2020 18:46:49 -0400 Received: from m0098419.ppops.net (m0098419.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 07OMVsRl040449; Mon, 24 Aug 2020 18:46:49 -0400 Received: from ppma06ams.nl.ibm.com (66.31.33a9.ip4.static.sl-reverse.com [169.51.49.102]) by mx0b-001b2d01.pphosted.com with ESMTP id 334m6jvag0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Aug 2020 18:46:49 -0400 Received: from pps.filterd (ppma06ams.nl.ibm.com [127.0.0.1]) by ppma06ams.nl.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 07OMcavW013663; Mon, 24 Aug 2020 22:46:47 GMT Received: from b06cxnps3075.portsmouth.uk.ibm.com (d06relay10.portsmouth.uk.ibm.com [9.149.109.195]) by ppma06ams.nl.ibm.com with ESMTP id 332uk6asy4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Aug 2020 22:46:47 +0000 Received: from b06wcsmtp001.portsmouth.uk.ibm.com (b06wcsmtp001.portsmouth.uk.ibm.com [9.149.105.160]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 07OMkjJ431261062 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 24 Aug 2020 22:46:45 GMT Received: from b06wcsmtp001.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F409FA405B; Mon, 24 Aug 2020 22:46:44 +0000 (GMT) Received: from b06wcsmtp001.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1F5EBA4054; Mon, 24 Aug 2020 22:46:42 +0000 (GMT) Received: from li-f45666cc-3089-11b2-a85c-c57d1a57929f.ibm.com (unknown [9.160.38.197]) by b06wcsmtp001.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 24 Aug 2020 22:46:41 +0000 (GMT) Message-ID: Subject: Re: [PATCH v2 2/3] IMA: add policy to support measuring critical data from kernel components From: Mimi Zohar To: Tushar Sugandhi , stephen.smalley.work@gmail.com, casey@schaufler-ca.com, agk@redhat.com, snitzer@redhat.com, gmazyland@gmail.com Cc: tyhicks@linux.microsoft.com, sashal@kernel.org, jmorris@namei.org, nramas@linux.microsoft.com, linux-integrity@vger.kernel.org, selinux@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@redhat.com Date: Mon, 24 Aug 2020 18:46:41 -0400 In-Reply-To: <20200821182107.5328-3-tusharsu@linux.microsoft.com> References: <20200821182107.5328-1-tusharsu@linux.microsoft.com> <20200821182107.5328-3-tusharsu@linux.microsoft.com> Content-Type: text/plain; charset="ISO-8859-15" X-Mailer: Evolution 3.28.5 (3.28.5-12.el8) Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235,18.0.687 definitions=2020-08-24_12:2020-08-24,2020-08-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 bulkscore=0 suspectscore=0 mlxlogscore=999 spamscore=0 impostorscore=0 mlxscore=0 priorityscore=1501 clxscore=1015 malwarescore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2006250000 definitions=main-2008240174 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 2020-08-21 at 11:21 -0700, Tushar Sugandhi wrote: > There would be several candidate kernel components suitable for IMA > measurement. Not all of them would have support for IMA measurement. > Also, system administrators may not want to measure data for all of > them, even when they support IMA measurement. An IMA policy specific > to various kernel components is needed to measure their respective > critical data. > > Add a new IMA policy CRITICAL_DATA+data_sources to support measuring > various critical kernel components. This policy would enable the > system administrators to limit the measurement to the components, > if the components support IMA measurement. > > Signed-off-by: Tushar Sugandhi > --- > Documentation/ABI/testing/ima_policy | 6 ++- > security/integrity/ima/ima.h | 1 + > security/integrity/ima/ima_api.c | 2 +- > security/integrity/ima/ima_policy.c | 62 +++++++++++++++++++++++++--- > 4 files changed, 63 insertions(+), 8 deletions(-) > > diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy > index cd572912c593..a0dd0f108555 100644 > --- a/Documentation/ABI/testing/ima_policy > +++ b/Documentation/ABI/testing/ima_policy > @@ -29,7 +29,7 @@ Description: > base: func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK] > [FIRMWARE_CHECK] > [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] > - [KEXEC_CMDLINE] [KEY_CHECK] > + [KEXEC_CMDLINE] [KEY_CHECK] [CRITICAL_DATA] > mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] > [[^]MAY_EXEC] > fsmagic:= hex value > @@ -125,3 +125,7 @@ Description: > keys added to .builtin_trusted_keys or .ima keyring: > > measure func=KEY_CHECK keyrings=.builtin_trusted_keys|.ima > + > + Example of measure rule using CRITICAL_DATA to measure critical data > + > + measure func=CRITICAL_DATA data_sources=selinux|apparmor|dm-crypt This example uses "data_sources" without first defining it in the "option:" section. Defining two new options is an indication that this patch should be split up. One which defines the "CRITICAL_DATA" and another one which defines the new key value pair. The term "data_sources" is pretty generic. Perhaps constrain it a bit by re- naming it "critical_data=". Or was such using a generic name intentional? Normally "CRITICAL_DATA" would be defined with the critical data hook, but that seems to be defined in patch 3/3 "IMA: define IMA hook to measure critical data from kernel components". > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h > index 8875085db689..0f4209a92bfb 100644 > --- a/security/integrity/ima/ima.h > +++ b/security/integrity/ima/ima.h > @@ -200,6 +200,7 @@ static inline unsigned int ima_hash_key(u8 *digest) > hook(POLICY_CHECK, policy) \ > hook(KEXEC_CMDLINE, kexec_cmdline) \ > hook(KEY_CHECK, key) \ > + hook(CRITICAL_DATA, critical_data) \ > hook(MAX_CHECK, none) > > #define __ima_hook_enumify(ENUM, str) ENUM, > diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c > index af218babd198..9917e1730cb6 100644 > --- a/security/integrity/ima/ima_api.c > +++ b/security/integrity/ima/ima_api.c > @@ -176,7 +176,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, > * subj=, obj=, type=, func=, mask=, fsmagic= > * subj,obj, and type: are LSM specific. > * func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK > - * | KEXEC_CMDLINE | KEY_CHECK > + * | KEXEC_CMDLINE | KEY_CHECK | CRITICAL_DATA > * mask: contains the permission mask > * fsmagic: hex value > * > diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c > index 8866e84d0062..7b649095ac7a 100644 > --- a/security/integrity/ima/ima_policy.c > +++ b/security/integrity/ima/ima_policy.c > @@ -33,6 +33,7 @@ > #define IMA_PCR 0x0100 > #define IMA_FSNAME 0x0200 > #define IMA_KEYRINGS 0x0400 > +#define IMA_DATA_SOURCES 0x0800 > > #define UNKNOWN 0 > #define MEASURE 0x0001 /* same as IMA_MEASURE */ > @@ -84,6 +85,7 @@ struct ima_rule_entry { > } lsm[MAX_LSM_RULES]; > char *fsname; > struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */ > + struct ima_rule_opt_list *data_sources; /* Measure data from these sources */ > struct ima_template_desc *template; > }; > > @@ -508,14 +510,23 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, > { > int i; > > - if (func == KEY_CHECK) { > - return (rule->flags & IMA_FUNC) && (rule->func == func) && > - ima_match_rule_data(rule, rule->keyrings, func_data, > - true, cred); > - } > if ((rule->flags & IMA_FUNC) && > (rule->func != func && func != POST_SETATTR)) > return false; > + > + switch (func) { > + case KEY_CHECK: > + return ((rule->func == func) && > + ima_match_rule_data(rule, rule->keyrings, > + func_data, true, cred)); > + case CRITICAL_DATA: > + return ((rule->func == func) && > + ima_match_rule_data(rule, rule->data_sources, > + func_data, false, cred)); > + default: > + break; > + } > + > if ((rule->flags & IMA_MASK) && > (rule->mask != mask && func != POST_SETATTR)) > return false; > @@ -911,7 +922,7 @@ enum { > Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, > Opt_appraise_type, Opt_appraise_flag, > Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings, > - Opt_err > + Opt_data_sources, Opt_err > }; > > static const match_table_t policy_tokens = { > @@ -948,6 +959,7 @@ static const match_table_t policy_tokens = { > {Opt_pcr, "pcr=%s"}, > {Opt_template, "template=%s"}, > {Opt_keyrings, "keyrings=%s"}, > + {Opt_data_sources, "data_sources=%s"}, > {Opt_err, NULL} > }; > > @@ -1110,6 +1122,19 @@ static bool ima_validate_rule(struct ima_rule_entry *entry) > if (ima_rule_contains_lsm_cond(entry)) > return false; > > + break; > + case CRITICAL_DATA: > + if (entry->action & ~(MEASURE | DONT_MEASURE)) > + return false; > + > + if (!(entry->flags & IMA_DATA_SOURCES) || > + (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR | > + IMA_DATA_SOURCES))) > + return false; Requiring IMA_FUNC and IMA_DATA_SOURCES makes sense, but why are IMA_UID and IMA_PCR required? > + > + if (ima_rule_contains_lsm_cond(entry)) > + return false; > + > break; > default: > return false; > @@ -1242,6 +1267,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) > else if (IS_ENABLED(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) && > strcmp(args[0].from, "KEY_CHECK") == 0) > entry->func = KEY_CHECK; > + else if (strcmp(args[0].from, "CRITICAL_DATA") == 0) > + entry->func = CRITICAL_DATA; > else > result = -EINVAL; > if (!result) > @@ -1312,6 +1339,23 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) > > entry->flags |= IMA_KEYRINGS; > break; > + case Opt_data_sources: > + ima_log_string(ab, "data_sources", args[0].from); > + > + if (entry->data_sources) { > + result = -EINVAL; > + break; > + } > + > + entry->data_sources = ima_alloc_rule_opt_list(args); > + if (IS_ERR(entry->data_sources)) { > + result = PTR_ERR(entry->data_sources); > + entry->data_sources = NULL; > + break; > + } > + "keyrings=" isn't bounded because keyrings can be created by userspace. Perhaps keyring names has a minimum/maximum length. IMA isn't measuring userspace construsts. Shouldn't the list of critical data being measured be bounded and verified? Mimi > + entry->flags |= IMA_DATA_SOURCES; > + break; > case Opt_fsuuid: > ima_log_string(ab, "fsuuid", args[0].from); > > @@ -1692,6 +1736,12 @@ int ima_policy_show(struct seq_file *m, void *v) > seq_puts(m, " "); > } > > + if (entry->flags & IMA_DATA_SOURCES) { > + seq_puts(m, "data_sources="); > + ima_show_rule_opt_list(m, entry->data_sources); > + seq_puts(m, " "); > + } > + > if (entry->flags & IMA_PCR) { > snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr); > seq_printf(m, pt(Opt_pcr), tbuf);