// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Microsoft Corporation
 *
 * Author: Tushar Sugandhi <tusharsu@linux.microsoft.com>
 *
 * File: dm-ima.c
 *       Enables IMA measurements for DM targets
 */

#include "dm-core.h"
#include "dm-ima.h"

#include <linux/ima.h>
#include <linux/sched/mm.h>
#include <crypto/hash.h>
#include <linux/crypto.h>
#include <crypto/hash_info.h>

#define DM_MSG_PREFIX "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=val1,key2=val2,key3=val3; pairs properly.
 */
static 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] == '=' || (*buf)[i] == ',')
			sp++;

	if (!sp)
		return;

	for (i = l-1, j = i+sp; i >= 0; i--) {
		(*buf)[j--] = (*buf)[i];
		if ((*buf)[i] == '\\' || (*buf)[i] == ';' || (*buf)[i] == '=' || (*buf)[i] == ',')
			(*buf)[j--] = '\\';
	}
}

/*
 * Internal function to allocate memory for IMA measurements.
 */
static void *dm_ima_alloc(size_t len, gfp_t flags, bool noio)
{
	unsigned int noio_flag;
	void *ptr;

	if (noio)
		noio_flag = memalloc_noio_save();

	ptr = kzalloc(len, flags);

	if (noio)
		memalloc_noio_restore(noio_flag);

	return ptr;
}

/*
 * Internal function to allocate and copy name and uuid for IMA measurements.
 */
static int dm_ima_alloc_and_copy_name_uuid(struct mapped_device *md, char **dev_name,
					   char **dev_uuid, bool noio)
{
	int r;
	*dev_name = dm_ima_alloc(DM_NAME_LEN*2, GFP_KERNEL, noio);
	if (!(*dev_name)) {
		r = -ENOMEM;
		goto error;
	}

	*dev_uuid = dm_ima_alloc(DM_UUID_LEN*2, GFP_KERNEL, noio);
	if (!(*dev_uuid)) {
		r = -ENOMEM;
		goto error;
	}

	r = dm_copy_name_and_uuid(md, *dev_name, *dev_uuid);
	if (r)
		goto error;

	fix_separator_chars(dev_name);
	fix_separator_chars(dev_uuid);

	return 0;
error:
	kfree(*dev_name);
	kfree(*dev_uuid);
	*dev_name = NULL;
	*dev_uuid = NULL;
	return r;
}

/*
 * Internal function to allocate and copy device data for IMA measurements.
 */
static int dm_ima_alloc_and_copy_device_data(struct mapped_device *md, char **device_data,
					     unsigned int num_targets, bool noio)
{
	char *dev_name = NULL, *dev_uuid = NULL;
	int r;

	r = dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio);
	if (r)
		return r;

	*device_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio);
	if (!(*device_data)) {
		r = -ENOMEM;
		goto error;
	}

	scnprintf(*device_data, DM_IMA_DEVICE_BUF_LEN,
		  "name=%s,uuid=%s,major=%d,minor=%d,minor_count=%d,num_targets=%u;",
		  dev_name, dev_uuid, md->disk->major, md->disk->first_minor,
		  md->disk->minors, num_targets);
error:
	kfree(dev_name);
	kfree(dev_uuid);
	return r;
}

/*
 * Internal wrapper function to call IMA to measure DM data.
 */
static void dm_ima_measure_data(const char *event_name, const void *buf, size_t buf_len,
				bool noio)
{
	unsigned int noio_flag;

	if (noio)
		noio_flag = memalloc_noio_save();

	ima_measure_critical_data(DM_NAME, event_name, buf, buf_len,
				  false, NULL, 0);

	if (noio)
		memalloc_noio_restore(noio_flag);
}

/*
 * Internal function to allocate and copy current device capacity for IMA measurements.
 */
static int dm_ima_alloc_and_copy_capacity_str(struct mapped_device *md, char **capacity_str,
					      bool noio)
{
	sector_t capacity;

	capacity = get_capacity(md->disk);

	*capacity_str = dm_ima_alloc(DM_IMA_DEVICE_CAPACITY_BUF_LEN, GFP_KERNEL, noio);
	if (!(*capacity_str))
		return -ENOMEM;

	scnprintf(*capacity_str, DM_IMA_DEVICE_BUF_LEN, "current_device_capacity=%llu;",
		  capacity);

	return 0;
}

