Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp3199148pxa; Tue, 18 Aug 2020 09:02:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwoNfIMvmHFbQu04ZsSqKG7CR0VEqfA7V5R/tyAeVumuYIXF9fXP6gOppHYLMl1Ibx9qvBF X-Received: by 2002:a17:906:7856:: with SMTP id p22mr20166593ejm.262.1597766524319; Tue, 18 Aug 2020 09:02:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597766524; cv=none; d=google.com; s=arc-20160816; b=HSW162CSnkafhMVX92kE7P4W5D8CnlSMapK3ObbXOUKazB9eIr4F629s/kkmcKNDqL f7jidJKIXXebFwpx89sm824VkPsy0NKEgQoONzZ25/9kpCaV5BZ6teDnh42eIdkR1IJt yImrDXik4sRAD7SSjnl+DfOF9dITY0UJwT2jdD32WO08zgJGGDMeil9SdQRAXTkMQKLv 49MeQ6/lz0MkpFinHKg6BEHAbboVaWZtiNTSND65LL43X73xM7Wumixex7GyL6TgEPn0 6KZEOe0S83TnLLjO/Bz7jpfQcFESUC4A0wkz4AcxavTlCfbZixTpTckYlz94Yk9JcPEg mEww== 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:message-id:date:subject:cc:to:from; bh=DWXiqbMPnYJ2XZX4kzPmPVqkYOAPC6I3TMs5+a78bk4=; b=Ll4LyUwm5vwdKv0PoH2KcsC6/HXoEqGRTmcmn50TgWZFUbAdn92IS/K4gWeFsIoOHR m6ljUY+1JCif+VmoKY5nobKP2jyM1ycKag83qN8czBLdq8YPJbDMN/FXq+GCYLh5KgFd 40hmi8pAYCQQmTGYf48KnJdSkXyM7QLZVCOxxXt1siudsy4EV2FGHqHbD5nnaI43uwm9 U+3Id07JpqMrNb3GqvasmCriURHmGqbhL4jBAeq2YG2NpgIkssoXR2Ll2PrPU5bYNycm sidvhO/g2A5eVEoid9V9CLBfJWgQJBxXe1imrjTUjmqpLEReLLl5nd8YL97JFXc+S3qM dY+Q== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id va1si13382544ejb.558.2020.08.18.09.01.39; Tue, 18 Aug 2020 09:02:04 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727063AbgHRPph (ORCPT + 99 others); Tue, 18 Aug 2020 11:45:37 -0400 Received: from lhrrgout.huawei.com ([185.176.76.210]:2637 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726971AbgHRPoe (ORCPT ); Tue, 18 Aug 2020 11:44:34 -0400 Received: from lhreml722-chm.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id F38319593CBDEE2F0A10; Tue, 18 Aug 2020 16:44:32 +0100 (IST) Received: from kstruczy-linux-box (10.204.65.138) by lhreml722-chm.china.huawei.com (10.201.108.73) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1913.5; Tue, 18 Aug 2020 16:44:31 +0100 Received: by kstruczy-linux-box (sSMTP sendmail emulation); Tue, 18 Aug 2020 17:44:33 +0200 From: To: , , , CC: , , , , , , , , , , Krzysztof Struczynski Subject: [RFC PATCH 14/30] ima: Add per namespace view of the measurement list Date: Tue, 18 Aug 2020 17:42:14 +0200 Message-ID: <20200818154230.14016-5-krzysztof.struczynski@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200818154230.14016-1-krzysztof.struczynski@huawei.com> References: <20200818154230.14016-1-krzysztof.struczynski@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.204.65.138] X-ClientProxiedBy: fraeml707-chm.china.huawei.com (10.206.15.35) To lhreml722-chm.china.huawei.com (10.201.108.73) X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Krzysztof Struczynski Modify ima securityfs interface, so that only measurement list entries that belong to the given ima namespace are visible/counted. The initial ima namespace is an exception, its processes have access to all measurement list entries. Signed-off-by: Krzysztof Struczynski --- include/linux/ima.h | 1 + security/integrity/ima/ima_fs.c | 57 ++++++++++++++++++++++++++---- security/integrity/ima/ima_init.c | 1 + security/integrity/ima/ima_ns.c | 1 + security/integrity/ima/ima_queue.c | 8 +++++ 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index df22143ffe30..d59ed38a4305 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -203,6 +203,7 @@ struct ima_namespace { struct ima_policy_data *policy_data; struct integrity_iint_tree *iint_tree; struct list_head *measurements; + atomic_long_t ml_len; /* number of stored measurements in the list */ } __randomize_layout; extern struct ima_namespace init_ima_ns; diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 4758e14c4a7b..e2893f0b0f31 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -63,7 +63,9 @@ static ssize_t ima_show_measurements_count(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { - return ima_show_htable_value(buf, count, ppos, &ima_htable.len); + struct ima_namespace *ima_ns = get_current_ns(); + + return ima_show_htable_value(buf, count, ppos, &ima_ns->ml_len); } @@ -77,10 +79,36 @@ static void *ima_measurements_start(struct seq_file *m, loff_t *pos) { loff_t l = *pos; struct ima_queue_entry *qe; + struct ima_namespace *ima_ns = get_current_ns(); + unsigned int ns_id = get_ns_id(ima_ns); + + if (ima_ns == &init_ima_ns) { + /* we need a lock since pos could point beyond last element */ + rcu_read_lock(); + list_for_each_entry_rcu(qe, &ima_measurements, later) { + if (!l--) { + rcu_read_unlock(); + return qe; + } + } + rcu_read_unlock(); + return NULL; + } - /* we need a lock since pos could point beyond last element */ rcu_read_lock(); - list_for_each_entry_rcu(qe, &ima_measurements, later) { + qe = list_next_or_null_rcu(&ima_measurements, + ima_ns->measurements, + struct ima_queue_entry, + later); + if (!qe) { + rcu_read_unlock(); + return NULL; + } + + list_for_each_entry_from_rcu(qe, &ima_measurements, later) { + if (ns_id != qe->entry->ns_id) + continue; + if (!l--) { rcu_read_unlock(); return qe; @@ -93,12 +121,27 @@ static void *ima_measurements_start(struct seq_file *m, loff_t *pos) static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos) { struct ima_queue_entry *qe = v; + struct ima_namespace *ima_ns = get_current_ns(); + unsigned int ns_id = get_ns_id(ima_ns); + + if (ima_ns == &init_ima_ns) { + /* lock protects when reading beyond last element + * against concurrent list-extension + */ + rcu_read_lock(); + qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, + later); + rcu_read_unlock(); + (*pos)++; + + return (&qe->later == &ima_measurements) ? NULL : qe; + } - /* lock protects when reading beyond last element - * against concurrent list-extension - */ rcu_read_lock(); - qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later); + list_for_each_entry_continue_rcu(qe, &ima_measurements, later) { + if (ns_id == qe->entry->ns_id) + break; + } rcu_read_unlock(); (*pos)++; diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 2100ee341dfc..ac9509d8c0f0 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -36,6 +36,7 @@ struct ima_namespace init_ima_ns = { .policy_data = &init_policy_data, .iint_tree = &init_iint_tree, .measurements = &ima_measurements, + .ml_len = ATOMIC_LONG_INIT(0), }; EXPORT_SYMBOL(init_ima_ns); diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c index f331187a4d3c..81de492baa99 100644 --- a/security/integrity/ima/ima_ns.c +++ b/security/integrity/ima/ima_ns.c @@ -126,6 +126,7 @@ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns, ns->user_ns = get_user_ns(user_ns); ns->ucounts = ucounts; ns->frozen = false; + atomic_long_set(&ns->ml_len, 0); rwlock_init(&ns->iint_tree->lock); ns->iint_tree->root = RB_ROOT; diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index bd890778c5be..ec5b3ca3ef92 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -227,6 +227,14 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, goto out; } + /* Initial ima namespace has access to all measurement list entries, + * therefore always increment its measurement list length. Other + * namespaces can see only their own entries. + */ + if (ima_ns != &init_ima_ns) + atomic_long_inc(&ima_ns->ml_len); + atomic_long_inc(&init_ima_ns.ml_len); + if (violation) /* invalidate pcr */ digests_arg = digests; -- 2.20.1