From patchwork Sun Nov 1 22:26:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 11873127 X-Patchwork-Delegate: snitzer@redhat.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BA10C388F2 for ; Mon, 2 Nov 2020 07:58:43 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BA54921556 for ; Mon, 2 Nov 2020 07:58:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BA54921556 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: mail.kernel.org; spf=tempfail smtp.mailfrom=dm-devel-bounces@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-155-KlEL2ebrM6ec3L8rK5bDvA-1; Mon, 02 Nov 2020 02:58:39 -0500 X-MC-Unique: KlEL2ebrM6ec3L8rK5bDvA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2047C1006C98; Mon, 2 Nov 2020 07:58:32 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 03DE460C15; Mon, 2 Nov 2020 07:58:32 +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 D15C58C7AF; Mon, 2 Nov 2020 07:58:31 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 0A1MQh7D029354 for ; Sun, 1 Nov 2020 17:26:43 -0500 Received: by smtp.corp.redhat.com (Postfix) id 478281111C72; Sun, 1 Nov 2020 22:26:43 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast05.extmail.prod.ext.rdu2.redhat.com [10.11.55.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 43DF51111C6F for ; Sun, 1 Nov 2020 22:26:40 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2827B80088F for ; Sun, 1 Nov 2020 22:26:40 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-196-0fR7FBpIP7eQSa00PfxrdQ-1; Sun, 01 Nov 2020 17:26:37 -0500 X-MC-Unique: 0fR7FBpIP7eQSa00PfxrdQ-1 Received: from tusharsu-Ubuntu.lan (c-71-197-163-6.hsd1.wa.comcast.net [71.197.163.6]) by linux.microsoft.com (Postfix) with ESMTPSA id 449EF20B9C34; Sun, 1 Nov 2020 14:26:36 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 449EF20B9C34 From: Tushar Sugandhi To: zohar@linux.ibm.com, stephen.smalley.work@gmail.com, casey@schaufler-ca.com, agk@redhat.com, snitzer@redhat.com, gmazyland@gmail.com, paul@paul-moore.com Date: Sun, 1 Nov 2020 14:26:21 -0800 Message-Id: <20201101222626.6111-3-tusharsu@linux.microsoft.com> In-Reply-To: <20201101222626.6111-1-tusharsu@linux.microsoft.com> References: <20201101222626.6111-1-tusharsu@linux.microsoft.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.3 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id 0A1MQh7D029354 X-loop: dm-devel@redhat.com X-Mailman-Approved-At: Mon, 02 Nov 2020 02:58:01 -0500 Cc: sashal@kernel.org, dm-devel@redhat.com, selinux@vger.kernel.org, jmorris@namei.org, linux-kernel@vger.kernel.org, nramas@linux.microsoft.com, linux-security-module@vger.kernel.org, tyhicks@linux.microsoft.com, linux-integrity@vger.kernel.org Subject: [dm-devel] [PATCH v5 2/7] IMA: update process_buffer_measurement to measure buffer hash X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=dm-devel-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com process_buffer_measurement() currently only measures the input buffer. In case of SeLinux policy measurement, the policy being measured could be large (several MB). This may result in a large entry in IMA measurement log. Introduce a boolean parameter measure_buf_hash to support measuring hash of a buffer, which would be much smaller, instead of the buffer itself. To use the functionality introduced in this patch, the attestation client and the server changes need to go hand in hand. The client/kernel would know what data is being measured as-is (e.g. KEXEC_CMDLINE), and what data has it’s hash measured (e.g. SeLinux Policy). And the attestation server should verify data/hash accordingly. Just like the data being measured in other cases, the attestation server will know what are possible values of the large buffers being measured. e.g. the possible valid SeLinux policy values that are being pushed to the client. The attestation server will have to maintain the hash of those buffer values. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima.h | 3 ++- security/integrity/ima/ima_appraise.c | 2 +- security/integrity/ima/ima_asymmetric_keys.c | 2 +- security/integrity/ima/ima_main.c | 25 ++++++++++++++++++-- security/integrity/ima/ima_queue_keys.c | 3 ++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 8875085db689..0f77e0b697a3 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -267,7 +267,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, struct ima_template_desc *template_desc); void process_buffer_measurement(struct inode *inode, const void *buf, int size, const char *eventname, enum ima_hooks func, - int pcr, const char *func_data); + int pcr, const char *func_data, + bool measure_buf_hash); void ima_audit_measurement(struct integrity_iint_cache *iint, const unsigned char *filename); int ima_alloc_init_template(struct ima_event_data *event_data, diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 3dd8c2e4314e..be64c0bf62a7 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -347,7 +347,7 @@ int ima_check_blacklist(struct integrity_iint_cache *iint, if ((rc == -EPERM) && (iint->flags & IMA_MEASURE)) process_buffer_measurement(NULL, digest, digestsize, "blacklisted-hash", NONE, - pcr, NULL); + pcr, NULL, false); } return rc; diff --git a/security/integrity/ima/ima_asymmetric_keys.c b/security/integrity/ima/ima_asymmetric_keys.c index 1c68c500c26f..a74095793936 100644 --- a/security/integrity/ima/ima_asymmetric_keys.c +++ b/security/integrity/ima/ima_asymmetric_keys.c @@ -60,5 +60,5 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key, */ process_buffer_measurement(NULL, payload, payload_len, keyring->description, KEY_CHECK, 0, - keyring->description); + keyring->description, false); } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index ae5da9f3339d..4485d87c0aa5 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -787,12 +787,15 @@ int ima_post_load_data(char *buf, loff_t size, * @func: IMA hook * @pcr: pcr to extend the measurement * @func_data: private data specific to @func, can be NULL. + * @measure_buf_hash: if set to true - will measure hash of the buf, + * instead of buf * * Based on policy, the buffer is measured into the ima log. */ void process_buffer_measurement(struct inode *inode, const void *buf, int size, const char *eventname, enum ima_hooks func, - int pcr, const char *func_data) + int pcr, const char *func_data, + bool measure_buf_hash) { int ret = 0; const char *audit_cause = "ENOMEM"; @@ -807,6 +810,8 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, struct ima_digest_data hdr; char digest[IMA_MAX_DIGEST_SIZE]; } hash = {}; + char digest_hash[IMA_MAX_DIGEST_SIZE]; + int hash_len = hash_digest_size[ima_hash_algo]; int violation = 0; int action = 0; u32 secid; @@ -855,6 +860,21 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, goto out; } + if (measure_buf_hash) { + memcpy(digest_hash, hash.hdr.digest, hash_len); + + ret = ima_calc_buffer_hash(digest_hash, + hash_len, + iint.ima_hash); + if (ret < 0) { + audit_cause = "measure_buf_hash_error"; + goto out; + } + + event_data.buf = digest_hash; + event_data.buf_len = hash_len; + } + ret = ima_alloc_init_template(&event_data, &entry, template); if (ret < 0) { audit_cause = "alloc_entry"; @@ -896,7 +916,8 @@ void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) return; process_buffer_measurement(file_inode(f.file), buf, size, - "kexec-cmdline", KEXEC_CMDLINE, 0, NULL); + "kexec-cmdline", KEXEC_CMDLINE, 0, NULL, + false); fdput(f); } diff --git a/security/integrity/ima/ima_queue_keys.c b/security/integrity/ima/ima_queue_keys.c index 69a8626a35c0..c2f2ad34f9b7 100644 --- a/security/integrity/ima/ima_queue_keys.c +++ b/security/integrity/ima/ima_queue_keys.c @@ -162,7 +162,8 @@ void ima_process_queued_keys(void) entry->payload_len, entry->keyring_name, KEY_CHECK, 0, - entry->keyring_name); + entry->keyring_name, + false); list_del(&entry->list); ima_free_key_entry(entry); }