/*
 * Initialize/reset the dm ima related data structure variables.
 */
void dm_ima_reset_data(struct mapped_device *md)
{
	memset(&(md->ima), 0, sizeof(md->ima));
	md->ima.dm_version_str_len = strlen(DM_IMA_VERSION_STR);
}

/*
 * 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)
{
	size_t device_data_buf_len, target_metadata_buf_len, target_data_buf_len, l = 0;
	char *target_metadata_buf = NULL, *target_data_buf = NULL, *digest_buf = NULL;
	char *ima_buf = NULL, *device_data_buf = NULL;
	int digest_size, last_target_measured = -1, r;
	status_type_t type = STATUSTYPE_IMA;
	size_t cur_total_buf_len = 0;
	unsigned int num_targets, i;
	SHASH_DESC_ON_STACK(shash, NULL);
	struct crypto_shash *tfm = NULL;
	u8 *digest = NULL;
	bool noio = false;
	/*
	 * In below hash_alg_prefix_len assignment +1 is for the additional char (':'),
	 * when prefixing the hash value with the hash algorithm name. e.g. sha256:<hash_value>.
	 */
	const size_t hash_alg_prefix_len = strlen(DM_IMA_TABLE_HASH_ALG) + 1;
	char table_load_event_name[] = "dm_table_load";

	ima_buf = dm_ima_alloc(DM_IMA_MEASUREMENT_BUF_LEN, GFP_KERNEL, noio);
	if (!ima_buf)
		return;

	target_metadata_buf = dm_ima_alloc(DM_IMA_TARGET_METADATA_BUF_LEN, GFP_KERNEL, noio);
	if (!target_metadata_buf)
		goto error;

	target_data_buf = dm_ima_alloc(DM_IMA_TARGET_DATA_BUF_LEN, GFP_KERNEL, noio);
	if (!target_data_buf)
		goto error;

	num_targets = table->num_targets;

	if (dm_ima_alloc_and_copy_device_data(table->md, &device_data_buf, num_targets, noio))
		goto error;

	tfm = crypto_alloc_shash(DM_IMA_TABLE_HASH_ALG, 0, 0);
	if (IS_ERR(tfm))
		goto error;

	shash->tfm = tfm;
	digest_size = crypto_shash_digestsize(tfm);
	digest = dm_ima_alloc(digest_size, GFP_KERNEL, noio);
	if (!digest)
		goto error;

	r = crypto_shash_init(shash);
	if (r)
		goto error;

	memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len);
	l += table->md->ima.dm_version_str_len;

	device_data_buf_len = strlen(device_data_buf);
	memcpy(ima_buf + l, device_data_buf, device_data_buf_len);
	l += device_data_buf_len;

	for (i = 0; i < num_targets; i++) {
		struct dm_target *ti = dm_table_get_target(table, i);

		last_target_measured = 0;

		/*
		 * First retrieve the target metadata.
		 */
		scnprintf(target_metadata_buf, DM_IMA_TARGET_METADATA_BUF_LEN,
			  "target_index=%d,target_begin=%llu,target_len=%llu,",
			  i, ti->begin, ti->len);
		target_metadata_buf_len = strlen(target_metadata_buf);

		/*
		 * Then retrieve the actual target data.
		 */
		if (ti->type->status)
			ti->type->status(ti, type, status_flags, target_data_buf,
					 DM_IMA_TARGET_DATA_BUF_LEN);
		else
			target_data_buf[0] = '\0';

		target_data_buf_len = strlen(target_data_buf);

		/*
		 * Check if the total data can fit into the IMA buffer.
		 */
		cur_total_buf_len = l + target_metadata_buf_len + target_data_buf_len;

		/*
		 * IMA measurements for DM targets are best-effort.
		 * If the total data buffered so far, including the current target,
		 * is too large to fit into DM_IMA_MEASUREMENT_BUF_LEN, measure what
		 * we have in the current buffer, and continue measuring the remaining
		 * targets by prefixing the device metadata again.
		 */
		if (unlikely(cur_total_buf_len >= DM_IMA_MEASUREMENT_BUF_LEN)) {
			dm_ima_measure_data(table_load_event_name, ima_buf, l, noio);
			r = crypto_shash_update(shash, (const u8 *)ima_buf, l);
			if (r < 0)
				goto error;

			memset(ima_buf, 0, DM_IMA_MEASUREMENT_BUF_LEN);
			l = 0;

			/*
			 * Each new "dm_table_load" entry in IMA log should have device data
			 * prefix, so that multiple records from the same "dm_table_load" for
			 * a given device can be linked together.
			 */
			memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len);
			l += table->md->ima.dm_version_str_len;

			memcpy(ima_buf + l, device_data_buf, device_data_buf_len);
			l += device_data_buf_len;

			/*
			 * If this iteration of the for loop turns out to be the last target
			 * in the table, dm_ima_measure_data("dm_table_load", ...) doesn't need
			 * to be called again, just the hash needs to be finalized.
			 * "last_target_measured" tracks this state.
			 */
			last_target_measured = 1;
		}

		/*
		 * Fill-in all the target metadata, so that multiple targets for the same
		 * device can be linked together.
		 */
		memcpy(ima_buf + l, target_metadata_buf, target_metadata_buf_len);
		l += target_metadata_buf_len;

		memcpy(ima_buf + l, target_data_buf, target_data_buf_len);
		l += target_data_buf_len;
	}

	if (!last_target_measured) {
		dm_ima_measure_data(table_load_event_name, ima_buf, l, noio);

		r = crypto_shash_update(shash, (const u8 *)ima_buf, l);
		if (r < 0)
			goto error;
	}

	/*
	 * Finalize the table hash, and store it in table->md->ima.inactive_table.hash,
	 * so that the table data can be verified against the future device state change
	 * events, e.g. resume, rename, remove, table-clear etc.
	 */
	r = crypto_shash_final(shash, digest);
	if (r < 0)
		goto error;

	digest_buf = dm_ima_alloc((digest_size*2) + hash_alg_prefix_len + 1, GFP_KERNEL, noio);

	if (!digest_buf)
		goto error;

	snprintf(digest_buf, hash_alg_prefix_len + 1, "%s:", DM_IMA_TABLE_HASH_ALG);

	for (i = 0; i < digest_size; i++)
		snprintf((digest_buf + hash_alg_prefix_len + (i*2)), 3, "%02x", digest[i]);

	if (table->md->ima.active_table.hash != table->md->ima.inactive_table.hash)
		kfree(table->md->ima.inactive_table.hash);

	table->md->ima.inactive_table.hash = digest_buf;
	table->md->ima.inactive_table.hash_len = strlen(digest_buf);
	table->md->ima.inactive_table.num_targets = num_targets;

	if (table->md->ima.active_table.device_metadata !=
	    table->md->ima.inactive_table.device_metadata)
		kfree(table->md->ima.inactive_table.device_metadata);

	table->md->ima.inactive_table.device_metadata = device_data_buf;
	table->md->ima.inactive_table.device_metadata_len = device_data_buf_len;

	goto exit;
