From patchwork Wed May 26 00:59:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 12280463 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 319B0C47088 for ; Wed, 26 May 2021 01:10:14 +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 9E69A61417 for ; Wed, 26 May 2021 01:10:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9E69A61417 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-230-fYS3JjEsOfe1lLfqreoSAw-1; Tue, 25 May 2021 21:10:10 -0400 X-MC-Unique: fYS3JjEsOfe1lLfqreoSAw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 02063800FF0; Wed, 26 May 2021 01:10:07 +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 D65445C1A1; Wed, 26 May 2021 01:10:06 +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 97E69180B463; Wed, 26 May 2021 01:10:06 +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 14Q19jfW020114 for ; Tue, 25 May 2021 21:09:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id B87D010F26EE; Wed, 26 May 2021 01:09:45 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast04.extmail.prod.ext.rdu2.redhat.com [10.11.55.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B3CA910F26ED for ; Wed, 26 May 2021 01:09:42 +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 0FBD2101A531 for ; Wed, 26 May 2021 01:09:42 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-406-4mxto6IhMFynb1oifFu98g-1; Tue, 25 May 2021 21:09:39 -0400 X-MC-Unique: 4mxto6IhMFynb1oifFu98g-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 17F7720B7188; Tue, 25 May 2021 18:00:04 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 17F7720B7188 From: Tushar Sugandhi To: dm-devel@redhat.com Date: Tue, 25 May 2021 17:59:48 -0700 Message-Id: <20210526005954.31564-2-tusharsu@linux.microsoft.com> In-Reply-To: <20210526005954.31564-1-tusharsu@linux.microsoft.com> References: <20210526005954.31564-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 14Q19jfW020114 X-loop: dm-devel@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, zohar@linux.ibm.com, snitzer@redhat.com, agk@redhat.com Subject: [dm-devel] [RFC 1/7] dm: measure data on table load 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.16 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 DM configures a block device with various target specific attributes passed to it as a table. DM loads the table, and calls each target’s respective constructors with the attributes as input parameters. Some of these attributes are critical to ensure the device meets certain security bar. Thus, IMA should measure these attributes, to ensure they are not tampered with, during the lifetime of the device. So that external services can have high confidence in the configuration of the block-devices on a given system. Some devices may have large tables. And a given device may change its state (table-load, suspend, resume, rename, remove, table-clear etc.) many times. Measuring these attributes each time when the device changes its state will significantly increase the size of the IMA logs. Further, once configured, these attributes are not expected to change unless a new table is loaded, or a device is removed and recreated. Therefore the clear text of the attributes should only be measured during table load, and the hash of the active/inactive table should be measured for the remaining device state changes. Measure device parameters, as well as target specific attributes, during table load, using IMA function ima_measure_critical_data(). Compute the hash of the inactive table and store it for measurements during future state change. If a load is called multiple times, update the inactive table hash with the hash of the latest populated table. So that the correct inactive table hash is measured when the device transitions to different states like resume, remove, rename etc. Signed-off-by: Tushar Sugandhi --- drivers/md/Makefile | 2 + drivers/md/dm-core.h | 5 + drivers/md/dm-ima.c | 219 ++++++++++++++++++++++++++++++++++ drivers/md/dm-ima.h | 36 ++++++ drivers/md/dm-ioctl.c | 7 ++ include/linux/device-mapper.h | 2 +- include/uapi/linux/dm-ioctl.h | 6 + 7 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 drivers/md/dm-ima.c create mode 100644 drivers/md/dm-ima.h diff --git a/drivers/md/Makefile b/drivers/md/Makefile index ef7ddc27685c..af349b7cbf8b 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -92,6 +92,8 @@ ifeq ($(CONFIG_DM_UEVENT),y) dm-mod-objs += dm-uevent.o endif +dm-mod-objs += dm-ima.o + ifeq ($(CONFIG_DM_VERITY_FEC),y) dm-verity-objs += dm-verity-fec.o endif diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h index 5953ff2bd260..f67f898803db 100644 --- a/drivers/md/dm-core.h +++ b/drivers/md/dm-core.h @@ -18,6 +18,7 @@ #include #include "dm.h" +#include "dm-ima.h" #define DM_RESERVED_MAX_IOS 1024 @@ -114,6 +115,10 @@ struct mapped_device { bool init_tio_pdu:1; struct srcu_struct io_barrier; + +#ifdef CONFIG_IMA + struct dm_ima_measurements ima; +#endif }; void disable_discard(struct mapped_device *md); diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c new file mode 100644 index 000000000000..8903e746ead6 --- /dev/null +++ b/drivers/md/dm-ima.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Microsoft Corporation + * + * Author: Tushar Sugandhi + * + * File: dm-ima.c + * Enables IMA measurements for DM targets + */ + +#include "dm-core.h" +#include "dm-ima.h" + +#include +#include +#include +#include +#include + +#define DM_MSG_PREFIX "dm-ima" + +#ifdef CONFIG_IMA +/* + * Internal function to prefix separator characters in input buffer with escape + * character, so that they don't interfere with the construction of key-value pairs, + * and clients can split the key1=value1;key2=value2; pairs properly. + */ +void fix_separator_chars(char **buf) +{ + int l = strlen(*buf); + int i, j, sp = 0; + + for (i = 0; i < l; i++) + if ((*buf)[i] == '\\' || (*buf)[i] == ';' || (*buf)[i] == '=') + sp++; + + if (sp == 0) + return; + + for (i = l-1, j = i+sp; i >= 0; i--) { + (*buf)[j--] = (*buf)[i]; + if ((*buf)[i] == '\\' || (*buf)[i] == ';' || (*buf)[i] == '=') + (*buf)[j--] = '\\'; + } +} + +/* + * Internal wrapper function to call IMA to measure DM data. + */ +void dm_ima_measure_data(const char *event_name, const void *buf, size_t buf_len) +{ + unsigned int noio_flag; + + noio_flag = memalloc_noio_save(); + ima_measure_critical_data(DM_NAME, event_name, buf, buf_len, false); + memalloc_noio_restore(noio_flag); +} + +/* + * Build up the IMA data for each target, and finally measure. + */ +void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) +{ + char *ima_buf_head = NULL, *ima_buf_cur = NULL, *device_data = NULL, *digest_buf = NULL; + size_t total_buf_len = DM_IMA_DEVICE_BUF_LEN + DM_IMA_TABLE_BUF_LEN; + unsigned int num_targets, device_data_len, i; + int desc_size, digest_size, last_i = -1, r; + char *dev_name = NULL, *dev_uuid = NULL; + status_type_t type = STATUSTYPE_IMA; + struct shash_desc *desc = NULL; + struct crypto_shash *tfm; + long ima_remaining; + sector_t capacity; + u8 *digest = NULL; + + dev_name = kzalloc(DM_NAME_LEN*2, GFP_KERNEL); + if (!dev_name) + goto error; + + dev_uuid = kzalloc(DM_UUID_LEN*2, GFP_KERNEL); + if (!dev_uuid) + goto error; + + if (dm_copy_name_and_uuid(table->md, dev_name, dev_uuid)) + goto error; + + fix_separator_chars(&dev_name); + fix_separator_chars(&dev_uuid); + + ima_buf_head = ima_buf_cur = kzalloc(total_buf_len, GFP_KERNEL); + if (!ima_buf_head) + goto error; + + device_data = kzalloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL); + if (!device_data) + goto error; + + tfm = crypto_alloc_shash("sha256", 0, 0); + if (IS_ERR(tfm)) + goto error; + + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); + digest_size = crypto_shash_digestsize(tfm); + + digest = kzalloc(digest_size, GFP_KERNEL); + if (!digest) + goto error; + + desc = kzalloc(desc_size, GFP_KERNEL); + if (!desc) + goto error; + + desc->tfm = tfm; + + num_targets = dm_table_get_num_targets(table); + capacity = get_capacity(table->md->disk); + + scnprintf(device_data, DM_IMA_DEVICE_BUF_LEN, + "name=%s;uuid=%s;capacity=%llu;major=%d;minor=%d;minor_count=%d;num_targets=%u;", + dev_name, dev_uuid, capacity, table->md->disk->major, + table->md->disk->first_minor, table->md->disk->minors, num_targets); + + device_data_len = strlen(device_data); + memcpy(ima_buf_cur, device_data, device_data_len); + ima_buf_cur += device_data_len; + + for (i = 0; i < num_targets; i++) { + struct dm_target *ti = dm_table_get_target(table, i); + size_t l = 0; + + ima_remaining = total_buf_len - (ima_buf_cur - ima_buf_head); + + if (ti->type->status) + ti->type->status(ti, type, status_flags, ima_buf_cur, ima_remaining); + else + ima_buf_cur[0] = '\0'; + + l = strlen(ima_buf_cur); + + ima_remaining -= (l+1); + + if (ima_remaining > 0) { + ima_buf_cur += l; + last_i = -1; + continue; + } + + if (unlikely(i == last_i)) { + /* IMA measurements for DM targets are best-effort. + * If the IMA data from current target type is too large to fit + * into total_buf_len, measure what we have in the current buffer, and bail-out. + */ + DMERR("IMA data for %s target too large.", ti->type->name); + break; + } + /* The buffer ima_buf_head is full if we reach here. + * In this case, measure the current buffer, free it, and reallocate a new buffer, + * and continue measuring the remaining targets in the table. + */ + ima_buf_cur[0] = '\0'; + dm_ima_measure_data("table_load", ima_buf_head, strlen(ima_buf_head)); + crypto_shash_update(desc, (const u8 *)ima_buf_head, strlen(ima_buf_head)); + kfree(ima_buf_head); + ima_buf_head = ima_buf_cur = kzalloc(total_buf_len, GFP_KERNEL); + if (!ima_buf_head) + goto error; + /* + * Each new "table_load" entry in IMA log should have device data prefix, + * so that multiple records from the same table load can be linked together. + */ + memcpy(ima_buf_cur, device_data, device_data_len); + ima_buf_cur += device_data_len; + + last_i = i; + i--; + } + + dm_ima_measure_data("table_load", ima_buf_head, strlen(ima_buf_head)); + + kfree(table->md->ima.inactive_table_hash); + table->md->ima.inactive_table_hash = NULL; + table->md->ima.inactive_table_hash_len = 0; + + r = crypto_shash_update(desc, (const u8 *)ima_buf_head, strlen(ima_buf_head)); + if (r < 0) + goto error; + + r = crypto_shash_final(desc, digest); + if (r < 0) + goto error; + + digest_buf = kzalloc((digest_size*2)+1, GFP_KERNEL); + if (!digest_buf) + goto error; + + for (i = 0; i < digest_size; i++) + snprintf((digest_buf+(i*2)), 3, "%02x", digest[i]); + + table->md->ima.inactive_table_hash = digest_buf; + table->md->ima.inactive_table_hash_len = strlen(digest_buf); + table->md->ima.device_data = device_data; + table->md->ima.device_data_len = device_data_len; + table->md->ima.num_targets = num_targets; + +error: + kfree(dev_name); + kfree(dev_uuid); + kfree(digest); + kfree(desc); + crypto_free_shash(tfm); + kfree(ima_buf_head); +} + +#else +void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) {} +#endif +MODULE_AUTHOR("Tushar Sugandhi "); +MODULE_DESCRIPTION("Enables IMA measurements for DM targets"); +MODULE_LICENSE("GPL"); diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h new file mode 100644 index 000000000000..a71e0682fcb9 --- /dev/null +++ b/drivers/md/dm-ima.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2021 Microsoft Corporation + * + * Author: Tushar Sugandhi + * + * File: dm-ima.h + * Header file for device mapper IMA measurements. + */ + +#ifndef DM_IMA_H +#define DM_IMA_H + +#define DM_IMA_TABLE_BUF_LEN 4096 +#define DM_IMA_DEVICE_BUF_LEN 1024 + +struct dm_ima_measurements { + /* Contains data specific to the device which is common across + * all the targets in the table.e.g. name, uuid, major, minor, capacity etc. + * The values are stored in semicolon separated key=value; pairs. + */ + char *device_data; + unsigned int device_data_len; + unsigned int num_targets; + + /* Contains the sha256 hashs of the IMA measurements of the + * target attributes key-value pairs from the active/inactive tables. + */ + char *active_table_hash; + unsigned int active_table_hash_len; + char *inactive_table_hash; + unsigned int inactive_table_hash_len; +}; + +void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags); +#endif /*DM_IMA_H*/ diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 2209cbcd84db..21deff8513a7 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -21,6 +21,9 @@ #include +#include +#include "dm-ima.h" + #define DM_MSG_PREFIX "ioctl" #define DM_DRIVER_EMAIL "dm-devel@redhat.com" @@ -1224,6 +1227,8 @@ static void retrieve_status(struct dm_table *table, if (param->flags & DM_STATUS_TABLE_FLAG) type = STATUSTYPE_TABLE; + else if (param->flags & DM_IMA_MEASUREMENT_FLAG) + type = STATUSTYPE_IMA; else type = STATUSTYPE_INFO; @@ -1391,6 +1396,8 @@ static int populate_table(struct dm_table *table, next = spec->next; } + dm_ima_measure_on_table_load(table, STATUSTYPE_IMA); + return dm_table_complete(table); } diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index ff700fb6ce1d..738a7d023650 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -31,7 +31,7 @@ enum dm_queue_mode { DM_TYPE_DAX_BIO_BASED = 3, }; -typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t; +typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE, STATUSTYPE_IMA } status_type_t; union map_info { void *ptr; diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h index e5c6e458bdf7..c12ce30b52df 100644 --- a/include/uapi/linux/dm-ioctl.h +++ b/include/uapi/linux/dm-ioctl.h @@ -376,4 +376,10 @@ enum { */ #define DM_INTERNAL_SUSPEND_FLAG (1 << 18) /* Out */ +/* + * If set, returns in the in buffer passed by UM, the raw table information + * that would be measured by IMA subsystem on device state change. + */ +#define DM_IMA_MEASUREMENT_FLAG (1 << 19) /* In */ + #endif /* _LINUX_DM_IOCTL_H */ From patchwork Wed May 26 00:59:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 12280461 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 1FA85C4707F for ; Wed, 26 May 2021 01:10:14 +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-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8C1A161429 for ; Wed, 26 May 2021 01:10:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8C1A161429 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-523-04SBYUqlM1atvtDt_pXX8A-1; Tue, 25 May 2021 21:10:09 -0400 X-MC-Unique: 04SBYUqlM1atvtDt_pXX8A-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9EE9B80D683; Wed, 26 May 2021 01:10:04 +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 77501101E24A; Wed, 26 May 2021 01:10:04 +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 304535534D; Wed, 26 May 2021 01:10:04 +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 14Q19jOA020100 for ; Tue, 25 May 2021 21:09:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id 42F06208AB60; Wed, 26 May 2021 01:09:45 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast02.extmail.prod.ext.rdu2.redhat.com [10.11.55.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3E17E208AB70 for ; Wed, 26 May 2021 01:09:42 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.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 16C5D800B26 for ; Wed, 26 May 2021 01:09:42 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-155-GHL0CSEDNVuWJ5ia9EaosA-1; Tue, 25 May 2021 21:09:39 -0400 X-MC-Unique: GHL0CSEDNVuWJ5ia9EaosA-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 75F0420B8006; Tue, 25 May 2021 18:00:04 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 75F0420B8006 From: Tushar Sugandhi To: dm-devel@redhat.com Date: Tue, 25 May 2021 17:59:49 -0700 Message-Id: <20210526005954.31564-3-tusharsu@linux.microsoft.com> In-Reply-To: <20210526005954.31564-1-tusharsu@linux.microsoft.com> References: <20210526005954.31564-1-tusharsu@linux.microsoft.com> 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: dm-devel@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, zohar@linux.ibm.com, snitzer@redhat.com, agk@redhat.com Subject: [dm-devel] [RFC 2/7] dm: measure data on device resume 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: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 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 A given block device can load a table multiple times, with different input parameters, before eventually resuming it. Further, a device may be suspended and then resumed. The device may never resume after a table-load. Because of the above valid scenarios for a given device, it is important to measure and log the device resume event using IMA. Also, if the table is large, measuring it in clear-text each time the device changes state, will unnecessarily increase the size of IMA log. Since the table clear-text is already measured during table-load event, measuring the hash during resume should be sufficient to validate the table contents. Measure the device parameters, and hash of the active table, when the device is resumed. Signed-off-by: Tushar Sugandhi --- drivers/md/dm-ima.c | 47 +++++++++++++++++++++++++++++++++++++++++++ drivers/md/dm-ima.h | 1 + drivers/md/dm-ioctl.c | 8 ++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c index 8903e746ead6..b244a7fd58fe 100644 --- a/drivers/md/dm-ima.c +++ b/drivers/md/dm-ima.c @@ -211,8 +211,55 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl kfree(ima_buf_head); } +/* + * Measure IMA data on device resume + */ +void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) +{ + char *device_table_data; + unsigned int noio_flag, l; + char active[] = "active_table_hash="; + unsigned int active_len = strlen(active); + + noio_flag = memalloc_noio_save(); + device_table_data = kzalloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL); + memalloc_noio_restore(noio_flag); + + if (!device_table_data) + return; + + if (swap) { + kfree(md->ima.active_table_hash); + md->ima.active_table_hash = NULL; + md->ima.active_table_hash_len = 0; + + if (md->ima.inactive_table_hash) { + md->ima.active_table_hash = md->ima.inactive_table_hash; + md->ima.active_table_hash_len = md->ima.inactive_table_hash_len; + md->ima.inactive_table_hash = NULL; + md->ima.inactive_table_hash_len = 0; + } + } + + l = md->ima.device_data_len; + memcpy(device_table_data, md->ima.device_data, l); + memcpy(device_table_data + l, active, active_len); + l += active_len; + + memcpy(device_table_data + l, md->ima.active_table_hash, md->ima.active_table_hash_len); + l += md->ima.active_table_hash_len; + + memcpy(device_table_data + l, ";", 1); + l++; + + dm_ima_measure_data("device_resume", device_table_data, l); + + kfree(device_table_data); +} + #else void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) {} +void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) {} #endif MODULE_AUTHOR("Tushar Sugandhi "); MODULE_DESCRIPTION("Enables IMA measurements for DM targets"); diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h index a71e0682fcb9..1cd0c76e0379 100644 --- a/drivers/md/dm-ima.h +++ b/drivers/md/dm-ima.h @@ -33,4 +33,5 @@ struct dm_ima_measurements { }; void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags); +void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap); #endif /*DM_IMA_H*/ diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 21deff8513a7..e06e256d1a7e 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1162,8 +1162,12 @@ static int do_resume(struct dm_ioctl *param) if (dm_suspended_md(md)) { r = dm_resume(md); - if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) - param->flags |= DM_UEVENT_GENERATED_FLAG; + if (!r) { + dm_ima_measure_on_device_resume(md, new_map ? true : false); + + if (!dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) + param->flags |= DM_UEVENT_GENERATED_FLAG; + } } /* From patchwork Wed May 26 00:59:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 12280455 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 ACEB7C47088 for ; Wed, 26 May 2021 01:09:56 +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 49A626142B for ; Wed, 26 May 2021 01:09:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 49A626142B 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-214-VWO8qPcINISRtnZN94A23w-1; Tue, 25 May 2021 21:09:53 -0400 X-MC-Unique: VWO8qPcINISRtnZN94A23w-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B8D781009465; Wed, 26 May 2021 01:09:49 +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 95BB0100EBAF; Wed, 26 May 2021 01:09:49 +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 8299C1801029; Wed, 26 May 2021 01:09:48 +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 14Q19j3N020099 for ; Tue, 25 May 2021 21:09:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id 43019208AB65; Wed, 26 May 2021 01:09:45 +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 3E0F8208AB6F for ; Wed, 26 May 2021 01:09:43 +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 0B34F833942 for ; Wed, 26 May 2021 01:09:43 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-418-14ofU0RdOIOOsjCX16t9AA-1; Tue, 25 May 2021 21:09:40 -0400 X-MC-Unique: 14ofU0RdOIOOsjCX16t9AA-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 C6B8120B8008; Tue, 25 May 2021 18:00:04 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C6B8120B8008 From: Tushar Sugandhi To: dm-devel@redhat.com Date: Tue, 25 May 2021 17:59:50 -0700 Message-Id: <20210526005954.31564-4-tusharsu@linux.microsoft.com> In-Reply-To: <20210526005954.31564-1-tusharsu@linux.microsoft.com> References: <20210526005954.31564-1-tusharsu@linux.microsoft.com> 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: dm-devel@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, zohar@linux.ibm.com, snitzer@redhat.com, agk@redhat.com Subject: [dm-devel] [RFC 3/7] dm: measure data on device remove 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: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 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 Presence of an active block-device, configured with expected parameters, is important for an external attestation service to determine if a system meets the attestation requirements. Therefore it is important for DM to measure the device remove events. Measure device parameters, and table hashes when the device is removed. Signed-off-by: Tushar Sugandhi --- drivers/md/dm-ima.c | 56 +++++++++++++++++++++++++++++++++++++++++++ drivers/md/dm-ima.h | 1 + drivers/md/dm-ioctl.c | 2 ++ 3 files changed, 59 insertions(+) diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c index b244a7fd58fe..a93387beda9e 100644 --- a/drivers/md/dm-ima.c +++ b/drivers/md/dm-ima.c @@ -257,9 +257,65 @@ void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) kfree(device_table_data); } +/* + * Measure IMA data on remove + */ +void dm_ima_measure_on_device_remove(struct mapped_device *md) +{ + unsigned int noio_flag, l; + char *dev_table_data; + char active[] = "active_table_hash="; + char inactive[] = "inactive_table_hash="; + unsigned int active_len = strlen(active); + unsigned int inactive_len = strlen(inactive); + + noio_flag = memalloc_noio_save(); + dev_table_data = kzalloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL); + memalloc_noio_restore(noio_flag); + + if (!dev_table_data) + goto bad; + l = strlen(md->ima.device_data); + memcpy(dev_table_data, md->ima.device_data, l); + + if (md->ima.active_table_hash) { + memcpy(dev_table_data + l, active, active_len); + l += active_len; + + memcpy(dev_table_data + l, + md->ima.active_table_hash, + md->ima.active_table_hash_len); + l += md->ima.active_table_hash_len; + + memcpy(dev_table_data + l, ";", 1); + l++; + } + + if (md->ima.inactive_table_hash) { + memcpy(dev_table_data + l, inactive, inactive_len); + l += inactive_len; + + memcpy(dev_table_data + l, + md->ima.inactive_table_hash, + md->ima.inactive_table_hash_len); + + l += md->ima.inactive_table_hash_len; + + memcpy(dev_table_data + l, ";", 1); + l++; + } + + dm_ima_measure_data("device_remove", dev_table_data, l); + + kfree(dev_table_data); +bad: + kfree(md->ima.device_data); +} + #else void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) {} void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) {} +void dm_ima_measure_on_device_remove(struct mapped_device *md) {} #endif MODULE_AUTHOR("Tushar Sugandhi "); MODULE_DESCRIPTION("Enables IMA measurements for DM targets"); diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h index 1cd0c76e0379..974b14361958 100644 --- a/drivers/md/dm-ima.h +++ b/drivers/md/dm-ima.h @@ -34,4 +34,5 @@ struct dm_ima_measurements { void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags); void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap); +void dm_ima_measure_on_device_remove(struct mapped_device *md); #endif /*DM_IMA_H*/ diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index e06e256d1a7e..cb6392c156c2 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -984,6 +984,8 @@ static int dev_remove(struct file *filp, struct dm_ioctl *param, size_t param_si param->flags &= ~DM_DEFERRED_REMOVE; + dm_ima_measure_on_device_remove(md); + if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr)) param->flags |= DM_UEVENT_GENERATED_FLAG; From patchwork Wed May 26 00:59:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 12280467 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 F27ECC47087 for ; Wed, 26 May 2021 01:10:20 +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-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8281361417 for ; Wed, 26 May 2021 01:10:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8281361417 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-379--1RFVhoNOVW4O8fdyT9T9A-1; Tue, 25 May 2021 21:10:16 -0400 X-MC-Unique: -1RFVhoNOVW4O8fdyT9T9A-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 937AE8030A1; Wed, 26 May 2021 01:10:11 +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 770046E418; Wed, 26 May 2021 01:10:11 +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 4451F1801264; Wed, 26 May 2021 01:10:11 +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 14Q19otw020152 for ; Tue, 25 May 2021 21:09:50 -0400 Received: by smtp.corp.redhat.com (Postfix) id 6387F208AB60; Wed, 26 May 2021 01:09:50 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast02.extmail.prod.ext.rdu2.redhat.com [10.11.55.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5F6C7208AB6F for ; Wed, 26 May 2021 01:09:50 +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 48E0A800B26 for ; Wed, 26 May 2021 01:09:50 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-232-RvZUpjnoM3-PgUAey4ZSsg-1; Tue, 25 May 2021 21:09:40 -0400 X-MC-Unique: RvZUpjnoM3-PgUAey4ZSsg-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 502FB20B800A; Tue, 25 May 2021 18:00:05 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 502FB20B800A From: Tushar Sugandhi To: dm-devel@redhat.com Date: Tue, 25 May 2021 17:59:51 -0700 Message-Id: <20210526005954.31564-5-tusharsu@linux.microsoft.com> In-Reply-To: <20210526005954.31564-1-tusharsu@linux.microsoft.com> References: <20210526005954.31564-1-tusharsu@linux.microsoft.com> 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: dm-devel@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, zohar@linux.ibm.com, snitzer@redhat.com, agk@redhat.com Subject: [dm-devel] [RFC 4/7] dm: measure data on table clear 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: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-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=dm-devel-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com For a given block device, an inactive table slot contains the parameters to configure the device with. The inactive table can be cleared multiple times, accidentally or maliciously, which may impact the functionality of the device, and compromise the system. Therefore it is important to measure and log the event when a table is cleared. Measure device parameters, and table hashes when the inactive table slot is cleared. Signed-off-by: Tushar Sugandhi --- drivers/md/dm-ima.c | 50 +++++++++++++++++++++++++++++++++++++++++++ drivers/md/dm-ima.h | 2 ++ drivers/md/dm-ioctl.c | 3 +++ 3 files changed, 55 insertions(+) diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c index a93387beda9e..6670b5f74004 100644 --- a/drivers/md/dm-ima.c +++ b/drivers/md/dm-ima.c @@ -312,10 +312,60 @@ void dm_ima_measure_on_device_remove(struct mapped_device *md) kfree(md->ima.device_data); } +/* + * measure ima data on table clear + */ +void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) +{ + unsigned int noio_flag, l; + char *device_table_data; + char inactive[] = "inactive_table_hash="; + unsigned int inactive_len = strlen(inactive); + + noio_flag = memalloc_noio_save(); + device_table_data = kzalloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL); + memalloc_noio_restore(noio_flag); + + if (!device_table_data) + goto bad; + + l = strlen(md->ima.device_data); + memcpy(device_table_data, md->ima.device_data, l); + memcpy(device_table_data + l, inactive, inactive_len); + l += inactive_len; + + memcpy(device_table_data + l, md->ima.inactive_table_hash, + md->ima.inactive_table_hash_len); + + l += md->ima.inactive_table_hash_len; + + memcpy(device_table_data + l, ";", 1); + l++; + + dm_ima_measure_data("table_clear", device_table_data, l); + + if (new_map) { + kfree(md->ima.inactive_table_hash); + md->ima.inactive_table_hash = NULL; + md->ima.inactive_table_hash_len = 0; + + if (md->ima.active_table_hash) { + md->ima.inactive_table_hash = md->ima.active_table_hash; + md->ima.inactive_table_hash_len = md->ima.active_table_hash_len; + } + + } + + kfree(device_table_data); +bad: + return; +} + #else void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) {} void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) {} void dm_ima_measure_on_device_remove(struct mapped_device *md) {} +void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) {} #endif MODULE_AUTHOR("Tushar Sugandhi "); MODULE_DESCRIPTION("Enables IMA measurements for DM targets"); diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h index 974b14361958..ed633e031a18 100644 --- a/drivers/md/dm-ima.h +++ b/drivers/md/dm-ima.h @@ -35,4 +35,6 @@ struct dm_ima_measurements { void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags); void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap); void dm_ima_measure_on_device_remove(struct mapped_device *md); +void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map); + #endif /*DM_IMA_H*/ diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index cb6392c156c2..b4f47d596985 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1509,6 +1509,7 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s struct hash_cell *hc; struct mapped_device *md; struct dm_table *old_map = NULL; + bool has_new_map = false; down_write(&_hash_lock); @@ -1522,6 +1523,7 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s if (hc->new_map) { old_map = hc->new_map; hc->new_map = NULL; + has_new_map = true; } param->flags &= ~DM_INACTIVE_PRESENT_FLAG; @@ -1533,6 +1535,7 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s dm_sync_table(md); dm_table_destroy(old_map); } + dm_ima_measure_on_table_clear(md, has_new_map); dm_put(md); return 0; From patchwork Wed May 26 00:59:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 12280457 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 3AC60C4707F for ; Wed, 26 May 2021 01:09:59 +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 C8920613F1 for ; Wed, 26 May 2021 01:09:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C8920613F1 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-508-0zcvLVgcNZqiJcvCsZ280w-1; Tue, 25 May 2021 21:09:53 -0400 X-MC-Unique: 0zcvLVgcNZqiJcvCsZ280w-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 9AA9818358F3; Wed, 26 May 2021 01:09:49 +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 AB46460C04; Wed, 26 May 2021 01:09:48 +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 F3C20180B464; Wed, 26 May 2021 01:09:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 14Q19iT5020088 for ; Tue, 25 May 2021 21:09:44 -0400 Received: by smtp.corp.redhat.com (Postfix) id 174E420287CC; Wed, 26 May 2021 01:09:44 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1230820287A8 for ; Wed, 26 May 2021 01:09:41 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) (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 A98DC80D0E0 for ; Wed, 26 May 2021 01:09:41 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-228-Eeg7Cw8ZPlaXqqdbzWoTcQ-1; Tue, 25 May 2021 21:09:39 -0400 X-MC-Unique: Eeg7Cw8ZPlaXqqdbzWoTcQ-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 9FAD520B800D; Tue, 25 May 2021 18:00:05 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 9FAD520B800D From: Tushar Sugandhi To: dm-devel@redhat.com Date: Tue, 25 May 2021 17:59:52 -0700 Message-Id: <20210526005954.31564-6-tusharsu@linux.microsoft.com> In-Reply-To: <20210526005954.31564-1-tusharsu@linux.microsoft.com> References: <20210526005954.31564-1-tusharsu@linux.microsoft.com> 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.6 X-loop: dm-devel@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, zohar@linux.ibm.com, snitzer@redhat.com, agk@redhat.com Subject: [dm-devel] [RFC 5/7] dm: measure data on device rename 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: , MIME-Version: 1.0 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 A given block device is identified by it's name and UUID. However, both these parameters can be renamed. For an external attestation service to correctly attest a given device, it needs to keep track of these rename events. Fix if there are any separator characters in the new name/UUID. Update the device data for IMA with the new values. Measure both old device data and the new device name/UUID parameters in the same IMA measurement event, so that the old and new values can be connected later. Signed-off-by: Tushar Sugandhi --- drivers/md/dm-ima.c | 70 +++++++++++++++++++++++++++++++++++++++++++ drivers/md/dm-ima.h | 1 + drivers/md/dm-ioctl.c | 3 ++ 3 files changed, 74 insertions(+) diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c index 6670b5f74004..511d471648a1 100644 --- a/drivers/md/dm-ima.c +++ b/drivers/md/dm-ima.c @@ -361,11 +361,81 @@ void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) return; } +/* + * Measure IMA data on device rename + */ +void dm_ima_measure_on_device_rename(struct mapped_device *md) +{ + char *old_device_data = NULL, *new_device_data = NULL, *combined_device_data = NULL; + char *new_dev_name = NULL, *new_dev_uuid = NULL; + unsigned int noio_flag; + sector_t capacity; + + noio_flag = memalloc_noio_save(); + new_device_data = kzalloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL); + memalloc_noio_restore(noio_flag); + + if (!new_device_data) + return; + + noio_flag = memalloc_noio_save(); + new_dev_name = kzalloc(DM_NAME_LEN*2, GFP_KERNEL); + memalloc_noio_restore(noio_flag); + if (!new_dev_name) + goto error; + + memalloc_noio_restore(noio_flag); + new_dev_uuid = kzalloc(DM_UUID_LEN*2, GFP_KERNEL); + memalloc_noio_restore(noio_flag); + if (!new_dev_uuid) + goto error; + + if (dm_copy_name_and_uuid(md, new_dev_name, new_dev_uuid)) + goto error; + + fix_separator_chars(&new_dev_name); + fix_separator_chars(&new_dev_uuid); + + noio_flag = memalloc_noio_save(); + combined_device_data = kzalloc(DM_IMA_DEVICE_BUF_LEN * 2, GFP_KERNEL); + memalloc_noio_restore(noio_flag); + + if (!combined_device_data) + goto error; + + capacity = get_capacity(md->disk); + + old_device_data = md->ima.device_data; + + scnprintf(new_device_data, DM_IMA_DEVICE_BUF_LEN, + "name=%s;uuid=%s;capacity=%llu;major=%d;minor=%d;minor_count=%d;num_targets=%u;", + new_dev_name, new_dev_uuid, capacity, md->disk->major, md->disk->first_minor, + md->disk->minors, md->ima.num_targets); + md->ima.device_data = new_device_data; + md->ima.device_data_len = strlen(new_device_data); + + scnprintf(combined_device_data, DM_IMA_DEVICE_BUF_LEN * 2, "%snew_name=%s;new_uuid=%s;", + old_device_data, new_dev_name, new_dev_uuid); + + dm_ima_measure_data("device_rename", combined_device_data, strlen(combined_device_data)); + + goto exit; + +error: + kfree(new_device_data); +exit: + kfree(combined_device_data); + kfree(old_device_data); + kfree(new_dev_name); + kfree(new_dev_uuid); +} + #else void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) {} void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) {} void dm_ima_measure_on_device_remove(struct mapped_device *md) {} void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) {} +void dm_ima_measure_on_device_rename(struct mapped_device *md) {} #endif MODULE_AUTHOR("Tushar Sugandhi "); MODULE_DESCRIPTION("Enables IMA measurements for DM targets"); diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h index ed633e031a18..340032f1d07f 100644 --- a/drivers/md/dm-ima.h +++ b/drivers/md/dm-ima.h @@ -36,5 +36,6 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap); void dm_ima_measure_on_device_remove(struct mapped_device *md); void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map); +void dm_ima_measure_on_device_rename(struct mapped_device *md); #endif /*DM_IMA_H*/ diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index b4f47d596985..9d8258dd014e 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -486,6 +486,9 @@ static struct mapped_device *dm_hash_rename(struct dm_ioctl *param, param->flags |= DM_UEVENT_GENERATED_FLAG; md = hc->md; + + dm_ima_measure_on_device_rename(md); + up_write(&_hash_lock); kfree(old_name); From patchwork Wed May 26 00:59:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 12280459 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 4872BC4707F for ; Wed, 26 May 2021 01:10:10 +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 C247961417 for ; Wed, 26 May 2021 01:10:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C247961417 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-344-EhOnhtTvO7Onk3a5cZHZYw-1; Tue, 25 May 2021 21:10:06 -0400 X-MC-Unique: EhOnhtTvO7Onk3a5cZHZYw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D6932107ACC7; Wed, 26 May 2021 01:10:02 +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 AB6EA101E24A; Wed, 26 May 2021 01:10:02 +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 7862655348; Wed, 26 May 2021 01:10:02 +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 14Q19jiO020101 for ; Tue, 25 May 2021 21:09:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id 4573E208AB66; Wed, 26 May 2021 01:09:45 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3EF00208AB75 for ; Wed, 26 May 2021 01:09:42 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.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 DDC8480D0E1 for ; Wed, 26 May 2021 01:09:41 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-261-H8L96rZJNvWBKumkfMYogw-1; Tue, 25 May 2021 21:09:39 -0400 X-MC-Unique: H8L96rZJNvWBKumkfMYogw-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 00D0C20B8010; Tue, 25 May 2021 18:00:05 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 00D0C20B8010 From: Tushar Sugandhi To: dm-devel@redhat.com Date: Tue, 25 May 2021 17:59:53 -0700 Message-Id: <20210526005954.31564-7-tusharsu@linux.microsoft.com> In-Reply-To: <20210526005954.31564-1-tusharsu@linux.microsoft.com> References: <20210526005954.31564-1-tusharsu@linux.microsoft.com> 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: dm-devel@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, zohar@linux.ibm.com, snitzer@redhat.com, agk@redhat.com Subject: [dm-devel] [RFC 6/7] dm: update target specific status functions to measure data 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: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 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 For device mapper targets to take advantage of IMA's measurement capabilities, the status functions for the individual targets need to be updated to handle the status_type_t case for value STATUSTYPE_IMA. Update status functions for the following target types, to log their respective attributes to be measured using IMA. 01. cache 02. crypt 03. integrity 04. linear 05. mirror 06. multipath 07. raid 08. snapshot 09. striped 10. verity For rest of the targets, handle the STATUSTYPE_IMA case by setting the measurement buffer to NULL. For IMA to measure the data on a given system, the IMA policy on the system needs to be updated to have the following line, and the system needs to be restarted for the measurements to take effect. /etc/ima/ima-policy measure func=CRITICAL_DATA label=device-mapper template=ima-buf The measurements will be reflected in the IMA logs, which are located at: /sys/kernel/security/integrity/ima/ascii_runtime_measurements /sys/kernel/security/integrity/ima/binary_runtime_measurements These IMA logs can later be consumed by various attestation clients running on the system, and send them to external services for attesting the system. Signed-off-by: Tushar Sugandhi --- drivers/md/dm-cache-target.c | 30 +++++++++++++ drivers/md/dm-clone-target.c | 7 +++ drivers/md/dm-crypt.c | 50 ++++++++++++++++++++++ drivers/md/dm-delay.c | 4 ++ drivers/md/dm-dust.c | 4 ++ drivers/md/dm-ebs-target.c | 3 ++ drivers/md/dm-era-target.c | 4 ++ drivers/md/dm-flakey.c | 4 ++ drivers/md/dm-integrity.c | 38 ++++++++++++++++ drivers/md/dm-linear.c | 8 ++++ drivers/md/dm-log-userspace-base.c | 3 ++ drivers/md/dm-log-writes.c | 4 ++ drivers/md/dm-log.c | 10 +++++ drivers/md/dm-mpath.c | 29 +++++++++++++ drivers/md/dm-ps-historical-service-time.c | 3 ++ drivers/md/dm-ps-io-affinity.c | 3 ++ drivers/md/dm-ps-queue-length.c | 3 ++ drivers/md/dm-ps-round-robin.c | 4 ++ drivers/md/dm-ps-service-time.c | 3 ++ drivers/md/dm-raid.c | 42 ++++++++++++++++++ drivers/md/dm-raid1.c | 18 ++++++++ drivers/md/dm-snap-persistent.c | 4 ++ drivers/md/dm-snap-transient.c | 4 ++ drivers/md/dm-snap.c | 16 +++++++ drivers/md/dm-stripe.c | 15 +++++++ drivers/md/dm-switch.c | 4 ++ drivers/md/dm-thin.c | 8 ++++ drivers/md/dm-unstripe.c | 4 ++ drivers/md/dm-verity-target.c | 46 ++++++++++++++++++++ drivers/md/dm-writecache.c | 3 ++ drivers/md/dm-zoned-target.c | 3 ++ include/linux/device-mapper.h | 4 ++ 32 files changed, 385 insertions(+) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 6ab01ff25747..7cb089fd416e 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -3192,6 +3192,36 @@ static void cache_status(struct dm_target *ti, status_type_t type, DMEMIT(" %s", cache->ctr_args[i]); if (cache->nr_ctr_args) DMEMIT(" %s", cache->ctr_args[cache->nr_ctr_args - 1]); + break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + if (get_cache_mode(cache) == CM_FAIL) + DMEMIT("metadata_mode=fail;"); + else if (get_cache_mode(cache) == CM_READ_ONLY) + DMEMIT("metadata_mode=ro;"); + else + DMEMIT("metadata_mode=rw;"); + + format_dev_t(buf, cache->metadata_dev->bdev->bd_dev); + DMEMIT("cache_metadata_device=%s;", buf); + format_dev_t(buf, cache->cache_dev->bdev->bd_dev); + DMEMIT("cache_device=%s;", buf); + format_dev_t(buf, cache->origin_dev->bdev->bd_dev); + DMEMIT("cache_origin_device=%s;", buf); + + for (i = 0; i < cache->nr_ctr_args - 1; i++) { + if (!strcmp(cache->ctr_args[i], "writethrough")) + DMEMIT("writethrough=y;"); + else if (!strcmp(cache->ctr_args[i], "passthrough")) + DMEMIT("passthrough=y;"); + else if (!strcmp(cache->ctr_args[i], "metadata2")) + DMEMIT("metadata2=y;"); + else if (!strcmp(cache->ctr_args[i], "no_discard_passdown")) + DMEMIT("no_discard_passdown=y;"); + } + break; } return; diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c index a90bdf9b2ca6..e5dc68f18ee6 100644 --- a/drivers/md/dm-clone-target.c +++ b/drivers/md/dm-clone-target.c @@ -1499,6 +1499,13 @@ static void clone_status(struct dm_target *ti, status_type_t type, for (i = 0; i < clone->nr_ctr_args; i++) DMEMIT(" %s", clone->ctr_args[i]); + + break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + + break; } return; diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index b0ab080f2567..5d179c57a55a 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -3473,6 +3473,56 @@ static void crypt_status(struct dm_target *ti, status_type_t type, DMEMIT(" iv_large_sectors"); } + break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + if (ti->num_discard_bios) + DMEMIT("allow_discards=y;"); + else + DMEMIT("allow_discards=n;"); + + if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) + DMEMIT("same_cpu=y;"); + else + DMEMIT("same_cpu=n;"); + + if (test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags)) + DMEMIT("submit_from_crypt_cpus=y;"); + else + DMEMIT("submit_from_crypt_cpus=n;"); + + if (test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)) + DMEMIT("no_read_workqueue=y;"); + else + DMEMIT("no_read_workqueue=n;"); + + if (test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags)) + DMEMIT("no_write_workqueue=y;"); + else + DMEMIT("no_write_workqueue=n;"); + + if (cc->on_disk_tag_size) + DMEMIT("integrity_tag_size=%u;cipher_auth=%s;", + cc->on_disk_tag_size, cc->cipher_auth); + + if (cc->sector_size != (1 << SECTOR_SHIFT)) + DMEMIT("sector_size=%d;", cc->sector_size); + + if (test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags)) + DMEMIT("iv_large_sectors=y;"); + else + DMEMIT("iv_large_sectors=y;"); + + if (cc->cipher_string) + DMEMIT("cipher_string=%s;", cc->cipher_string); + + DMEMIT("key_size=%u;", cc->key_size); + DMEMIT("key_parts=%u;", cc->key_parts); + DMEMIT("key_extra_size=%u;", cc->key_extra_size); + DMEMIT("key_mac_size=%u;", cc->key_mac_size); + break; } } diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index 2628a832787b..76c0bed73840 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c @@ -326,6 +326,10 @@ static void delay_status(struct dm_target *ti, status_type_t type, DMEMIT_DELAY_CLASS(&dc->flush); } break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-dust.c b/drivers/md/dm-dust.c index cbe1058ee589..5e455da70678 100644 --- a/drivers/md/dm-dust.c +++ b/drivers/md/dm-dust.c @@ -527,6 +527,10 @@ static void dust_status(struct dm_target *ti, status_type_t type, DMEMIT("%s %llu %u", dd->dev->name, (unsigned long long)dd->start, dd->blksz); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-ebs-target.c b/drivers/md/dm-ebs-target.c index 71475a2410be..6b42bdaf0ce2 100644 --- a/drivers/md/dm-ebs-target.c +++ b/drivers/md/dm-ebs-target.c @@ -401,6 +401,9 @@ static void ebs_status(struct dm_target *ti, status_type_t type, snprintf(result, maxlen, ec->u_bs_set ? "%s %llu %u %u" : "%s %llu %u", ec->dev->name, (unsigned long long) ec->start, ec->e_bs, ec->u_bs); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c index d9ac7372108c..9d2d072729c0 100644 --- a/drivers/md/dm-era-target.c +++ b/drivers/md/dm-era-target.c @@ -1640,6 +1640,10 @@ static void era_status(struct dm_target *ti, status_type_t type, format_dev_t(buf, era->origin_dev->bdev->bd_dev); DMEMIT("%s %u", buf, era->sectors_per_block); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return; diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index b7fee9936f05..8720e1a4873b 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -440,6 +440,10 @@ static void flakey_status(struct dm_target *ti, status_type_t type, fc->corrupt_bio_value, fc->corrupt_bio_flags); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 781942aeddd1..df234575dda4 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -3310,6 +3310,44 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type, EMIT_ALG(journal_mac_alg, "journal_mac"); break; } + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + DMEMIT("dev_name=%s;start=%llu;tag_size=%u;mode=%c;", + ic->dev->name, ic->start, ic->tag_size, ic->mode); + + if (ic->meta_dev) + DMEMIT("meta_device=%s;", ic->meta_dev->name); + if (ic->sectors_per_block != 1) + DMEMIT("block_size=%u;", ic->sectors_per_block << SECTOR_SHIFT); + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) + DMEMIT("recalculate=y;"); + else + DMEMIT("recalculate=n;"); + + if (ic->discard) + DMEMIT("allow_discards=y;"); + else + DMEMIT("allow_discards=n;"); + + DMEMIT("journal_sectors=%u;", ic->initial_sectors - SB_SECTORS); + DMEMIT("interleave_sectors=%u;", 1U << ic->sb->log2_interleave_sectors); + DMEMIT("buffer_sectors=%u;", 1U << ic->log2_buffer_sectors); + DMEMIT("mode=%c;", ic->mode); + if ((ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0) + DMEMIT("fix_padding=y;"); + else + DMEMIT("fix_padding=n;"); + + if ((ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) != 0) + DMEMIT("fix_hmac=y;"); + else + DMEMIT("fix_hmac=n;"); + + if (ic->legacy_recalculate) + DMEMIT("legacy_recalculate=y;"); + else + DMEMIT("legacy_recalculate=n;"); + break; } } diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 92db0f5e7f28..42acf4ed3b39 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -106,6 +106,7 @@ static void linear_status(struct dm_target *ti, status_type_t type, unsigned status_flags, char *result, unsigned maxlen) { struct linear_c *lc = (struct linear_c *) ti->private; + size_t sz = 0; switch (type) { case STATUSTYPE_INFO: @@ -116,6 +117,13 @@ static void linear_status(struct dm_target *ti, status_type_t type, snprintf(result, maxlen, "%s %llu", lc->dev->name, (unsigned long long)lc->start); break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + DMEMIT("device_name=%s;start=%llu;", lc->dev->name, + (unsigned long long)lc->start); + break; } } diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c index 52090bee17c2..15cfe33ea68c 100644 --- a/drivers/md/dm-log-userspace-base.c +++ b/drivers/md/dm-log-userspace-base.c @@ -820,6 +820,9 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type, DMEMIT("integrated_flush "); DMEMIT("%s ", table_args); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return (r) ? 0 : (int)sz; } diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c index 57882654ffee..f3a6a0d3bf2d 100644 --- a/drivers/md/dm-log-writes.c +++ b/drivers/md/dm-log-writes.c @@ -834,6 +834,10 @@ static void log_writes_status(struct dm_target *ti, status_type_t type, case STATUSTYPE_TABLE: DMEMIT("%s %s", lc->dev->name, lc->logdev->name); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 33e71ea6cc14..e0bcdf339df7 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -793,6 +793,11 @@ static int core_status(struct dm_dirty_log *log, status_type_t status, DMEMIT("%s %u %u ", log->type->name, lc->sync == DEFAULTSYNC ? 1 : 2, lc->region_size); DMEMIT_SYNC; + break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return sz; @@ -817,6 +822,11 @@ static int disk_status(struct dm_dirty_log *log, status_type_t status, lc->sync == DEFAULTSYNC ? 2 : 3, lc->log_dev->name, lc->region_size); DMEMIT_SYNC; + break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return sz; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index bced42f082b0..4d9af76fb6e8 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1904,6 +1904,35 @@ static void multipath_status(struct dm_target *ti, status_type_t type, } } break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + list_for_each_entry(pg, &m->priority_groups, list) { + if (pg->bypassed) + state = 'D'; /* Disabled */ + else if (pg == m->current_pg) + state = 'A'; /* Currently Active */ + else + state = 'E'; /* Enabled */ + + DMEMIT("state=%c;", state); + + list_for_each_entry(p, &pg->pgpaths, list) { + DMEMIT("path_name=%s;is_active=%s;fail_count=%u;", + p->path.dev->name, + p->is_active ? "A" : "F", + p->fail_count); + if (pg->ps.type->status) { + DMEMIT("path_selector_status="); + sz += pg->ps.type->status(&pg->ps, + &p->path, type, result + sz, + maxlen - sz); + DMEMIT(";"); + } + } + } + break; } spin_unlock_irqrestore(&m->lock, flags); diff --git a/drivers/md/dm-ps-historical-service-time.c b/drivers/md/dm-ps-historical-service-time.c index 186f91e2752c..0ad613e12b22 100644 --- a/drivers/md/dm-ps-historical-service-time.c +++ b/drivers/md/dm-ps-historical-service-time.c @@ -255,6 +255,9 @@ static int hst_status(struct path_selector *ps, struct dm_path *path, case STATUSTYPE_TABLE: DMEMIT("0 "); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-ps-io-affinity.c b/drivers/md/dm-ps-io-affinity.c index 077655cd4fae..618179028c13 100644 --- a/drivers/md/dm-ps-io-affinity.c +++ b/drivers/md/dm-ps-io-affinity.c @@ -171,6 +171,9 @@ static int ioa_status(struct path_selector *ps, struct dm_path *path, pi = path->pscontext; DMEMIT("%*pb ", cpumask_pr_args(pi->cpumask)); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return sz; diff --git a/drivers/md/dm-ps-queue-length.c b/drivers/md/dm-ps-queue-length.c index 5fd018d18418..5988f52b5a6e 100644 --- a/drivers/md/dm-ps-queue-length.c +++ b/drivers/md/dm-ps-queue-length.c @@ -102,6 +102,9 @@ static int ql_status(struct path_selector *ps, struct dm_path *path, case STATUSTYPE_TABLE: DMEMIT("%u ", pi->repeat_count); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-ps-round-robin.c b/drivers/md/dm-ps-round-robin.c index bdbb7e6e8212..8b47949454e9 100644 --- a/drivers/md/dm-ps-round-robin.c +++ b/drivers/md/dm-ps-round-robin.c @@ -100,6 +100,10 @@ static int rr_status(struct path_selector *ps, struct dm_path *path, pi = path->pscontext; DMEMIT("%u ", pi->repeat_count); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-ps-service-time.c b/drivers/md/dm-ps-service-time.c index 9cfda665e9eb..3ec9c33265c5 100644 --- a/drivers/md/dm-ps-service-time.c +++ b/drivers/md/dm-ps-service-time.c @@ -99,6 +99,9 @@ static int st_status(struct path_selector *ps, struct dm_path *path, DMEMIT("%u %u ", pi->repeat_count, pi->relative_throughput); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index bf4a467fc73a..67d7f9e5b89b 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3671,6 +3671,48 @@ static void raid_status(struct dm_target *ti, status_type_t type, for (i = 0; i < rs->raid_disks; i++) DMEMIT(" %s %s", __get_dev_name(rs->dev[i].meta_dev), __get_dev_name(rs->dev[i].data_dev)); + break; + + case STATUSTYPE_IMA: + /* *Should* always succeed */ + rt = get_raid_type_by_ll(mddev->new_level, mddev->new_layout); + if (!rt) + return; + + DMEMIT_NAME_VERSION(ti->type); + + DMEMIT("raid_type=%s;raid_disks=%d;", rt->name, mddev->raid_disks); + + /* Access most recent mddev properties for status output */ + smp_rmb(); + state = decipher_sync_action(mddev, recovery); + DMEMIT("raid_state=%s;", sync_str(state)); + + for (i = 0; i < rs->raid_disks; i++) { + DMEMIT("raid_device_%d_status=", i); + DMEMIT(__raid_dev_status(rs, &rs->dev[i].rdev)); + DMEMIT(";"); + } + + if (rt_is_raid456(rt)) { + DMEMIT("journal_dev_mode="); + switch (rs->journal_dev.mode) { + case R5C_JOURNAL_MODE_WRITE_THROUGH: + DMEMIT("%s", + _raid456_journal_mode[R5C_JOURNAL_MODE_WRITE_THROUGH].param); + break; + case R5C_JOURNAL_MODE_WRITE_BACK: + DMEMIT("%s", + _raid456_journal_mode[R5C_JOURNAL_MODE_WRITE_BACK].param); + break; + default: + DMEMIT("invalid"); + break; + } + DMEMIT(";"); + } + break; + } } diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index b0a82f29a2e4..ecfc6d4c41e3 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1435,6 +1435,24 @@ static void mirror_status(struct dm_target *ti, status_type_t type, } break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + DMEMIT("mirrors=%d;", ms->nr_mirrors); + for (m = 0; m < ms->nr_mirrors; m++) { + DMEMIT("mirror_device_%d=%s;", m, ms->mirror[m].dev->name); + DMEMIT("mirror_device_%d_status=%c;", + m, device_status_char(&(ms->mirror[m]))); + } + + DMEMIT("%s", errors_handled(ms) ? "handle_errors=y;" : "handle_errors=n;"); + DMEMIT("%s", keep_log(ms) ? "keep_log=y;" : "keep_log=n;"); + + DMEMIT("log_type_status="); + sz += log->type->status(log, type, result+sz, maxlen-sz); + DMEMIT(";"); + break; } } diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 9ab4bf651ca9..ed7e903c5b44 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -908,6 +908,10 @@ static unsigned persistent_status(struct dm_exception_store *store, case STATUSTYPE_TABLE: DMEMIT(" %s %llu", store->userspace_supports_overflow ? "PO" : "P", (unsigned long long)store->chunk_size); + break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return sz; diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c index 4d50a12cf00c..f6d46610ae77 100644 --- a/drivers/md/dm-snap-transient.c +++ b/drivers/md/dm-snap-transient.c @@ -95,6 +95,10 @@ static unsigned transient_status(struct dm_exception_store *store, break; case STATUSTYPE_TABLE: DMEMIT(" N %llu", (unsigned long long)store->chunk_size); + break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return sz; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index a2acb014c13a..daebbc92016d 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -2389,6 +2389,19 @@ static void snapshot_status(struct dm_target *ti, status_type_t type, DMEMIT(" discard_passdown_origin"); } break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + DMEMIT("snap_origin_name=%s;", snap->origin->name); + DMEMIT("snap_cow_name=%s;", snap->cow->name); + DMEMIT("%s", snap->valid ? "snap_valid=y;" : "snap_valid=n;"); + DMEMIT("%s", snap->merge_failed ? + "snap_merge_failed=y;" : "snap_merge_failed=n;"); + DMEMIT("%s", snap->snapshot_overflowed ? + "snapshot_overflowed=y;" : "snapshot_overflowed=n"); + break; + } } @@ -2733,6 +2746,9 @@ static void origin_status(struct dm_target *ti, status_type_t type, case STATUSTYPE_TABLE: snprintf(result, maxlen, "%s", o->dev->name); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index df359d33cda8..65352c6005f3 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -428,6 +428,21 @@ static void stripe_status(struct dm_target *ti, status_type_t type, DMEMIT(" %s %llu", sc->stripe[i].dev->name, (unsigned long long)sc->stripe[i].physical_start); break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + DMEMIT("stripes=%d;chunk_size=%llu;", + sc->stripes, + (unsigned long long)sc->chunk_size); + for (i = 0; i < sc->stripes; i++) { + DMEMIT("stripe_%d_device_name=%s;", i, sc->stripe[i].dev->name); + DMEMIT("stripe_%d_physical_start=%llu;", i, + (unsigned long long)sc->stripe[i].physical_start); + DMEMIT("stripe_%d_status=%c;", i, + atomic_read(&(sc->stripe[i].error_count)) ? 'D' : 'A'); + } + break; } } diff --git a/drivers/md/dm-switch.c b/drivers/md/dm-switch.c index 262e2b0fd975..028a92ff6d57 100644 --- a/drivers/md/dm-switch.c +++ b/drivers/md/dm-switch.c @@ -504,6 +504,10 @@ static void switch_status(struct dm_target *ti, status_type_t type, DMEMIT(" %s %llu", sctx->path_list[path_nr].dmdev->name, (unsigned long long)sctx->path_list[path_nr].start); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 985baee3a678..fc299cf90135 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -4012,6 +4012,10 @@ static void pool_status(struct dm_target *ti, status_type_t type, (unsigned long long)pt->low_water_blocks); emit_flags(&pt->requested_pf, result, sz, maxlen); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return; @@ -4423,6 +4427,10 @@ static void thin_status(struct dm_target *ti, status_type_t type, if (tc->origin_dev) DMEMIT(" %s", format_dev_t(buf, tc->origin_dev->bdev->bd_dev)); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-unstripe.c b/drivers/md/dm-unstripe.c index 7357c1bd5863..c04be1f6d059 100644 --- a/drivers/md/dm-unstripe.c +++ b/drivers/md/dm-unstripe.c @@ -156,6 +156,10 @@ static void unstripe_status(struct dm_target *ti, status_type_t type, uc->stripes, (unsigned long long)uc->chunk_size, uc->unstripe, uc->dev->name, (unsigned long long)uc->physical_start); break; + + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index d3e76aefc1a6..38c991eb5069 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -772,6 +772,52 @@ static void verity_status(struct dm_target *ti, status_type_t type, DMEMIT(" " DM_VERITY_ROOT_HASH_VERIFICATION_OPT_SIG_KEY " %s", v->signature_key_desc); break; + + case STATUSTYPE_IMA: + DMEMIT_NAME_VERSION(ti->type); + + DMEMIT("hash_failed=%c;", v->hash_failed ? 'C' : 'V'); + + DMEMIT("verity_version=%u;", v->version); + DMEMIT("data_device_name=%s;", v->data_dev->name); + DMEMIT("hash_device_name=%s;", v->hash_dev->name); + DMEMIT("verity_algorithm=%s;", v->alg_name); + + DMEMIT("root_digest="); + for (x = 0; x < v->digest_size; x++) + DMEMIT("%02x", v->root_digest[x]); + DMEMIT(";"); + + DMEMIT("salt="); + if (!v->salt_size) + DMEMIT("-"); + else + for (x = 0; x < v->salt_size; x++) + DMEMIT("%02x", v->salt[x]); + DMEMIT(";"); + + DMEMIT("%s", v->zero_digest ? "ignore_zero_blocks=y;" : "ignore_zero_blocks=n;"); + DMEMIT("%s", v->validated_blocks ? "check_at_most_once=y;" : + "check_at_most_once=n;"); + + if (v->mode != DM_VERITY_MODE_EIO) { + DMEMIT("verity_mode="); + switch (v->mode) { + case DM_VERITY_MODE_LOGGING: + DMEMIT(DM_VERITY_OPT_LOGGING); + break; + case DM_VERITY_MODE_RESTART: + DMEMIT(DM_VERITY_OPT_RESTART); + break; + case DM_VERITY_MODE_PANIC: + DMEMIT(DM_VERITY_OPT_PANIC); + break; + default: + DMEMIT("invalid"); + } + DMEMIT(";"); + } + break; } } diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index aecc246ade26..02bb1019bdc6 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -2536,6 +2536,9 @@ static void writecache_status(struct dm_target *ti, status_type_t type, if (wc->writeback_fua_set) DMEMIT(" %sfua", wc->writeback_fua ? "" : "no"); break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } } diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c index 7e88df64d197..b1d311238b5b 100644 --- a/drivers/md/dm-zoned-target.c +++ b/drivers/md/dm-zoned-target.c @@ -1119,6 +1119,9 @@ static void dmz_status(struct dm_target *ti, status_type_t type, DMEMIT(" %s", buf); } break; + case STATUSTYPE_IMA: + result[0] = '\0'; + break; } return; } diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 738a7d023650..61ac0fcec7d4 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -596,6 +596,10 @@ void dm_destroy_keyslot_manager(struct blk_keyslot_manager *ksm); #define DMEMIT(x...) sz += ((sz >= maxlen) ? \ 0 : scnprintf(result + sz, maxlen - sz, x)) +#define DMEMIT_NAME_VERSION(y) \ + DMEMIT("target_type_name=%s;target_type_version=%u.%u.%u;", \ + y->name, y->version[0], y->version[1], y->version[2]) + /* * Definitions of return values from target end_io function. */ From patchwork Wed May 26 00:59:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 12280465 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 BC22EC4707F for ; Wed, 26 May 2021 01:10:19 +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-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5064F613F1 for ; Wed, 26 May 2021 01:10:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5064F613F1 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-131-TAD_IjCiM8e0-XH3wo2t6Q-1; Tue, 25 May 2021 21:10:14 -0400 X-MC-Unique: TAD_IjCiM8e0-XH3wo2t6Q-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 74F4118397BA; Wed, 26 May 2021 01:10:09 +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 27C9C1F0E6; Wed, 26 May 2021 01:10:09 +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 E8A011801262; Wed, 26 May 2021 01:10:08 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 14Q19jfx020115 for ; Tue, 25 May 2021 21:09:46 -0400 Received: by smtp.corp.redhat.com (Postfix) id D532DF5669; Wed, 26 May 2021 01:09:45 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D0105C2105 for ; Wed, 26 May 2021 01:09:43 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.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 1AEF480D0E2 for ; Wed, 26 May 2021 01:09:43 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-243-oKyX9LYeOKaTx8ZPDYAL8g-1; Tue, 25 May 2021 21:09:41 -0400 X-MC-Unique: oKyX9LYeOKaTx8ZPDYAL8g-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 674FB20B8013; Tue, 25 May 2021 18:00:06 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 674FB20B8013 From: Tushar Sugandhi To: dm-devel@redhat.com Date: Tue, 25 May 2021 17:59:54 -0700 Message-Id: <20210526005954.31564-8-tusharsu@linux.microsoft.com> In-Reply-To: <20210526005954.31564-1-tusharsu@linux.microsoft.com> References: <20210526005954.31564-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.79 on 10.11.54.5 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id 14Q19jfx020115 X-loop: dm-devel@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, zohar@linux.ibm.com, snitzer@redhat.com, agk@redhat.com Subject: [dm-devel] [RFC 7/7] dm: add documentation for IMA measurement support 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.84 on 10.5.11.23 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 System administrators need instructions to set the IMA policy correctly to enable measurement of various DM targets using IMA. Various attestation client/server component owners also need the detailed information on how to interpret the IMA measurement data emitted by DM targets. To address that, a separate documentation page is needed. Add documentation to admin-guide to help system administrators and attestation client/server component owners interpret the measurement data generated by various DM targets, on various device / table state changes. Signed-off-by: Tushar Sugandhi --- .../admin-guide/device-mapper/dm-ima.rst | 271 ++++++++++++++++++ .../admin-guide/device-mapper/index.rst | 1 + 2 files changed, 272 insertions(+) create mode 100644 Documentation/admin-guide/device-mapper/dm-ima.rst diff --git a/Documentation/admin-guide/device-mapper/dm-ima.rst b/Documentation/admin-guide/device-mapper/dm-ima.rst new file mode 100644 index 000000000000..f7b486ed2ca1 --- /dev/null +++ b/Documentation/admin-guide/device-mapper/dm-ima.rst @@ -0,0 +1,271 @@ +====== +dm-ima +====== + +For a given system, various external services/infrastructure tools +(including the attestation service) interact with it - both during the +setup and during rest of the system run-time. They share sensitive data +and/or execute critical workload on that system. The external services +may want to verify the current run-time state of the relevant kernel +subsystems before fully trusting the system with business-critical +data/workload. + +Device mapper plays a critical role on a given system by providing +various important functionalities to the block devices using various +target types like crypt, verity, integrity etc. Each of these target +types’ functionalities can be configured with various attributes. +The attributes chosen to configure these target types can significantly +impact the security profile of the block device, and in-turn, of the +system itself. For instance, the type of encryption algorithm and the +key size determines the strength of encryption for a given block device. + +Therefore, verifying the current state of various block devices as well +as their various target attributes is crucial for external services before +fully trusting the system with business-critical data/workload. + +IMA kernel subsystem provides the necessary functionality for +device mapper to measure the state and configuration of +various block devices - + - BY device mapper itself, from within the kernel, + - in a tamper resistant way, + - and re-measured - triggered on state/configuration change. + +Setting the IMA Policy: +======================= +For IMA to measure the data on a given system, the IMA policy on the +system needs to be updated to have following line, and the system needs +to be restarted for the measurements to take effect. + +/etc/ima/ima-policy + measure func=CRITICAL_DATA label=device-mapper template=ima-buf + +The measurements will be reflected in the IMA logs, which are located at: + +/sys/kernel/security/integrity/ima/ascii_runtime_measurements +/sys/kernel/security/integrity/ima/binary_runtime_measurements + +Supported Device States: +======================== +Following device state changes will trigger IMA measurements. +01. Table load +02. Device resume +03. Device remove +04. Table clear +05. Device rename + +01. Table load: +--------------- +When a new table is loaded in a device's inactive table slot, +the device information and target specific details from the +targets in the table are measured. + +For instance, if a linear device is created with the following table entries, +#dmsetup create linear1 +0 1 linear /dev/loop0 8192 +1 1 linear /dev/loop1 8192 +2 1 linear /dev/loop2 8192 +3 1 linear /dev/loop3 8192 + +Then IMA ASCII measurement log will have an entry similar to the following, +with the format: +[device_data];[target_data_row_1];[target_data_row_2];...[target_data_row_n]; + +(converted from ASCII to text for readability) + +10 0d27cf7227d473d1c2b56b0433ca0215f2aefa0f ima-buf sha1:ec047e05fa07a9b477631d298539dcac8bdd3025 +table_load name=linear1;uuid=;capacity=0;major=253;minor=0;minor_count=1;num_targets=4; +target_type_name=linear;target_type_version=1.4.0;device_name=7:0;start=8192; +target_type_name=linear;target_type_version=1.4.0;device_name=7:1;start=8192; +target_type_name=linear;target_type_version=1.4.0;device_name=7:2;start=8192; +target_type_name=linear;target_type_version=1.4.0;device_name=7:3;start=8192; + +02. Device resume: +------------------ +When a suspended device is resumed, the device information and a sha256 hash of the +data from previous load of an active table are measured. + +For instance, if a linear device is resumed with the following command, +#dmsetup resume linear1 + +Then IMA ASCII measurement log will have an entry similar to the following, +with the format: +[device_data];active_table_hash=(sha256hash([device_data];[target_data_row_1];...[target_data_row_n]); + +(converted from ASCII to text for readability) + +10 e36dce92b9070434876d01bfc8e3cc942dbe3ce2 ima-buf sha1:fb5c71b7dc91bcc64bcae552694e809bfcb4e52e +device_resume name=linear1;uuid=;capacity=0;major=253;minor=0;minor_count=1;num_targets=4; +active_table_hash=07b98a0b742f8a45588118632cef4c5706579caa552585ec5ddb50fe03aa083b; + + + +03. Device remove: +------------------ +When a device is removed, the device information and a sha256 hash of the +data from an active and inactive table are measured. + +For instance, if a linear device is removed with the following command, +# dmsetup remove linear1 + +Then IMA ASCII measurement log will have an entry similar to the following, +with the format: +[device_data];active_table_hash=(sha256hash([device_data];[rows_from_active_table]]); +inactive_table_hash=(sha256hash([device_data];[rows_from_inactive_table]]); + +(converted from ASCII to text for readability) + +10 724e209d998546427f70ce45b508a42eeebb9d0a ima-buf sha1:27f7bc1380d38058025007df0fff94a5e8fe2374 +device_remove name=linear1;uuid=1234;capacity=4;major=253;minor=0;minor_count=1;num_targets=4; +active_table_hash=07b98a0b742f8a45588118632cef4c5706579caa552585ec5ddb50fe03aa083b; +inactive_table_hash=07b98a0b742f8a45588118632cef4c5706579caa552585ec5ddb50fe03aa083b; + + +04. Table clear: +---------------- +When an inactive table is cleared from the device, the device information and a sha256 hash of the +data from an inactive table are measured. + +For instance, if a linear device's inactive table is cleared with the following command, + +# dmsetup clear linear1 + +Then IMA ASCII measurement log will have an entry similar to the following, +with the format: +[device_data];inactive_table_hash=(sha256hash([device_data];[rows_from_inactive_table]]); + +(converted from ASCII to text for readability) + +10 5f9ae8da02ab2abde3b92df20d6d3f8b8d3369db ima-buf sha1:0105b5946801e6e42e6f42b5d90f7583e98b08c5 +table_clear name=linear1;uuid=1234;capacity=4;major=253;minor=0;minor_count=1;num_targets=4; +inactive_table_hash=80bfc94f14f7f5a3d68ea6dbbd53064f90cdd30e0ea1cbdb593f7a1f2b0e96c7; + + +05. Device rename: +------------------ +When an device's NAME or UUID is changed, the device information and the new NAME and UUID +are measured. + +For instance, if a linear device's name is changed with the following command, + +#dmsetup rename linear1 linear=2 +Then IMA ASCII measurement log will have an entry similar to the following, +with the format: +[current_device_data];new_name=;new_uuid=; + + +(converted from ASCII to text for readability) +10 10b599505894c0885aeef801ede7e04a87b4245e ima-buf sha1:b0abee16f7caa778035b49c1c8119186248b44a4 +device_rename name=linear1;uuid=1234;capacity=4;major=253;minor=0;minor_count=1;num_targets=4; +new_name=linear\=2;new_uuid=1234; + + +Supported targets: +================== +Following targets are supported to measure their data using IMA. + +01. cache +02. crypt +03. integrity +04. linear +05. mirror +06. multipath +07. raid +08. snapshot +09. striped +10. verity + +01. cache +--------- +<> + +02. crypt +----- +When a crypt target is loaded, then IMA ASCII measurement log will have an entry +similar to the following, depicting what crypt attributes are measured. + +(converted from ASCII to text for readability) + +10 7852bada6bb36d59cdc9a17369f9b9f71f46c1eb ima-buf sha1:c84c1680a37f049a01430dd3886f20a597f9fec8 + table_load name=luks-2777bb3d-6160-4dcd-8722-a86a519a95c1; + uuid=CRYPT-LUKS1-2777bb3d61604dcd8722a86a519a95c1-luks-2777bb3d-6160-4dcd-8722-a86a519a95c1; + capacity=0;major=253;minor=15;minor_count=1;num_targets=1;target_type_name=crypt; + target_type_version=1.23.0;allow_discards=n;same_cpu=n;submit_from_crypt_cpus=n;no_read_workqueue=n; + no_write_workqueue=n;iv_large_sectors=y;cipher_string=aes-xts-plain64;key_size=32;key_parts=1; + key_extra_size=0;key_mac_size=0; + +03. integrity +------------- +<> + + +04. linear +---------- +When a linear target is loaded, then IMA ASCII measurement log will have an entry +similar to the following, depicting what linear attributes are measured. + +(converted from ASCII to text for readability) +10 8fb70d291178abcc2acca33ef57adc0d3ff0e67a ima-buf sha1:4b9ae1ae655505054b0ab37181e2f9f8d847f675 +table_load name=linear1;uuid=1234;capacity=4;major=253;minor=0;minor_count=1;num_targets=4; +target_type_name=linear;target_type_version=1.4.0;device_name=7:0;start=8192; + + +05. mirror +---------- +When a mirror target is loaded, then IMA ASCII measurement log will have an entry +similar to the following, depicting what mirror attributes are measured. + +(converted from ASCII to text for readability) +10 4dd208e0fd00a5b5ca358364b5a90eb2c4f2013e ima-buf sha1:7bf75a5db56958ec07ee3f5ae356e58d52fe8910 +table_load name=test-mirror;uuid=;capacity=0;major=253;minor=7;minor_count=1;num_targets=1; +target_type_name=mirror;target_type_version=1.14.0;mirrors=2;mirror_device_0=253:2; +mirror_device_0_status=A;mirror_device_1=253:6;mirror_device_1_status=A;handle_errors=y; +keep_log=n;log_type_status=; + +06. multipath +------------- +<> + +07. raid +-------- +When a raid target is loaded, then IMA ASCII measurement log will have an entry +similar to the following, depicting what raid attributes are measured. + +(converted from ASCII to text for readability) +10 ad7ce5156f6675bacf07e57fc7d24b52128682a6 ima-buf sha1:024b05c82badd4edf8a1e877f8fc558e8de80acb +table_load name=test-raid1;uuid=;capacity=0;major=253;minor=2;minor_count=1;num_targets=1; +target_type_name=raid;target_type_version=1.15.1;raid_type=raid1;raid_disks=2;raid_state=idle; +raid_device_0_status=A;raid_device_1_status=A; + +08. snapshot +------------ +<> + +09. striped +---------- +When a linear target is loaded, then IMA ASCII measurement log will have an entry +similar to the following, depicting what linear attributes are measured. + +(converted from ASCII to text for readability) +10 b75993407d68c74de8a13a9467049a57013fb855 ima-buf sha1:fa75997f2bf9b87ee4b4dff5bd420055b22f938a +table_load name=test-raid0;uuid=;capacity=0;major=253;minor=11;minor_count=1;num_targets=1; +target_type_name=striped;target_type_version=1.6.0;stripes=4;chunk_size=128; +stripe_0_device_name=253:1;stripe_0_physical_start=0;stripe_0_status=A; +stripe_1_device_name=253:6;stripe_1_physical_start=0;stripe_1_status=A; +stripe_2_device_name=253:8;stripe_2_physical_start=0;stripe_2_status=A; +stripe_3_device_name=253:10;stripe_3_physical_start=0;stripe_3_status=A; + +10. verity +---------- +When a verity target is loaded, then IMA ASCII measurement log will have an entry +similar to the following, depicting what verity attributes are measured. + +(converted from ASCII to text for readability) + +0 c5188b404e70166baa1573fb289eea81981d5164 ima-buf sha1:a2cc6780198ede624d4f0864ffa76741332f85d3 +table_load name=vr2;uuid=CRYPT-VERITY-c5203ede74d349d89941a46c51a6784f-vr2;capacity=0;major=253;minor=16; +minor_count=1;num_targets=1; +target_type_name=verity;target_type_version=1.8.0;hash_failed=V;verity_version=1; +data_device_name=8:49;hash_device_name=8:33;verity_algorithm=sha256; +root_digest=6dbfd48cd67e5c94df25db02f15c621595675cceb39e1e88a8ccd773e408decc; +salt=daab90c9f8a164c02c59f494fa7d5cde91c415ebe0b0fb9b068c2c9d3b57a787; +ignore_zero_blocks=n;check_at_most_once=n; diff --git a/Documentation/admin-guide/device-mapper/index.rst b/Documentation/admin-guide/device-mapper/index.rst index 6cf8adc86fa8..cde52cc09645 100644 --- a/Documentation/admin-guide/device-mapper/index.rst +++ b/Documentation/admin-guide/device-mapper/index.rst @@ -13,6 +13,7 @@ Device Mapper dm-dust dm-ebs dm-flakey + dm-ima dm-init dm-integrity dm-io