lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20211201163708.3578176-1-roberto.sassu@huawei.com>
Date:   Wed, 1 Dec 2021 17:37:08 +0100
From:   Roberto Sassu <roberto.sassu@...wei.com>
To:     <deven.desai@...ux.microsoft.com>, <corbet@....net>,
        <axboe@...nel.dk>, <agk@...hat.com>, <snitzer@...hat.com>,
        <ebiggers@...nel.org>, <tytso@....edu>, <paul@...l-moore.com>,
        <eparis@...hat.com>, <jmorris@...ei.org>, <serge@...lyn.com>
CC:     <jannh@...gle.com>, <dm-devel@...hat.com>,
        <linux-doc@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <linux-block@...r.kernel.org>, <linux-fscrypt@...r.kernel.org>,
        <linux-audit@...hat.com>, <linux-security-module@...r.kernel.org>,
        <linux-integrity@...r.kernel.org>, <tusharsu@...ux.microsoft.com>,
        Roberto Sassu <roberto.sassu@...wei.com>
Subject: [RFC][PATCH] device mapper: Add builtin function dm_get_status()

Users of the device mapper driver might want to obtain a device status,
with status types defined in the status_type_t enumerator.

If a function to get the status is exported by the device mapper, when
compiled as a module, it is not suitable to use by callers compiled builtin
in the kernel.

Introduce the real function to get the status, _dm_get_status(), in the
device mapper module, and add the stub dm_get_status() in dm-builtin.c, so
that it can be invoked by builtin callers.

The stub calls the real function if the device mapper is compiled builtin
or the module has been loaded. Calls to the real function are safely
disabled if the module is unloaded. The race condition is avoided by
incrementing the reference count of the module.

_dm_get_status() invokes the status() method for each device mapper table,
which writes a string to the supplied buffer as output. The buffer might
contain multiple strings concatenated together. If there is not enough
space available, the string is truncated and a termination character is put
at the end.

Signed-off-by: Roberto Sassu <roberto.sassu@...wei.com>
---
 drivers/md/dm-builtin.c       | 13 +++++++
 drivers/md/dm-core.h          |  5 +++
 drivers/md/dm.c               | 71 +++++++++++++++++++++++++++++++++++
 include/linux/device-mapper.h |  3 ++
 4 files changed, 92 insertions(+)

diff --git a/drivers/md/dm-builtin.c b/drivers/md/dm-builtin.c
index 8eb52e425141..cc1e9c27ab41 100644
--- a/drivers/md/dm-builtin.c
+++ b/drivers/md/dm-builtin.c
@@ -47,3 +47,16 @@ void dm_kobject_release(struct kobject *kobj)
 }
 
 EXPORT_SYMBOL(dm_kobject_release);
+
+dm_get_status_fn status_fn;
+EXPORT_SYMBOL(status_fn);
+
+ssize_t dm_get_status(dev_t dev, status_type_t type, const char *target_name,
+		      u8 *buf, size_t buf_len)
+{
+	if (status_fn)
+		return status_fn(dev, type, target_name, buf, buf_len);
+
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(dm_get_status);
diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
index b855fef4f38a..6600ec260558 100644
--- a/drivers/md/dm-core.h
+++ b/drivers/md/dm-core.h
@@ -259,4 +259,9 @@ extern atomic_t dm_global_event_nr;
 extern wait_queue_head_t dm_global_eventq;
 void dm_issue_global_event(void);
 
+typedef ssize_t (*dm_get_status_fn)(dev_t dev, status_type_t type,
+				    const char *target_name, u8 *buf,
+				    size_t buf_len);
+
+extern dm_get_status_fn status_fn;
 #endif
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 662742a310cb..55e59a4e3661 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -192,6 +192,74 @@ static unsigned dm_get_numa_node(void)
 					 DM_NUMA_NODE, num_online_nodes() - 1);
 }
 
+static ssize_t _dm_get_status(dev_t dev, status_type_t type,
+			      const char *target_name, u8 *buf, size_t buf_len)
+{
+	struct mapped_device *md;
+	struct dm_table *table;
+	u8 *buf_ptr = buf;
+	ssize_t len, res = 0;
+	int srcu_idx, num_targets, i;
+
+	if (buf_len > INT_MAX)
+		return -EINVAL;
+
+	if (!buf_len)
+		return buf_len;
+
+	if (!try_module_get(THIS_MODULE))
+		return -EBUSY;
+
+	md = dm_get_md(dev);
+	if (!md) {
+		res = -ENOENT;
+		goto out_module;
+	}
+
+	table = dm_get_live_table(md, &srcu_idx);
+	if (!table) {
+		res = -ENOENT;
+		goto out_md;
+	}
+
+	memset(buf, 0, buf_len);
+
+	num_targets = dm_table_get_num_targets(table);
+
+	for (i = 0; i < num_targets; i++) {
+		struct dm_target *ti = dm_table_get_target(table, i);
+
+		if (!ti)
+			continue;
+
+		if (target_name && strcmp(ti->type->name, target_name))
+			continue;
+
+		if (!ti->type->status)
+			continue;
+
+		ti->type->status(ti, type, 0, buf_ptr, buf + buf_len - buf_ptr);
+
+		if (!*buf_ptr)
+			continue;
+
+		len = strlen(buf_ptr);
+		buf_ptr += len + 1;
+
+		if (buf_ptr == buf + buf_len)
+			break;
+
+		res += len + 1;
+	}
+
+	dm_put_live_table(md, srcu_idx);
+out_md:
+	dm_put(md);
+out_module:
+	module_put(THIS_MODULE);
+	return res;
+}
+
 static int __init local_init(void)
 {
 	int r;
@@ -275,6 +343,7 @@ static int __init dm_init(void)
 			goto bad;
 	}
 
+	status_fn = _dm_get_status;
 	return 0;
 bad:
 	while (i--)
@@ -287,6 +356,8 @@ static void __exit dm_exit(void)
 {
 	int i = ARRAY_SIZE(_exits);
 
+	status_fn = NULL;
+
 	while (i--)
 		_exits[i]();
 
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index a7df155ea49b..d97b296d3104 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -487,6 +487,9 @@ int dm_report_zones(struct block_device *bdev, sector_t start, sector_t sector,
 		    struct dm_report_zones_args *args, unsigned int nr_zones);
 #endif /* CONFIG_BLK_DEV_ZONED */
 
+ssize_t dm_get_status(dev_t dev, status_type_t type, const char *target_name,
+		      u8 *buf, size_t buf_len);
+
 /*
  * Device mapper functions to parse and create devices specified by the
  * parameter "dm-mod.create="
-- 
2.32.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