error:
	kfree(digest_buf);
	kfree(device_data_buf);
exit:
	kfree(digest);
	if (tfm)
		crypto_free_shash(tfm);
	kfree(ima_buf);
	kfree(target_metadata_buf);
	kfree(target_data_buf);
}

/*
 * Measure IMA data on device resume.
 */
void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap)
{
	char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL;
	char active[] = "active_table_hash=";
	unsigned int active_len = strlen(active), capacity_len = 0;
	unsigned int l = 0;
	bool noio = true;
	bool nodata = true;
	int r;

	device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio);
	if (!device_table_data)
		return;

	r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio);
	if (r)
		goto error;

	memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len);
	l += md->ima.dm_version_str_len;

	if (swap) {
		if (md->ima.active_table.hash != md->ima.inactive_table.hash)
			kfree(md->ima.active_table.hash);

		md->ima.active_table.hash = NULL;
		md->ima.active_table.hash_len = 0;

		if (md->ima.active_table.device_metadata !=
		    md->ima.inactive_table.device_metadata)
			kfree(md->ima.active_table.device_metadata);

		md->ima.active_table.device_metadata = NULL;
		md->ima.active_table.device_metadata_len = 0;
		md->ima.active_table.num_targets = 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;
		}

		if (md->ima.inactive_table.device_metadata) {
			md->ima.active_table.device_metadata =
				md->ima.inactive_table.device_metadata;
			md->ima.active_table.device_metadata_len =
				md->ima.inactive_table.device_metadata_len;
			md->ima.active_table.num_targets = md->ima.inactive_table.num_targets;
			md->ima.inactive_table.device_metadata = NULL;
			md->ima.inactive_table.device_metadata_len = 0;
			md->ima.inactive_table.num_targets = 0;
		}
	}

	if (md->ima.active_table.device_metadata) {
		memcpy(device_table_data + l, md->ima.active_table.device_metadata,
		       md->ima.active_table.device_metadata_len);
		l += md->ima.active_table.device_metadata_len;

		nodata = false;
	}

	if (md->ima.active_table.hash) {
		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++;

		nodata = false;
	}

	if (nodata) {
		r = dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio);
		if (r)
			goto error;

		scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN,
			  "%sname=%s,uuid=%s;device_resume=no_data;",
			  DM_IMA_VERSION_STR, dev_name, dev_uuid);
		l = strlen(device_table_data);

	}

	capacity_len = strlen(capacity_str);
	memcpy(device_table_data + l, capacity_str, capacity_len);
	l += capacity_len;

	dm_ima_measure_data("dm_device_resume", device_table_data, l, noio);

	kfree(dev_name);
	kfree(dev_uuid);
