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: <20230126033358.1880-3-demi@invisiblethingslab.com>
Date:   Wed, 25 Jan 2023 22:33:54 -0500
From:   Demi Marie Obenour <demi@...isiblethingslab.com>
To:     Alasdair Kergon <agk@...hat.com>,
        Mike Snitzer <snitzer@...nel.org>, dm-devel@...hat.com
Cc:     Demi Marie Obenour <demi@...isiblethingslab.com>,
        Marek Marczykowski-Górecki 
        <marmarek@...isiblethingslab.com>, linux-kernel@...r.kernel.org
Subject: [RFC PATCH 2/7] Allow userspace to get an FD to a newly-created DM device

This allows creating a device-mapper device, opening it, and setting it
to be deleted when unused in a single atomic operation.

Signed-off-by: Demi Marie Obenour <demi@...isiblethingslab.com>
---
 drivers/md/dm-ioctl.c         | 67 +++++++++++++++++++++++++++++------
 include/uapi/linux/dm-ioctl.h | 16 ++++++++-
 2 files changed, 72 insertions(+), 11 deletions(-)

diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 36fc6ae4737a05ab53ab67a8ccee525cb5fda082..05438dedcd17b7cac470fcc5a9721d67daad4bfb 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -853,9 +853,21 @@ static void __dev_status(struct mapped_device *md, struct dm_ioctl *param)
 
 static int dev_create(struct file *filp, struct dm_ioctl *param, size_t param_size)
 {
-	int r, m = DM_ANY_MINOR;
+	int r, m = DM_ANY_MINOR, fd;
 	struct mapped_device *md;
 
+	/* Do not allow unknown flags */
+	if (param->flags > (2 * DM_FILE_DESCRIPTOR_FLAG - 1))
+		return -EINVAL;
+
+	/*
+	 * Do not allow creating a device that would just be destroyed
+	 * before the ioctl returns.
+	 */
+	if ((param->flags & DM_DEFERRED_REMOVE) &&
+	    !(param->flags & DM_FILE_DESCRIPTOR_FLAG))
+		return -EINVAL;
+
 	r = check_name(param->name);
 	if (r)
 		return r;
@@ -867,20 +879,55 @@ static int dev_create(struct file *filp, struct dm_ioctl *param, size_t param_si
 	if (r)
 		return r;
 
-	r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
-	if (r) {
-		dm_put(md);
-		dm_destroy(md);
-		return r;
-	}
-
 	param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
 
+	r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
+	if (r)
+		goto out_put;
+
+	if (param->flags & DM_FILE_DESCRIPTOR_FLAG) {
+		struct block_device *bdev = dm_disk(md)->part0;
+		struct file *file;
+
+		fd = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
+		if (fd < 0) {
+			r = fd;
+			goto out_put;
+		}
+
+		file = blkdev_get_file(bdev, O_RDWR|O_CLOEXEC, NULL);
+		if (IS_ERR(file)) {
+			r = PTR_ERR(file);
+			goto out_put_fd;
+		}
+
+		/*
+		 * Simulate opening the device.  The other checks in
+		 * dm_blk_open() are not necessary becuase we have a reference
+		 * to the `struct md`.
+		 */
+		atomic_inc(&md->open_count);
+		fd_install(fd, file);
+		param->file_descriptor = fd;
+	}
+
+	/*
+	 * If userspace requests it, automatically delete the device
+	 * when it is no longer used
+	 */
+	if (param->flags & DM_DEFERRED_REMOVE)
+		set_bit(DMF_DEFERRED_REMOVE, &md->flags);
+
 	__dev_status(md, param);
-
 	dm_put(md);
-
 	return 0;
+
+out_put_fd:
+	put_unused_fd(fd);
+out_put:
+	dm_put(md);
+	dm_destroy(md);
+	return r;
 }
 
 /*
diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h
index 7edf335778bae1cb206f6dd4d44e9cf7fb9da35c..30a6260ed7e06ff71fad1675dd4e7f9325d752a6 100644
--- a/include/uapi/linux/dm-ioctl.h
+++ b/include/uapi/linux/dm-ioctl.h
@@ -136,7 +136,13 @@ struct dm_ioctl {
 	 * For output, the ioctls return the event number, not the cookie.
 	 */
 	__u32 event_nr;      	/* in/out */
-	__u32 padding;
+
+	union {
+		/* Padding for named devices */
+		__u32 padding;
+		/* For anonymous devices, this is a file descriptor. */
+		__u32 file_descriptor;
+	};
 
 	__u64 dev;		/* in/out */
 
@@ -382,4 +388,12 @@ enum {
  */
 #define DM_IMA_MEASUREMENT_FLAG	(1 << 19) /* In */
 
+/*
+ * If set in a DM_DEV_CREATE ioctl(), sets the file_descriptor field
+ * to a valid file descriptor.  This can be combined with DM_DEFERRED_REMOVE
+ * to cause the device to be destroyed when the file descriptor is closed
+ * and is otherwise unused.
+ */
+#define DM_FILE_DESCRIPTOR_FLAG		(1 << 20) /* In */
+
 #endif				/* _LINUX_DM_IOCTL_H */
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