error:
	kfree(capacity_str);
	kfree(device_table_data);
}

/*
 * Measure IMA data on remove.
 */
void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all)
{
	char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL;
	char active_table_str[] = "active_table_hash=";
	char inactive_table_str[] = "inactive_table_hash=";
	char device_active_str[] = "device_active_metadata=";
	char device_inactive_str[] = "device_inactive_metadata=";
	char remove_all_str[] = "remove_all=";
	unsigned int active_table_len = strlen(active_table_str);
	unsigned int inactive_table_len = strlen(inactive_table_str);
	unsigned int device_active_len = strlen(device_active_str);
	unsigned int device_inactive_len = strlen(device_inactive_str);
	unsigned int remove_all_len = strlen(remove_all_str);
	unsigned int capacity_len = 0;
	unsigned int l = 0;
	bool noio = true;
	bool nodata = true;
	int r;

	device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN*2, GFP_KERNEL, noio);
	if (!device_table_data)
		goto exit;

	r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio);
	if (r) {
		kfree(device_table_data);
		goto exit;
	}

	memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len);
	l += md->ima.dm_version_str_len;

	if (md->ima.active_table.device_metadata) {
		memcpy(device_table_data + l, device_active_str, device_active_len);
		l += device_active_len;

		memcpy(device_table_data + l, md->ima.active_table.device_metadata,
		       md->ima.active_table.device_metadata_len);
		l += md->ima.active_table.device_metadata_len;

		nodata = false;
	}

	if (md->ima.inactive_table.device_metadata) {
		memcpy(device_table_data + l, device_inactive_str, device_inactive_len);
		l += device_inactive_len;

		memcpy(device_table_data + l, md->ima.inactive_table.device_metadata,
		       md->ima.inactive_table.device_metadata_len);
		l += md->ima.inactive_table.device_metadata_len;

		nodata = false;
	}

	if (md->ima.active_table.hash) {
		memcpy(device_table_data + l, active_table_str, active_table_len);
		l += active_table_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++;

		nodata = false;
	}

	if (md->ima.inactive_table.hash) {
		memcpy(device_table_data + l, inactive_table_str, inactive_table_len);
		l += inactive_table_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++;

		nodata = false;
	}
	/*
	 * In case both active and inactive tables, and corresponding
	 * device metadata is cleared/missing - record the name and uuid
	 * in IMA measurements.
	 */
	if (nodata) {
		if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio))
			goto error;

		scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN,
			  "%sname=%s,uuid=%s;device_remove=no_data;",
			  DM_IMA_VERSION_STR, dev_name, dev_uuid);
		l = strlen(device_table_data);
	}

	memcpy(device_table_data + l, remove_all_str, remove_all_len);
	l += remove_all_len;
	memcpy(device_table_data + l, remove_all ? "y;" : "n;", 2);
	l += 2;

	capacity_len = strlen(capacity_str);
	memcpy(device_table_data + l, capacity_str, capacity_len);
	l += capacity_len;

	dm_ima_measure_data("dm_device_remove", device_table_data, l, noio);

error:
	kfree(device_table_data);
	kfree(capacity_str);
exit:
	kfree(md->ima.active_table.device_metadata);

	if (md->ima.active_table.device_metadata !=
	    md->ima.inactive_table.device_metadata)
		kfree(md->ima.inactive_table.device_metadata);

	kfree(md->ima.active_table.hash);

	if (md->ima.active_table.hash != md->ima.inactive_table.hash)
		kfree(md->ima.inactive_table.hash);

	dm_ima_reset_data(md);

	kfree(dev_name);
	kfree(dev_uuid);
}

/*
 * Measure ima data on table clear.
 */
void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map)
{
	unsigned int l = 0, capacity_len = 0;
	char *device_table_data = NULL, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL;
	char inactive_str[] = "inactive_table_hash=";
	unsigned int inactive_len = strlen(inactive_str);
	bool noio = true;
	bool nodata = true;
	int r;

	device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio);
	if (!device_table_data)
		return;

	r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio);
	if (r)
		goto error1;

	memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len);
	l += md->ima.dm_version_str_len;

	if (md->ima.inactive_table.device_metadata_len &&
	    md->ima.inactive_table.hash_len) {
		memcpy(device_table_data + l, md->ima.inactive_table.device_metadata,
		       md->ima.inactive_table.device_metadata_len);
		l += md->ima.inactive_table.device_metadata_len;

		memcpy(device_table_data + l, inactive_str, 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++;

		nodata = false;
	}

	if (nodata) {
		if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio))
			goto error2;

		scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN,
			  "%sname=%s,uuid=%s;table_clear=no_data;",
			   DM_IMA_VERSION_STR, dev_name, dev_uuid);
		l = strlen(device_table_data);
	}

	capacity_len = strlen(capacity_str);
	memcpy(device_table_data + l, capacity_str, capacity_len);
	l += capacity_len;

	dm_ima_measure_data("dm_table_clear", device_table_data, l, noio);

	if (new_map) {
		if (md->ima.inactive_table.hash &&
		    md->ima.inactive_table.hash != md->ima.active_table.hash)
			kfree(md->ima.inactive_table.hash);

		md->ima.inactive_table.hash = NULL;
		md->ima.inactive_table.hash_len = 0;

		if (md->ima.inactive_table.device_metadata &&
		    md->ima.inactive_table.device_metadata != md->ima.active_table.device_metadata)
			kfree(md->ima.inactive_table.device_metadata);

		md->ima.inactive_table.device_metadata = NULL;
		md->ima.inactive_table.device_metadata_len = 0;
		md->ima.inactive_table.num_targets = 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;
		}

		if (md->ima.active_table.device_metadata) {
			md->ima.inactive_table.device_metadata =
				md->ima.active_table.device_metadata;
			md->ima.inactive_table.device_metadata_len =
				md->ima.active_table.device_metadata_len;
			md->ima.inactive_table.num_targets =
				md->ima.active_table.num_targets;
		}
	}

	kfree(dev_name);
	kfree(dev_uuid);
error2:
	kfree(capacity_str);
error1:
	kfree(device_table_data);
}

/*
 * 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, *capacity_str = NULL;
	bool noio = true;
	int r;

	if (dm_ima_alloc_and_copy_device_data(md, &new_device_data,
					      md->ima.active_table.num_targets, noio))
		return;

	if (dm_ima_alloc_and_copy_name_uuid(md, &new_dev_name, &new_dev_uuid, noio))
		goto error;

	combined_device_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN * 2, GFP_KERNEL, noio);
	if (!combined_device_data)
		goto error;

	r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio);
	if (r)
		goto error;

	old_device_data = md->ima.active_table.device_metadata;

	md->ima.active_table.device_metadata = new_device_data;
	md->ima.active_table.device_metadata_len = strlen(new_device_data);

	scnprintf(combined_device_data, DM_IMA_DEVICE_BUF_LEN * 2,
		  "%s%snew_name=%s,new_uuid=%s;%s", DM_IMA_VERSION_STR, old_device_data,
		  new_dev_name, new_dev_uuid, capacity_str);

	dm_ima_measure_data("dm_device_rename", combined_device_data, strlen(combined_device_data),
			    noio);

	goto exit;

error:
	kfree(new_device_data);
exit:
	kfree(capacity_str);
	kfree(combined_device_data);
	kfree(old_device_data);
	kfree(new_dev_name);
	kfree(new_dev_uuid);
}
