linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] nbd: provide a way for userspace processes to identify device backends
@ 2021-04-29 10:28 Prasanna Kumar Kalever
  2021-04-30  2:14 ` Xiubo Li
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Prasanna Kumar Kalever @ 2021-04-29 10:28 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-block, nbd, josef, axboe, idryomov, xiubli, Prasanna Kumar Kalever

Problem:
On reconfigure of device, there is no way to defend if the backend
storage is matching with the initial backend storage.

Say, if an initial connect request for backend "pool1/image1" got
mapped to /dev/nbd0 and the userspace process is terminated. A next
reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
use /dev/nbd0 for a different backend "pool1/image2"

For example, an operation like below could be dangerous:

$ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
/dev/nbd0
$ sudo blkid /dev/nbd0
/dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
$ sudo pkill -9 rbd-nbd
$ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
/dev/nbd0
$ sudo blkid /dev/nbd0
/dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"

Solution:
Provide a way for userspace processes to keep some metadata to identify
between the device and the backend, so that when a reconfigure request is
made, we can compare and avoid such dangerous operations.

With this solution, as part of the initial connect request, backend
path can be stored in the sysfs per device config, so that on a reconfigure
request it's easy to check if the backend path matches with the initial
connect backend path.

Please note, ioctl interface to nbd will not have these changes, as there
won't be any reconfigure.

Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
---
 drivers/block/nbd.c              | 60 +++++++++++++++++++++++++++++++-
 include/uapi/linux/nbd-netlink.h |  1 +
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 4ff71b579cfc..b5022187ad9c 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -79,6 +79,7 @@ struct link_dead_args {
 #define NBD_RT_HAS_CONFIG_REF		4
 #define NBD_RT_BOUND			5
 #define NBD_RT_DISCONNECT_ON_CLOSE	6
+#define NBD_RT_HAS_BACKEND_FILE		7
 
 #define NBD_DESTROY_ON_DISCONNECT	0
 #define NBD_DISCONNECT_REQUESTED	1
@@ -119,6 +120,8 @@ struct nbd_device {
 
 	struct completion *destroy_complete;
 	unsigned long flags;
+
+	char *backend;
 };
 
 #define NBD_CMD_REQUEUED	1
@@ -216,6 +219,20 @@ static const struct device_attribute pid_attr = {
 	.show = pid_show,
 };
 
+static ssize_t backend_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct gendisk *disk = dev_to_disk(dev);
+	struct nbd_device *nbd = (struct nbd_device *)disk->private_data;
+
+	return sprintf(buf, "%s\n", nbd->backend ?: "");
+}
+
+static const struct device_attribute backend_attr = {
+	.attr = { .name = "backend", .mode = 0444},
+	.show = backend_show,
+};
+
 static void nbd_dev_remove(struct nbd_device *nbd)
 {
 	struct gendisk *disk = nbd->disk;
@@ -1215,6 +1232,12 @@ static void nbd_config_put(struct nbd_device *nbd)
 				       &config->runtime_flags))
 			device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
 		nbd->task_recv = NULL;
+		if (test_and_clear_bit(NBD_RT_HAS_BACKEND_FILE,
+				       &config->runtime_flags)) {
+			device_remove_file(disk_to_dev(nbd->disk), &backend_attr);
+			kfree(nbd->backend);
+			nbd->backend = NULL;
+		}
 		nbd_clear_sock(nbd);
 		if (config->num_connections) {
 			int i;
@@ -1274,7 +1297,7 @@ static int nbd_start_device(struct nbd_device *nbd)
 
 	error = device_create_file(disk_to_dev(nbd->disk), &pid_attr);
 	if (error) {
-		dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n");
+		dev_err(disk_to_dev(nbd->disk), "device_create_file failed for pid!\n");
 		return error;
 	}
 	set_bit(NBD_RT_HAS_PID_FILE, &config->runtime_flags);
@@ -1681,6 +1704,7 @@ static int nbd_dev_add(int index)
 		BLK_MQ_F_BLOCKING;
 	nbd->tag_set.driver_data = nbd;
 	nbd->destroy_complete = NULL;
+	nbd->backend = NULL;
 
 	err = blk_mq_alloc_tag_set(&nbd->tag_set);
 	if (err)
@@ -1754,6 +1778,7 @@ static const struct nla_policy nbd_attr_policy[NBD_ATTR_MAX + 1] = {
 	[NBD_ATTR_SOCKETS]		=	{ .type = NLA_NESTED},
 	[NBD_ATTR_DEAD_CONN_TIMEOUT]	=	{ .type = NLA_U64 },
 	[NBD_ATTR_DEVICE_LIST]		=	{ .type = NLA_NESTED},
+	[NBD_ATTR_BACKEND_IDENTIFIER]	=	{ .type = NLA_STRING},
 };
 
 static const struct nla_policy nbd_sock_policy[NBD_SOCK_MAX + 1] = {
@@ -1956,6 +1981,23 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
 		}
 	}
 	ret = nbd_start_device(nbd);
+	if (ret)
+		goto out;
+	if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
+		nbd->backend = nla_strdup(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
+					  GFP_KERNEL);
+		if (!nbd->backend) {
+			ret = -ENOMEM;
+			goto out;
+		}
+	}
+	ret = device_create_file(disk_to_dev(nbd->disk), &backend_attr);
+	if (ret) {
+		dev_err(disk_to_dev(nbd->disk),
+			"device_create_file failed for backend!\n");
+		goto out;
+	}
+	set_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags);
 out:
 	mutex_unlock(&nbd->config_lock);
 	if (!ret) {
@@ -2048,6 +2090,22 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
 		       index);
 		return -EINVAL;
 	}
+	if (nbd->backend) {
+		if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
+			if (nla_strcmp(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
+				       nbd->backend)) {
+				mutex_unlock(&nbd_index_mutex);
+				dev_err(nbd_to_dev(nbd),
+					"backend image doesn't match with %s\n",
+					nbd->backend);
+				return -EINVAL;
+			}
+		} else {
+			mutex_unlock(&nbd_index_mutex);
+			dev_err(nbd_to_dev(nbd), "must specify backend\n");
+			return -EINVAL;
+		}
+	}
 	if (!refcount_inc_not_zero(&nbd->refs)) {
 		mutex_unlock(&nbd_index_mutex);
 		printk(KERN_ERR "nbd: device at index %d is going down\n",
diff --git a/include/uapi/linux/nbd-netlink.h b/include/uapi/linux/nbd-netlink.h
index c5d0ef7aa7d5..2d0b90964227 100644
--- a/include/uapi/linux/nbd-netlink.h
+++ b/include/uapi/linux/nbd-netlink.h
@@ -35,6 +35,7 @@ enum {
 	NBD_ATTR_SOCKETS,
 	NBD_ATTR_DEAD_CONN_TIMEOUT,
 	NBD_ATTR_DEVICE_LIST,
+	NBD_ATTR_BACKEND_IDENTIFIER,
 	__NBD_ATTR_MAX,
 };
 #define NBD_ATTR_MAX (__NBD_ATTR_MAX - 1)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-04-29 10:28 [PATCH] nbd: provide a way for userspace processes to identify device backends Prasanna Kumar Kalever
@ 2021-04-30  2:14 ` Xiubo Li
  2021-05-17 14:42   ` Prasanna Kalever
  2021-05-18  0:29 ` Ming Lei
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Xiubo Li @ 2021-04-30  2:14 UTC (permalink / raw)
  To: Prasanna Kumar Kalever, linux-kernel
  Cc: linux-block, nbd, josef, axboe, idryomov

On 2021/4/29 18:28, Prasanna Kumar Kalever wrote:
> Problem:
> On reconfigure of device, there is no way to defend if the backend
> storage is matching with the initial backend storage.
>
> Say, if an initial connect request for backend "pool1/image1" got
> mapped to /dev/nbd0 and the userspace process is terminated. A next
> reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> use /dev/nbd0 for a different backend "pool1/image2"
>
> For example, an operation like below could be dangerous:
>
> $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> $ sudo pkill -9 rbd-nbd
> $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
>
> Solution:
> Provide a way for userspace processes to keep some metadata to identify
> between the device and the backend, so that when a reconfigure request is
> made, we can compare and avoid such dangerous operations.
>
> With this solution, as part of the initial connect request, backend
> path can be stored in the sysfs per device config, so that on a reconfigure
> request it's easy to check if the backend path matches with the initial
> connect backend path.
>
> Please note, ioctl interface to nbd will not have these changes, as there
> won't be any reconfigure.
>
> Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
> ---
>   drivers/block/nbd.c              | 60 +++++++++++++++++++++++++++++++-
>   include/uapi/linux/nbd-netlink.h |  1 +
>   2 files changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index 4ff71b579cfc..b5022187ad9c 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -79,6 +79,7 @@ struct link_dead_args {
>   #define NBD_RT_HAS_CONFIG_REF		4
>   #define NBD_RT_BOUND			5
>   #define NBD_RT_DISCONNECT_ON_CLOSE	6
> +#define NBD_RT_HAS_BACKEND_FILE		7
>   
>   #define NBD_DESTROY_ON_DISCONNECT	0
>   #define NBD_DISCONNECT_REQUESTED	1
> @@ -119,6 +120,8 @@ struct nbd_device {
>   
>   	struct completion *destroy_complete;
>   	unsigned long flags;
> +
> +	char *backend;
>   };
>   
>   #define NBD_CMD_REQUEUED	1
> @@ -216,6 +219,20 @@ static const struct device_attribute pid_attr = {
>   	.show = pid_show,
>   };
>   
> +static ssize_t backend_show(struct device *dev,
> +		struct device_attribute *attr, char *buf)
> +{
> +	struct gendisk *disk = dev_to_disk(dev);
> +	struct nbd_device *nbd = (struct nbd_device *)disk->private_data;
> +
> +	return sprintf(buf, "%s\n", nbd->backend ?: "");
> +}
> +
> +static const struct device_attribute backend_attr = {
> +	.attr = { .name = "backend", .mode = 0444},
> +	.show = backend_show,
> +};
> +
>   static void nbd_dev_remove(struct nbd_device *nbd)
>   {
>   	struct gendisk *disk = nbd->disk;
> @@ -1215,6 +1232,12 @@ static void nbd_config_put(struct nbd_device *nbd)
>   				       &config->runtime_flags))
>   			device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
>   		nbd->task_recv = NULL;
> +		if (test_and_clear_bit(NBD_RT_HAS_BACKEND_FILE,
> +				       &config->runtime_flags)) {
> +			device_remove_file(disk_to_dev(nbd->disk), &backend_attr);
> +			kfree(nbd->backend);
> +			nbd->backend = NULL;
> +		}
>   		nbd_clear_sock(nbd);
>   		if (config->num_connections) {
>   			int i;
> @@ -1274,7 +1297,7 @@ static int nbd_start_device(struct nbd_device *nbd)
>   
>   	error = device_create_file(disk_to_dev(nbd->disk), &pid_attr);
>   	if (error) {
> -		dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n");
> +		dev_err(disk_to_dev(nbd->disk), "device_create_file failed for pid!\n");
>   		return error;
>   	}
>   	set_bit(NBD_RT_HAS_PID_FILE, &config->runtime_flags);
> @@ -1681,6 +1704,7 @@ static int nbd_dev_add(int index)
>   		BLK_MQ_F_BLOCKING;
>   	nbd->tag_set.driver_data = nbd;
>   	nbd->destroy_complete = NULL;
> +	nbd->backend = NULL;
>   
>   	err = blk_mq_alloc_tag_set(&nbd->tag_set);
>   	if (err)
> @@ -1754,6 +1778,7 @@ static const struct nla_policy nbd_attr_policy[NBD_ATTR_MAX + 1] = {
>   	[NBD_ATTR_SOCKETS]		=	{ .type = NLA_NESTED},
>   	[NBD_ATTR_DEAD_CONN_TIMEOUT]	=	{ .type = NLA_U64 },
>   	[NBD_ATTR_DEVICE_LIST]		=	{ .type = NLA_NESTED},
> +	[NBD_ATTR_BACKEND_IDENTIFIER]	=	{ .type = NLA_STRING},
>   };
>   
>   static const struct nla_policy nbd_sock_policy[NBD_SOCK_MAX + 1] = {
> @@ -1956,6 +1981,23 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
>   		}
>   	}
>   	ret = nbd_start_device(nbd);
> +	if (ret)
> +		goto out;
> +	if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
> +		nbd->backend = nla_strdup(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
> +					  GFP_KERNEL);
> +		if (!nbd->backend) {
> +			ret = -ENOMEM;
> +			goto out;
> +		}
> +	}
> +	ret = device_create_file(disk_to_dev(nbd->disk), &backend_attr);
> +	if (ret) {
> +		dev_err(disk_to_dev(nbd->disk),
> +			"device_create_file failed for backend!\n");
> +		goto out;
> +	}
> +	set_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags);
>   out:
>   	mutex_unlock(&nbd->config_lock);
>   	if (!ret) {
> @@ -2048,6 +2090,22 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
>   		       index);
>   		return -EINVAL;
>   	}
> +	if (nbd->backend) {
> +		if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
> +			if (nla_strcmp(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
> +				       nbd->backend)) {
> +				mutex_unlock(&nbd_index_mutex);
> +				dev_err(nbd_to_dev(nbd),
> +					"backend image doesn't match with %s\n",
> +					nbd->backend);
> +				return -EINVAL;
> +			}
> +		} else {
> +			mutex_unlock(&nbd_index_mutex);
> +			dev_err(nbd_to_dev(nbd), "must specify backend\n");
> +			return -EINVAL;
> +		}
> +	}
>   	if (!refcount_inc_not_zero(&nbd->refs)) {
>   		mutex_unlock(&nbd_index_mutex);
>   		printk(KERN_ERR "nbd: device at index %d is going down\n",
> diff --git a/include/uapi/linux/nbd-netlink.h b/include/uapi/linux/nbd-netlink.h
> index c5d0ef7aa7d5..2d0b90964227 100644
> --- a/include/uapi/linux/nbd-netlink.h
> +++ b/include/uapi/linux/nbd-netlink.h
> @@ -35,6 +35,7 @@ enum {
>   	NBD_ATTR_SOCKETS,
>   	NBD_ATTR_DEAD_CONN_TIMEOUT,
>   	NBD_ATTR_DEVICE_LIST,
> +	NBD_ATTR_BACKEND_IDENTIFIER,
>   	__NBD_ATTR_MAX,
>   };
>   #define NBD_ATTR_MAX (__NBD_ATTR_MAX - 1)

Reviewed-by: Xiubo Li <xiubli@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-04-30  2:14 ` Xiubo Li
@ 2021-05-17 14:42   ` Prasanna Kalever
  0 siblings, 0 replies; 14+ messages in thread
From: Prasanna Kalever @ 2021-05-17 14:42 UTC (permalink / raw)
  To: josef, axboe, Ming Lei
  Cc: Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Ilya Dryomov, Xiubo Li, stable

On Fri, Apr 30, 2021 at 7:44 AM Xiubo Li <xiubli@redhat.com> wrote:
>
> On 2021/4/29 18:28, Prasanna Kumar Kalever wrote:
> > Problem:
> > On reconfigure of device, there is no way to defend if the backend
> > storage is matching with the initial backend storage.
> >
> > Say, if an initial connect request for backend "pool1/image1" got
> > mapped to /dev/nbd0 and the userspace process is terminated. A next
> > reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> > use /dev/nbd0 for a different backend "pool1/image2"
> >
> > For example, an operation like below could be dangerous:
> >
> > $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> > /dev/nbd0
> > $ sudo blkid /dev/nbd0
> > /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> > $ sudo pkill -9 rbd-nbd
> > $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> > /dev/nbd0
> > $ sudo blkid /dev/nbd0
> > /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
> >
> > Solution:
> > Provide a way for userspace processes to keep some metadata to identify
> > between the device and the backend, so that when a reconfigure request is
> > made, we can compare and avoid such dangerous operations.
> >
> > With this solution, as part of the initial connect request, backend
> > path can be stored in the sysfs per device config, so that on a reconfigure
> > request it's easy to check if the backend path matches with the initial
> > connect backend path.
> >
> > Please note, ioctl interface to nbd will not have these changes, as there
> > won't be any reconfigure.
> >
> > Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
> > ---
> >   drivers/block/nbd.c              | 60 +++++++++++++++++++++++++++++++-
> >   include/uapi/linux/nbd-netlink.h |  1 +
> >   2 files changed, 60 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> > index 4ff71b579cfc..b5022187ad9c 100644
> > --- a/drivers/block/nbd.c
> > +++ b/drivers/block/nbd.c
> > @@ -79,6 +79,7 @@ struct link_dead_args {
> >   #define NBD_RT_HAS_CONFIG_REF               4
> >   #define NBD_RT_BOUND                        5
> >   #define NBD_RT_DISCONNECT_ON_CLOSE  6
> > +#define NBD_RT_HAS_BACKEND_FILE              7
> >
> >   #define NBD_DESTROY_ON_DISCONNECT   0
> >   #define NBD_DISCONNECT_REQUESTED    1
> > @@ -119,6 +120,8 @@ struct nbd_device {
> >
> >       struct completion *destroy_complete;
> >       unsigned long flags;
> > +
> > +     char *backend;
> >   };
> >
> >   #define NBD_CMD_REQUEUED    1
> > @@ -216,6 +219,20 @@ static const struct device_attribute pid_attr = {
> >       .show = pid_show,
> >   };
> >
> > +static ssize_t backend_show(struct device *dev,
> > +             struct device_attribute *attr, char *buf)
> > +{
> > +     struct gendisk *disk = dev_to_disk(dev);
> > +     struct nbd_device *nbd = (struct nbd_device *)disk->private_data;
> > +
> > +     return sprintf(buf, "%s\n", nbd->backend ?: "");
> > +}
> > +
> > +static const struct device_attribute backend_attr = {
> > +     .attr = { .name = "backend", .mode = 0444},
> > +     .show = backend_show,
> > +};
> > +
> >   static void nbd_dev_remove(struct nbd_device *nbd)
> >   {
> >       struct gendisk *disk = nbd->disk;
> > @@ -1215,6 +1232,12 @@ static void nbd_config_put(struct nbd_device *nbd)
> >                                      &config->runtime_flags))
> >                       device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
> >               nbd->task_recv = NULL;
> > +             if (test_and_clear_bit(NBD_RT_HAS_BACKEND_FILE,
> > +                                    &config->runtime_flags)) {
> > +                     device_remove_file(disk_to_dev(nbd->disk), &backend_attr);
> > +                     kfree(nbd->backend);
> > +                     nbd->backend = NULL;
> > +             }
> >               nbd_clear_sock(nbd);
> >               if (config->num_connections) {
> >                       int i;
> > @@ -1274,7 +1297,7 @@ static int nbd_start_device(struct nbd_device *nbd)
> >
> >       error = device_create_file(disk_to_dev(nbd->disk), &pid_attr);
> >       if (error) {
> > -             dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n");
> > +             dev_err(disk_to_dev(nbd->disk), "device_create_file failed for pid!\n");
> >               return error;
> >       }
> >       set_bit(NBD_RT_HAS_PID_FILE, &config->runtime_flags);
> > @@ -1681,6 +1704,7 @@ static int nbd_dev_add(int index)
> >               BLK_MQ_F_BLOCKING;
> >       nbd->tag_set.driver_data = nbd;
> >       nbd->destroy_complete = NULL;
> > +     nbd->backend = NULL;
> >
> >       err = blk_mq_alloc_tag_set(&nbd->tag_set);
> >       if (err)
> > @@ -1754,6 +1778,7 @@ static const struct nla_policy nbd_attr_policy[NBD_ATTR_MAX + 1] = {
> >       [NBD_ATTR_SOCKETS]              =       { .type = NLA_NESTED},
> >       [NBD_ATTR_DEAD_CONN_TIMEOUT]    =       { .type = NLA_U64 },
> >       [NBD_ATTR_DEVICE_LIST]          =       { .type = NLA_NESTED},
> > +     [NBD_ATTR_BACKEND_IDENTIFIER]   =       { .type = NLA_STRING},
> >   };
> >
> >   static const struct nla_policy nbd_sock_policy[NBD_SOCK_MAX + 1] = {
> > @@ -1956,6 +1981,23 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
> >               }
> >       }
> >       ret = nbd_start_device(nbd);
> > +     if (ret)
> > +             goto out;
> > +     if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
> > +             nbd->backend = nla_strdup(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
> > +                                       GFP_KERNEL);
> > +             if (!nbd->backend) {
> > +                     ret = -ENOMEM;
> > +                     goto out;
> > +             }
> > +     }
> > +     ret = device_create_file(disk_to_dev(nbd->disk), &backend_attr);
> > +     if (ret) {
> > +             dev_err(disk_to_dev(nbd->disk),
> > +                     "device_create_file failed for backend!\n");
> > +             goto out;
> > +     }
> > +     set_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags);
> >   out:
> >       mutex_unlock(&nbd->config_lock);
> >       if (!ret) {
> > @@ -2048,6 +2090,22 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
> >                      index);
> >               return -EINVAL;
> >       }
> > +     if (nbd->backend) {
> > +             if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
> > +                     if (nla_strcmp(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
> > +                                    nbd->backend)) {
> > +                             mutex_unlock(&nbd_index_mutex);
> > +                             dev_err(nbd_to_dev(nbd),
> > +                                     "backend image doesn't match with %s\n",
> > +                                     nbd->backend);
> > +                             return -EINVAL;
> > +                     }
> > +             } else {
> > +                     mutex_unlock(&nbd_index_mutex);
> > +                     dev_err(nbd_to_dev(nbd), "must specify backend\n");
> > +                     return -EINVAL;
> > +             }
> > +     }
> >       if (!refcount_inc_not_zero(&nbd->refs)) {
> >               mutex_unlock(&nbd_index_mutex);
> >               printk(KERN_ERR "nbd: device at index %d is going down\n",
> > diff --git a/include/uapi/linux/nbd-netlink.h b/include/uapi/linux/nbd-netlink.h
> > index c5d0ef7aa7d5..2d0b90964227 100644
> > --- a/include/uapi/linux/nbd-netlink.h
> > +++ b/include/uapi/linux/nbd-netlink.h
> > @@ -35,6 +35,7 @@ enum {
> >       NBD_ATTR_SOCKETS,
> >       NBD_ATTR_DEAD_CONN_TIMEOUT,
> >       NBD_ATTR_DEVICE_LIST,
> > +     NBD_ATTR_BACKEND_IDENTIFIER,
> >       __NBD_ATTR_MAX,
> >   };
> >   #define NBD_ATTR_MAX (__NBD_ATTR_MAX - 1)
>
> Reviewed-by: Xiubo Li <xiubli@redhat.com>

Thank you Xiubo Li.

Assuming this patch got lost, attempting to bring this patch onto the
top with a friendly reminder.
I sincerely request the maintainers to please take a look.

Many Thanks!
--
Prasanna


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-04-29 10:28 [PATCH] nbd: provide a way for userspace processes to identify device backends Prasanna Kumar Kalever
  2021-04-30  2:14 ` Xiubo Li
@ 2021-05-18  0:29 ` Ming Lei
  2021-05-18  7:52   ` Prasanna Kalever
  2021-06-16  8:42 ` Prasanna Kalever
  2021-06-16 12:59 ` Jens Axboe
  3 siblings, 1 reply; 14+ messages in thread
From: Ming Lei @ 2021-05-18  0:29 UTC (permalink / raw)
  To: Prasanna Kumar Kalever
  Cc: linux-kernel, linux-block, nbd, josef, axboe, idryomov, xiubli,
	Matteo Croce

Hello Prasanna,

On Thu, Apr 29, 2021 at 03:58:28PM +0530, Prasanna Kumar Kalever wrote:
> Problem:
> On reconfigure of device, there is no way to defend if the backend
> storage is matching with the initial backend storage.
> 
> Say, if an initial connect request for backend "pool1/image1" got
> mapped to /dev/nbd0 and the userspace process is terminated. A next
> reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> use /dev/nbd0 for a different backend "pool1/image2"
> 
> For example, an operation like below could be dangerous:

Can you explain a bit why it is dangerous?

> 
> $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> $ sudo pkill -9 rbd-nbd
> $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
> 
> Solution:
> Provide a way for userspace processes to keep some metadata to identify
> between the device and the backend, so that when a reconfigure request is
> made, we can compare and avoid such dangerous operations.
> 
> With this solution, as part of the initial connect request, backend
> path can be stored in the sysfs per device config, so that on a reconfigure
> request it's easy to check if the backend path matches with the initial
> connect backend path.
> 
> Please note, ioctl interface to nbd will not have these changes, as there
> won't be any reconfigure.

BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
is added for addressing this issue, what do you think of that generic
approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
for addressing this issue?

https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r

Thanks,
Ming


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-18  0:29 ` Ming Lei
@ 2021-05-18  7:52   ` Prasanna Kalever
  2021-05-18  9:24     ` Ming Lei
  2021-05-19 14:33     ` Matteo Croce
  0 siblings, 2 replies; 14+ messages in thread
From: Prasanna Kalever @ 2021-05-18  7:52 UTC (permalink / raw)
  To: Ming Lei
  Cc: Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, axboe, Ilya Dryomov, Xiubo Li, Matteo Croce

On Tue, May 18, 2021 at 6:00 AM Ming Lei <ming.lei@redhat.com> wrote:
>
> Hello Prasanna,
>
> On Thu, Apr 29, 2021 at 03:58:28PM +0530, Prasanna Kumar Kalever wrote:
> > Problem:
> > On reconfigure of device, there is no way to defend if the backend
> > storage is matching with the initial backend storage.
> >
> > Say, if an initial connect request for backend "pool1/image1" got
> > mapped to /dev/nbd0 and the userspace process is terminated. A next
> > reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> > use /dev/nbd0 for a different backend "pool1/image2"
> >
> > For example, an operation like below could be dangerous:
>

Hello Ming,

> Can you explain a bit why it is dangerous?

Yes, sure. Please check the below comments inline,

>
> >
> > $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> > /dev/nbd0
> > $ sudo blkid /dev/nbd0
> > /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"

On Map the rbd-nbd attempting to send NBD_CMD_CONNECT, for backend
'rbd-pool/ext4-image'. Post which kernel will allocate a new device
say /dev/nbd0 for backend file rbd-pool/ext4-image (format:
<pool>/<backendfile>)

> > $ sudo pkill -9 rbd-nbd

Assume normally or abnormally the userspace process (rbd-nbd here) is
terminated, but then as per the settings the device /dev/nbd0 is not
returned immediately, the kernel will wait for the
NBD_ATTR_DEAD_CONN_TIMEOUT to expire.

At this point two things could be possible:
1. if there is a reconfigure request from userspace within the timeout
then the kernel might reassign the same device /dev/nbd0.
2. if the timeout has expired, then the device will be relieved.

> > $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> > /dev/nbd0
> > $ sudo blkid /dev/nbd0
> > /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"

On attach the rbd-nbd attempt to send NBD_CMD_RECONFIGURE, after which
the kernel will assign '--device /dev/nbd0' to specified backend.

But there is a chance that userspace processes might accidentally send
NBD_CMD_RECONFIGURE claiming for /dev/nbd0 for a different backend
(rbd-pool/xfs-image instead of original rbd-pool/ext4-image).
Currently, there is no mechanism to verify if the backend provided
later with attach(NBD_CMD_RECONFIGURE) is matching with the one
provided originally with map(NBD_CMD_CONNECT) before granting for a
attach or reconfigure.

For example in the above-explained scenario:
Assume EXT4 on rbd-pool/ext4-image was mounted, after attach (Note:
device /dev/nbd0 is reconfigured to a different backend file) XFS on
rbd-pool/xfs-image would get corrupted. If there was an application
using /dev/nbd0 directly (as a raw block volume), it wouldn't be happy
either.

> >
> > Solution:
> > Provide a way for userspace processes to keep some metadata to identify
> > between the device and the backend, so that when a reconfigure request is
> > made, we can compare and avoid such dangerous operations.
> >
> > With this solution, as part of the initial connect request, backend
> > path can be stored in the sysfs per device config, so that on a reconfigure
> > request it's easy to check if the backend path matches with the initial
> > connect backend path.
> >
> > Please note, ioctl interface to nbd will not have these changes, as there
> > won't be any reconfigure.
>
> BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> is added for addressing this issue, what do you think of that generic
> approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> for addressing this issue?
>
> https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r

If I understand the changes and the background of the fix correctly, I
think with that fix author is trying to monotonically increase the seq
number and add it to the disk on every single device map/attach and
expose it through the sysfs, which will help the userspace processes
further to correlate events for particular and specific devices that
reuse the same loop device.

Coming back to my changes:
I think here with this fix, we are trying to solve a different
problem. The fix with this patch accepts a cookie or a backend string
(could be file-path or whatever id userspace choose to provide) from
userspace at the time of map and stores it in the sysfs
/sys/block/nbdX/backend path and persists it until unmap is issued on
the device (meaning that identity stays throughout the life cycle of
that device, no matter how many detach and attaches happen). If there
is a detach request in between (not unmap) then on the next attach
(reconfigure request to reuse the same device) the stored
cookie/UUID/backend-string will stand as a reference to verify if the
newly passed backend is matching with the actual backend passed at map
time to avoid any misconfigurations by accident and to safely proceed
with attach.


Thank you for the review.

BRs,
--
Prasanna

>
> Thanks,
> Ming
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-18  7:52   ` Prasanna Kalever
@ 2021-05-18  9:24     ` Ming Lei
  2021-05-18  9:49       ` Prasanna Kalever
  2021-05-19 14:33     ` Matteo Croce
  1 sibling, 1 reply; 14+ messages in thread
From: Ming Lei @ 2021-05-18  9:24 UTC (permalink / raw)
  To: Prasanna Kalever
  Cc: Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, axboe, Ilya Dryomov, Xiubo Li, Matteo Croce

On Tue, May 18, 2021 at 01:22:19PM +0530, Prasanna Kalever wrote:
> On Tue, May 18, 2021 at 6:00 AM Ming Lei <ming.lei@redhat.com> wrote:
> >
> > Hello Prasanna,
> >
> > On Thu, Apr 29, 2021 at 03:58:28PM +0530, Prasanna Kumar Kalever wrote:
> > > Problem:
> > > On reconfigure of device, there is no way to defend if the backend
> > > storage is matching with the initial backend storage.
> > >
> > > Say, if an initial connect request for backend "pool1/image1" got
> > > mapped to /dev/nbd0 and the userspace process is terminated. A next
> > > reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> > > use /dev/nbd0 for a different backend "pool1/image2"
> > >
> > > For example, an operation like below could be dangerous:
> >
> 
> Hello Ming,
> 
> > Can you explain a bit why it is dangerous?
> 
> Yes, sure. Please check the below comments inline,
> 
> >
> > >
> > > $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> > > /dev/nbd0
> > > $ sudo blkid /dev/nbd0
> > > /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> 
> On Map the rbd-nbd attempting to send NBD_CMD_CONNECT, for backend
> 'rbd-pool/ext4-image'. Post which kernel will allocate a new device
> say /dev/nbd0 for backend file rbd-pool/ext4-image (format:
> <pool>/<backendfile>)
> 
> > > $ sudo pkill -9 rbd-nbd
> 
> Assume normally or abnormally the userspace process (rbd-nbd here) is
> terminated, but then as per the settings the device /dev/nbd0 is not
> returned immediately, the kernel will wait for the
> NBD_ATTR_DEAD_CONN_TIMEOUT to expire.
> 
> At this point two things could be possible:
> 1. if there is a reconfigure request from userspace within the timeout
> then the kernel might reassign the same device /dev/nbd0.
> 2. if the timeout has expired, then the device will be relieved.
> 
> > > $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> > > /dev/nbd0
> > > $ sudo blkid /dev/nbd0
> > > /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
> 
> On attach the rbd-nbd attempt to send NBD_CMD_RECONFIGURE, after which
> the kernel will assign '--device /dev/nbd0' to specified backend.
> 
> But there is a chance that userspace processes might accidentally send
> NBD_CMD_RECONFIGURE claiming for /dev/nbd0 for a different backend
> (rbd-pool/xfs-image instead of original rbd-pool/ext4-image).
> Currently, there is no mechanism to verify if the backend provided
> later with attach(NBD_CMD_RECONFIGURE) is matching with the one
> provided originally with map(NBD_CMD_CONNECT) before granting for a
> attach or reconfigure.
> 
> For example in the above-explained scenario:
> Assume EXT4 on rbd-pool/ext4-image was mounted, after attach (Note:
> device /dev/nbd0 is reconfigured to a different backend file) XFS on
> rbd-pool/xfs-image would get corrupted. If there was an application
> using /dev/nbd0 directly (as a raw block volume), it wouldn't be happy
> either.

OK, got it. If I understand correctly, what you need is to not allow
reconfigure if the nbd disk is mounted, right?

> 
> > >
> > > Solution:
> > > Provide a way for userspace processes to keep some metadata to identify
> > > between the device and the backend, so that when a reconfigure request is
> > > made, we can compare and avoid such dangerous operations.
> > >
> > > With this solution, as part of the initial connect request, backend
> > > path can be stored in the sysfs per device config, so that on a reconfigure
> > > request it's easy to check if the backend path matches with the initial
> > > connect backend path.
> > >
> > > Please note, ioctl interface to nbd will not have these changes, as there
> > > won't be any reconfigure.
> >
> > BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> > is added for addressing this issue, what do you think of that generic
> > approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> > for addressing this issue?
> >
> > https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r
> 
> If I understand the changes and the background of the fix correctly, I
> think with that fix author is trying to monotonically increase the seq
> number and add it to the disk on every single device map/attach and
> expose it through the sysfs, which will help the userspace processes
> further to correlate events for particular and specific devices that
> reuse the same loop device.
> 
> Coming back to my changes:
> I think here with this fix, we are trying to solve a different
> problem. The fix with this patch accepts a cookie or a backend string
> (could be file-path or whatever id userspace choose to provide) from
> userspace at the time of map and stores it in the sysfs
> /sys/block/nbdX/backend path and persists it until unmap is issued on
> the device (meaning that identity stays throughout the life cycle of
> that device, no matter how many detach and attaches happen).

Your solution needs change from userspace side, so it isn't flexible.

> If there
> is a detach request in between (not unmap) then on the next attach
> (reconfigure request to reuse the same device) the stored
> cookie/UUID/backend-string will stand as a reference to verify if the
> newly passed backend is matching with the actual backend passed at map
> time to avoid any misconfigurations by accident and to safely proceed
> with attach.

We can avoid reconfigure if the nbd disk is opened exclusively, such as
mount, please see if the following patch can solve your probelm:

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 4ff71b579cfc..045532a68d1e 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -2063,6 +2063,11 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
 		return -EINVAL;
 	}
 
+	/* avoid changing device under exclusive owner */
+	ret = bd_prepare_to_claim(nbd->disk->part0, nbd_genl_reconfigure);
+	if (ret)
+		goto out_no_abort_claim;
+
 	mutex_lock(&nbd->config_lock);
 	config = nbd->config;
 	if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
@@ -2141,6 +2146,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
 		}
 	}
 out:
+	bd_abort_claiming(nbd->disk->part0, nbd_genl_reconfigure);
+out_no_abort_claim:
 	mutex_unlock(&nbd->config_lock);
 	nbd_config_put(nbd);
 	nbd_put(nbd);


Thanks,
Ming


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-18  9:24     ` Ming Lei
@ 2021-05-18  9:49       ` Prasanna Kalever
  2021-05-19  7:54         ` Ming Lei
  0 siblings, 1 reply; 14+ messages in thread
From: Prasanna Kalever @ 2021-05-18  9:49 UTC (permalink / raw)
  To: Ming Lei
  Cc: Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, axboe, Ilya Dryomov, Xiubo Li, Matteo Croce

On Tue, May 18, 2021 at 2:54 PM Ming Lei <ming.lei@redhat.com> wrote:
>
> On Tue, May 18, 2021 at 01:22:19PM +0530, Prasanna Kalever wrote:
> > On Tue, May 18, 2021 at 6:00 AM Ming Lei <ming.lei@redhat.com> wrote:
> > >
> > > Hello Prasanna,
> > >
> > > On Thu, Apr 29, 2021 at 03:58:28PM +0530, Prasanna Kumar Kalever wrote:
> > > > Problem:
> > > > On reconfigure of device, there is no way to defend if the backend
> > > > storage is matching with the initial backend storage.
> > > >
> > > > Say, if an initial connect request for backend "pool1/image1" got
> > > > mapped to /dev/nbd0 and the userspace process is terminated. A next
> > > > reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> > > > use /dev/nbd0 for a different backend "pool1/image2"
> > > >
> > > > For example, an operation like below could be dangerous:
> > >
> >
> > Hello Ming,
> >
> > > Can you explain a bit why it is dangerous?
> >
> > Yes, sure. Please check the below comments inline,
> >
> > >
> > > >
> > > > $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> > > > /dev/nbd0
> > > > $ sudo blkid /dev/nbd0
> > > > /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> >
> > On Map the rbd-nbd attempting to send NBD_CMD_CONNECT, for backend
> > 'rbd-pool/ext4-image'. Post which kernel will allocate a new device
> > say /dev/nbd0 for backend file rbd-pool/ext4-image (format:
> > <pool>/<backendfile>)
> >
> > > > $ sudo pkill -9 rbd-nbd
> >
> > Assume normally or abnormally the userspace process (rbd-nbd here) is
> > terminated, but then as per the settings the device /dev/nbd0 is not
> > returned immediately, the kernel will wait for the
> > NBD_ATTR_DEAD_CONN_TIMEOUT to expire.
> >
> > At this point two things could be possible:
> > 1. if there is a reconfigure request from userspace within the timeout
> > then the kernel might reassign the same device /dev/nbd0.
> > 2. if the timeout has expired, then the device will be relieved.
> >
> > > > $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> > > > /dev/nbd0
> > > > $ sudo blkid /dev/nbd0
> > > > /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
> >
> > On attach the rbd-nbd attempt to send NBD_CMD_RECONFIGURE, after which
> > the kernel will assign '--device /dev/nbd0' to specified backend.
> >
> > But there is a chance that userspace processes might accidentally send
> > NBD_CMD_RECONFIGURE claiming for /dev/nbd0 for a different backend
> > (rbd-pool/xfs-image instead of original rbd-pool/ext4-image).
> > Currently, there is no mechanism to verify if the backend provided
> > later with attach(NBD_CMD_RECONFIGURE) is matching with the one
> > provided originally with map(NBD_CMD_CONNECT) before granting for a
> > attach or reconfigure.
> >
> > For example in the above-explained scenario:
> > Assume EXT4 on rbd-pool/ext4-image was mounted, after attach (Note:
> > device /dev/nbd0 is reconfigured to a different backend file) XFS on
> > rbd-pool/xfs-image would get corrupted. If there was an application
> > using /dev/nbd0 directly (as a raw block volume), it wouldn't be happy
> > either.
>
> OK, got it. If I understand correctly, what you need is to not allow
> reconfigure if the nbd disk is mounted, right?

Excuse me, not exactly. Mount was one example scenario to showcase why
allowing attaching without any validation could be dangerous.
Basically, we want a way to check and verify if the backend specified
at map time and backend specified at attach(reconfigure) time are
matching for a given device, only if they are matching proceed to
attach else fail.

>
> >
> > > >
> > > > Solution:
> > > > Provide a way for userspace processes to keep some metadata to identify
> > > > between the device and the backend, so that when a reconfigure request is
> > > > made, we can compare and avoid such dangerous operations.
> > > >
> > > > With this solution, as part of the initial connect request, backend
> > > > path can be stored in the sysfs per device config, so that on a reconfigure
> > > > request it's easy to check if the backend path matches with the initial
> > > > connect backend path.
> > > >
> > > > Please note, ioctl interface to nbd will not have these changes, as there
> > > > won't be any reconfigure.
> > >
> > > BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> > > is added for addressing this issue, what do you think of that generic
> > > approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> > > for addressing this issue?
> > >
> > > https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r
> >
> > If I understand the changes and the background of the fix correctly, I
> > think with that fix author is trying to monotonically increase the seq
> > number and add it to the disk on every single device map/attach and
> > expose it through the sysfs, which will help the userspace processes
> > further to correlate events for particular and specific devices that
> > reuse the same loop device.
> >
> > Coming back to my changes:
> > I think here with this fix, we are trying to solve a different
> > problem. The fix with this patch accepts a cookie or a backend string
> > (could be file-path or whatever id userspace choose to provide) from
> > userspace at the time of map and stores it in the sysfs
> > /sys/block/nbdX/backend path and persists it until unmap is issued on
> > the device (meaning that identity stays throughout the life cycle of
> > that device, no matter how many detach and attaches happen).
>
> Your solution needs change from userspace side, so it isn't flexible.
>
> > If there
> > is a detach request in between (not unmap) then on the next attach
> > (reconfigure request to reuse the same device) the stored
> > cookie/UUID/backend-string will stand as a reference to verify if the
> > newly passed backend is matching with the actual backend passed at map
> > time to avoid any misconfigurations by accident and to safely proceed
> > with attach.
>
> We can avoid reconfigure if the nbd disk is opened exclusively, such as
> mount, please see if the following patch can solve your problem:

IMHO, we should almost never allow reconfigure/reattaching a given
device with a different backend (except in cases like live migration,
which the application should take care of), and not just when nbd disk
is opened exclusively.

When an attach (reconfigure) is issued, Its application's logic to
provide the same matching cookie (or device-string or a uuid) so that
kernel can validate it with /sys/block/nbdX/backend and continue
safely to attach and reassign the device back.

This is how it is supposed to be used:
https://github.com/ceph/ceph/pull/41323#issuecomment-842148450

Thanks!
--
Prasanna


>
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index 4ff71b579cfc..045532a68d1e 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -2063,6 +2063,11 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
>                 return -EINVAL;
>         }
>
> +       /* avoid changing device under exclusive owner */
> +       ret = bd_prepare_to_claim(nbd->disk->part0, nbd_genl_reconfigure);
> +       if (ret)
> +               goto out_no_abort_claim;
> +
>         mutex_lock(&nbd->config_lock);
>         config = nbd->config;
>         if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
> @@ -2141,6 +2146,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
>                 }
>         }
>  out:
> +       bd_abort_claiming(nbd->disk->part0, nbd_genl_reconfigure);
> +out_no_abort_claim:
>         mutex_unlock(&nbd->config_lock);
>         nbd_config_put(nbd);
>         nbd_put(nbd);
>
>
> Thanks,
> Ming
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-18  9:49       ` Prasanna Kalever
@ 2021-05-19  7:54         ` Ming Lei
  2021-05-19 14:17           ` Prasanna Kalever
  0 siblings, 1 reply; 14+ messages in thread
From: Ming Lei @ 2021-05-19  7:54 UTC (permalink / raw)
  To: Prasanna Kalever
  Cc: Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, axboe, Ilya Dryomov, Xiubo Li, Matteo Croce

On Tue, May 18, 2021 at 03:19:37PM +0530, Prasanna Kalever wrote:
> On Tue, May 18, 2021 at 2:54 PM Ming Lei <ming.lei@redhat.com> wrote:
> >
> > On Tue, May 18, 2021 at 01:22:19PM +0530, Prasanna Kalever wrote:
> > > On Tue, May 18, 2021 at 6:00 AM Ming Lei <ming.lei@redhat.com> wrote:
> > > >
> > > > Hello Prasanna,
> > > >
> > > > On Thu, Apr 29, 2021 at 03:58:28PM +0530, Prasanna Kumar Kalever wrote:
> > > > > Problem:
> > > > > On reconfigure of device, there is no way to defend if the backend
> > > > > storage is matching with the initial backend storage.
> > > > >
> > > > > Say, if an initial connect request for backend "pool1/image1" got
> > > > > mapped to /dev/nbd0 and the userspace process is terminated. A next
> > > > > reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> > > > > use /dev/nbd0 for a different backend "pool1/image2"
> > > > >
> > > > > For example, an operation like below could be dangerous:
> > > >
> > >
> > > Hello Ming,
> > >
> > > > Can you explain a bit why it is dangerous?
> > >
> > > Yes, sure. Please check the below comments inline,
> > >
> > > >
> > > > >
> > > > > $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> > > > > /dev/nbd0
> > > > > $ sudo blkid /dev/nbd0
> > > > > /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> > >
> > > On Map the rbd-nbd attempting to send NBD_CMD_CONNECT, for backend
> > > 'rbd-pool/ext4-image'. Post which kernel will allocate a new device
> > > say /dev/nbd0 for backend file rbd-pool/ext4-image (format:
> > > <pool>/<backendfile>)
> > >
> > > > > $ sudo pkill -9 rbd-nbd
> > >
> > > Assume normally or abnormally the userspace process (rbd-nbd here) is
> > > terminated, but then as per the settings the device /dev/nbd0 is not
> > > returned immediately, the kernel will wait for the
> > > NBD_ATTR_DEAD_CONN_TIMEOUT to expire.
> > >
> > > At this point two things could be possible:
> > > 1. if there is a reconfigure request from userspace within the timeout
> > > then the kernel might reassign the same device /dev/nbd0.
> > > 2. if the timeout has expired, then the device will be relieved.
> > >
> > > > > $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> > > > > /dev/nbd0
> > > > > $ sudo blkid /dev/nbd0
> > > > > /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
> > >
> > > On attach the rbd-nbd attempt to send NBD_CMD_RECONFIGURE, after which
> > > the kernel will assign '--device /dev/nbd0' to specified backend.
> > >
> > > But there is a chance that userspace processes might accidentally send
> > > NBD_CMD_RECONFIGURE claiming for /dev/nbd0 for a different backend
> > > (rbd-pool/xfs-image instead of original rbd-pool/ext4-image).
> > > Currently, there is no mechanism to verify if the backend provided
> > > later with attach(NBD_CMD_RECONFIGURE) is matching with the one
> > > provided originally with map(NBD_CMD_CONNECT) before granting for a
> > > attach or reconfigure.
> > >
> > > For example in the above-explained scenario:
> > > Assume EXT4 on rbd-pool/ext4-image was mounted, after attach (Note:
> > > device /dev/nbd0 is reconfigured to a different backend file) XFS on
> > > rbd-pool/xfs-image would get corrupted. If there was an application
> > > using /dev/nbd0 directly (as a raw block volume), it wouldn't be happy
> > > either.
> >
> > OK, got it. If I understand correctly, what you need is to not allow
> > reconfigure if the nbd disk is mounted, right?
> 
> Excuse me, not exactly. Mount was one example scenario to showcase why
> allowing attaching without any validation could be dangerous.

If nbd has exclusive owner, it shouldn't be reconfigured, which
can be respected in kernel side only, see loop_configure().

Not all application can provide NBD_ATTR_BACKEND_IDENTIFIER, so
claiming in nbd_genl_reconfigure() is still needed, IMO.

> Basically, we want a way to check and verify if the backend specified
> at map time and backend specified at attach(reconfigure) time are
> matching for a given device, only if they are matching proceed to
> attach else fail.
> 
> >
> > >
> > > > >
> > > > > Solution:
> > > > > Provide a way for userspace processes to keep some metadata to identify
> > > > > between the device and the backend, so that when a reconfigure request is
> > > > > made, we can compare and avoid such dangerous operations.
> > > > >
> > > > > With this solution, as part of the initial connect request, backend
> > > > > path can be stored in the sysfs per device config, so that on a reconfigure
> > > > > request it's easy to check if the backend path matches with the initial
> > > > > connect backend path.
> > > > >
> > > > > Please note, ioctl interface to nbd will not have these changes, as there
> > > > > won't be any reconfigure.
> > > >
> > > > BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> > > > is added for addressing this issue, what do you think of that generic
> > > > approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> > > > for addressing this issue?
> > > >
> > > > https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r
> > >
> > > If I understand the changes and the background of the fix correctly, I
> > > think with that fix author is trying to monotonically increase the seq
> > > number and add it to the disk on every single device map/attach and
> > > expose it through the sysfs, which will help the userspace processes
> > > further to correlate events for particular and specific devices that
> > > reuse the same loop device.
> > >
> > > Coming back to my changes:
> > > I think here with this fix, we are trying to solve a different
> > > problem. The fix with this patch accepts a cookie or a backend string
> > > (could be file-path or whatever id userspace choose to provide) from
> > > userspace at the time of map and stores it in the sysfs
> > > /sys/block/nbdX/backend path and persists it until unmap is issued on
> > > the device (meaning that identity stays throughout the life cycle of
> > > that device, no matter how many detach and attaches happen).
> >
> > Your solution needs change from userspace side, so it isn't flexible.
> >
> > > If there
> > > is a detach request in between (not unmap) then on the next attach
> > > (reconfigure request to reuse the same device) the stored
> > > cookie/UUID/backend-string will stand as a reference to verify if the
> > > newly passed backend is matching with the actual backend passed at map
> > > time to avoid any misconfigurations by accident and to safely proceed
> > > with attach.
> >
> > We can avoid reconfigure if the nbd disk is opened exclusively, such as
> > mount, please see if the following patch can solve your problem:
> 
> IMHO, we should almost never allow reconfigure/reattaching a given
> device with a different backend (except in cases like live migration,
> which the application should take care of), and not just when nbd disk
> is opened exclusively.
> 
> When an attach (reconfigure) is issued, Its application's logic to
> provide the same matching cookie (or device-string or a uuid) so that
> kernel can validate it with /sys/block/nbdX/backend and continue
> safely to attach and reassign the device back.

Your patch looks fine, but only new application can benefit from it, and
we still need to avoid reconfigure if the disk is opened exclusively for
old applications. Anyway:

Reviewed-by: Ming Lei <ming.lei@redhat.com>



Thanks,
Ming


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-19  7:54         ` Ming Lei
@ 2021-05-19 14:17           ` Prasanna Kalever
  0 siblings, 0 replies; 14+ messages in thread
From: Prasanna Kalever @ 2021-05-19 14:17 UTC (permalink / raw)
  To: Ming Lei
  Cc: Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, axboe, Ilya Dryomov, Xiubo Li, Matteo Croce

On Wed, May 19, 2021 at 1:24 PM Ming Lei <ming.lei@redhat.com> wrote:
>
> On Tue, May 18, 2021 at 03:19:37PM +0530, Prasanna Kalever wrote:
> > On Tue, May 18, 2021 at 2:54 PM Ming Lei <ming.lei@redhat.com> wrote:
> > >
> > > On Tue, May 18, 2021 at 01:22:19PM +0530, Prasanna Kalever wrote:
> > > > On Tue, May 18, 2021 at 6:00 AM Ming Lei <ming.lei@redhat.com> wrote:
> > > > >
> > > > > Hello Prasanna,
> > > > >
> > > > > On Thu, Apr 29, 2021 at 03:58:28PM +0530, Prasanna Kumar Kalever wrote:
> > > > > > Problem:
> > > > > > On reconfigure of device, there is no way to defend if the backend
> > > > > > storage is matching with the initial backend storage.
> > > > > >
> > > > > > Say, if an initial connect request for backend "pool1/image1" got
> > > > > > mapped to /dev/nbd0 and the userspace process is terminated. A next
> > > > > > reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> > > > > > use /dev/nbd0 for a different backend "pool1/image2"
> > > > > >
> > > > > > For example, an operation like below could be dangerous:
> > > > >
> > > >
> > > > Hello Ming,
> > > >
> > > > > Can you explain a bit why it is dangerous?
> > > >
> > > > Yes, sure. Please check the below comments inline,
> > > >
> > > > >
> > > > > >
> > > > > > $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> > > > > > /dev/nbd0
> > > > > > $ sudo blkid /dev/nbd0
> > > > > > /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> > > >
> > > > On Map the rbd-nbd attempting to send NBD_CMD_CONNECT, for backend
> > > > 'rbd-pool/ext4-image'. Post which kernel will allocate a new device
> > > > say /dev/nbd0 for backend file rbd-pool/ext4-image (format:
> > > > <pool>/<backendfile>)
> > > >
> > > > > > $ sudo pkill -9 rbd-nbd
> > > >
> > > > Assume normally or abnormally the userspace process (rbd-nbd here) is
> > > > terminated, but then as per the settings the device /dev/nbd0 is not
> > > > returned immediately, the kernel will wait for the
> > > > NBD_ATTR_DEAD_CONN_TIMEOUT to expire.
> > > >
> > > > At this point two things could be possible:
> > > > 1. if there is a reconfigure request from userspace within the timeout
> > > > then the kernel might reassign the same device /dev/nbd0.
> > > > 2. if the timeout has expired, then the device will be relieved.
> > > >
> > > > > > $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> > > > > > /dev/nbd0
> > > > > > $ sudo blkid /dev/nbd0
> > > > > > /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
> > > >
> > > > On attach the rbd-nbd attempt to send NBD_CMD_RECONFIGURE, after which
> > > > the kernel will assign '--device /dev/nbd0' to specified backend.
> > > >
> > > > But there is a chance that userspace processes might accidentally send
> > > > NBD_CMD_RECONFIGURE claiming for /dev/nbd0 for a different backend
> > > > (rbd-pool/xfs-image instead of original rbd-pool/ext4-image).
> > > > Currently, there is no mechanism to verify if the backend provided
> > > > later with attach(NBD_CMD_RECONFIGURE) is matching with the one
> > > > provided originally with map(NBD_CMD_CONNECT) before granting for a
> > > > attach or reconfigure.
> > > >
> > > > For example in the above-explained scenario:
> > > > Assume EXT4 on rbd-pool/ext4-image was mounted, after attach (Note:
> > > > device /dev/nbd0 is reconfigured to a different backend file) XFS on
> > > > rbd-pool/xfs-image would get corrupted. If there was an application
> > > > using /dev/nbd0 directly (as a raw block volume), it wouldn't be happy
> > > > either.
> > >
> > > OK, got it. If I understand correctly, what you need is to not allow
> > > reconfigure if the nbd disk is mounted, right?
> >
> > Excuse me, not exactly. Mount was one example scenario to showcase why
> > allowing attaching without any validation could be dangerous.
>
> If nbd has exclusive owner, it shouldn't be reconfigured, which
> can be respected in kernel side only, see loop_configure().
>
> Not all application can provide NBD_ATTR_BACKEND_IDENTIFIER, so
> claiming in nbd_genl_reconfigure() is still needed, IMO.
>
> > Basically, we want a way to check and verify if the backend specified
> > at map time and backend specified at attach(reconfigure) time are
> > matching for a given device, only if they are matching proceed to
> > attach else fail.
> >
> > >
> > > >
> > > > > >
> > > > > > Solution:
> > > > > > Provide a way for userspace processes to keep some metadata to identify
> > > > > > between the device and the backend, so that when a reconfigure request is
> > > > > > made, we can compare and avoid such dangerous operations.
> > > > > >
> > > > > > With this solution, as part of the initial connect request, backend
> > > > > > path can be stored in the sysfs per device config, so that on a reconfigure
> > > > > > request it's easy to check if the backend path matches with the initial
> > > > > > connect backend path.
> > > > > >
> > > > > > Please note, ioctl interface to nbd will not have these changes, as there
> > > > > > won't be any reconfigure.
> > > > >
> > > > > BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> > > > > is added for addressing this issue, what do you think of that generic
> > > > > approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> > > > > for addressing this issue?
> > > > >
> > > > > https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r
> > > >
> > > > If I understand the changes and the background of the fix correctly, I
> > > > think with that fix author is trying to monotonically increase the seq
> > > > number and add it to the disk on every single device map/attach and
> > > > expose it through the sysfs, which will help the userspace processes
> > > > further to correlate events for particular and specific devices that
> > > > reuse the same loop device.
> > > >
> > > > Coming back to my changes:
> > > > I think here with this fix, we are trying to solve a different
> > > > problem. The fix with this patch accepts a cookie or a backend string
> > > > (could be file-path or whatever id userspace choose to provide) from
> > > > userspace at the time of map and stores it in the sysfs
> > > > /sys/block/nbdX/backend path and persists it until unmap is issued on
> > > > the device (meaning that identity stays throughout the life cycle of
> > > > that device, no matter how many detach and attaches happen).
> > >
> > > Your solution needs change from userspace side, so it isn't flexible.
> > >
> > > > If there
> > > > is a detach request in between (not unmap) then on the next attach
> > > > (reconfigure request to reuse the same device) the stored
> > > > cookie/UUID/backend-string will stand as a reference to verify if the
> > > > newly passed backend is matching with the actual backend passed at map
> > > > time to avoid any misconfigurations by accident and to safely proceed
> > > > with attach.
> > >
> > > We can avoid reconfigure if the nbd disk is opened exclusively, such as
> > > mount, please see if the following patch can solve your problem:
> >
> > IMHO, we should almost never allow reconfigure/reattaching a given
> > device with a different backend (except in cases like live migration,
> > which the application should take care of), and not just when nbd disk
> > is opened exclusively.
> >
> > When an attach (reconfigure) is issued, Its application's logic to
> > provide the same matching cookie (or device-string or a uuid) so that
> > kernel can validate it with /sys/block/nbdX/backend and continue
> > safely to attach and reassign the device back.
>
> Your patch looks fine, but only new application can benefit from it, and
> we still need to avoid reconfigure if the disk is opened exclusively for
> old applications. Anyway:

Right applications adopting NBD_ATTR_BACKEND_IDENTIFIER will only get
benefited from these changes.
We could make it strict on the kernel side asking for a cookie but
that will break the existing users.

Here is one good example where we need to allow reconfigure when the
disk is opened exclusively:
Assume your nbd client process (rbd-nbd) is running in a server
container and the application is running in a different
container(which benefits from mount). During server upgrades, we need
to restart the server containers, which means the rbd-nbd process will
also be terminated and later rbd-nbd process need to brought back to
life where it should clam the same device with NBD_CMD_RECONFIGURE,
all this happening while the IO is ongoing on the mount point, in this
cases we need to allow reconfigure even when the disk is opened
exclusively.

Not just the upgrades there are many practical cases where restart of
the server container is done.

>
> Reviewed-by: Ming Lei <ming.lei@redhat.com>

Many thanks for your review.

BRs,
--
Prasanna

>
>
>
> Thanks,
> Ming
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-18  7:52   ` Prasanna Kalever
  2021-05-18  9:24     ` Ming Lei
@ 2021-05-19 14:33     ` Matteo Croce
  2021-05-26 14:13       ` Matteo Croce
  1 sibling, 1 reply; 14+ messages in thread
From: Matteo Croce @ 2021-05-19 14:33 UTC (permalink / raw)
  To: Prasanna Kalever
  Cc: Ming Lei, Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, Jens Axboe, Ilya Dryomov, Xiubo Li,
	Lennart Poettering, Luca Boccassi

On Tue, May 18, 2021 at 9:52 AM Prasanna Kalever <pkalever@redhat.com> wrote:
> > BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> > is added for addressing this issue, what do you think of that generic
> > approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> > for addressing this issue?
> >
> > https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r
>
> If I understand the changes and the background of the fix correctly, I
> think with that fix author is trying to monotonically increase the seq
> number and add it to the disk on every single device map/attach and
> expose it through the sysfs, which will help the userspace processes
> further to correlate events for particular and specific devices that
> reuse the same loop device.
>

Yes, but nothing prevents to use diskseq in nbd, and increase it on reconfigure.
That would allow to detect if the device has been reconfigured.

Regards,
-- 
per aspera ad upstream

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-19 14:33     ` Matteo Croce
@ 2021-05-26 14:13       ` Matteo Croce
  2021-05-27  5:22         ` Prasanna Kalever
  0 siblings, 1 reply; 14+ messages in thread
From: Matteo Croce @ 2021-05-26 14:13 UTC (permalink / raw)
  To: Prasanna Kalever
  Cc: Ming Lei, Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, Jens Axboe, Ilya Dryomov, Xiubo Li,
	Lennart Poettering, Luca Boccassi

On Wed, May 19, 2021 at 4:33 PM Matteo Croce <mcroce@linux.microsoft.com> wrote:
>
> On Tue, May 18, 2021 at 9:52 AM Prasanna Kalever <pkalever@redhat.com> wrote:
> > > BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> > > is added for addressing this issue, what do you think of that generic
> > > approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> > > for addressing this issue?
> > >
> > > https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r
> >
> > If I understand the changes and the background of the fix correctly, I
> > think with that fix author is trying to monotonically increase the seq
> > number and add it to the disk on every single device map/attach and
> > expose it through the sysfs, which will help the userspace processes
> > further to correlate events for particular and specific devices that
> > reuse the same loop device.
> >
>
> Yes, but nothing prevents to use diskseq in nbd, and increase it on reconfigure.
> That would allow to detect if the device has been reconfigured.
>
> Regards,
> --
> per aspera ad upstream

FYI: I just sent a v2 of the diskseq change

https://lore.kernel.org/linux-block/20210520135622.44625-1-mcroce@linux.microsoft.com/

-- 
per aspera ad upstream

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-05-26 14:13       ` Matteo Croce
@ 2021-05-27  5:22         ` Prasanna Kalever
  0 siblings, 0 replies; 14+ messages in thread
From: Prasanna Kalever @ 2021-05-27  5:22 UTC (permalink / raw)
  To: Matteo Croce
  Cc: Ming Lei, Prasanna Kumar Kalever, linux-kernel, linux-block, nbd,
	Josef Bacik, Jens Axboe, Ilya Dryomov, Xiubo Li,
	Lennart Poettering, Luca Boccassi

On Wed, May 26, 2021 at 7:44 PM Matteo Croce <mcroce@linux.microsoft.com> wrote:
>
> On Wed, May 19, 2021 at 4:33 PM Matteo Croce <mcroce@linux.microsoft.com> wrote:
> >
> > On Tue, May 18, 2021 at 9:52 AM Prasanna Kalever <pkalever@redhat.com> wrote:
> > > > BTW, loop has similar issue, and patch of 'block: add a sequence number to disks'
> > > > is added for addressing this issue, what do you think of that generic
> > > > approach wrt. this nbd's issue? such as used the exposed sysfs sequence number
> > > > for addressing this issue?
> > > >
> > > > https://lore.kernel.org/linux-block/YH81n34d2G3C4Re+@gardel-login/#r
> > >
> > > If I understand the changes and the background of the fix correctly, I
> > > think with that fix author is trying to monotonically increase the seq
> > > number and add it to the disk on every single device map/attach and
> > > expose it through the sysfs, which will help the userspace processes
> > > further to correlate events for particular and specific devices that
> > > reuse the same loop device.
> > >
> >
> > Yes, but nothing prevents to use diskseq in nbd, and increase it on reconfigure.
> > That would allow to detect if the device has been reconfigured.
> >
> > Regards,
> > --
> > per aspera ad upstream
>
> FYI: I just sent a v2 of the diskseq change
>
> https://lore.kernel.org/linux-block/20210520135622.44625-1-mcroce@linux.microsoft.com/

Thanks, Matteo, I will take a look.

Just to set the expectation here, I don't have any thoughts on
leverage the diskseq number for nbd as part of this patch. This patch
is trying to solve a different problem which is more severe for us
than helping to identify the reconfigured events.

That all said, once diskseq patches are merged, I will surely open a
new patch with the required changes in nbd, to leverage diskseq
number.

Best Regards,
--
Prasanna

>
> --
> per aspera ad upstream
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-04-29 10:28 [PATCH] nbd: provide a way for userspace processes to identify device backends Prasanna Kumar Kalever
  2021-04-30  2:14 ` Xiubo Li
  2021-05-18  0:29 ` Ming Lei
@ 2021-06-16  8:42 ` Prasanna Kalever
  2021-06-16 12:59 ` Jens Axboe
  3 siblings, 0 replies; 14+ messages in thread
From: Prasanna Kalever @ 2021-06-16  8:42 UTC (permalink / raw)
  To: Josef Bacik, linux-block, nbd, Jens Axboe
  Cc: linux-kernel, Ilya Dryomov, Xiubo Li, Prasanna Kumar Kalever

[Top posting]

Hello Josef, Jens and others nbd experts,

Looks like this patch lost track again. Here is an attempt to remind
you about this patch and request the maintainers for Acks.

Many Thanks!
--
Prasanna

On Thu, Apr 29, 2021 at 3:58 PM Prasanna Kumar Kalever
<prasanna.kalever@redhat.com> wrote:
>
> Problem:
> On reconfigure of device, there is no way to defend if the backend
> storage is matching with the initial backend storage.
>
> Say, if an initial connect request for backend "pool1/image1" got
> mapped to /dev/nbd0 and the userspace process is terminated. A next
> reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> use /dev/nbd0 for a different backend "pool1/image2"
>
> For example, an operation like below could be dangerous:
>
> $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> $ sudo pkill -9 rbd-nbd
> $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
>
> Solution:
> Provide a way for userspace processes to keep some metadata to identify
> between the device and the backend, so that when a reconfigure request is
> made, we can compare and avoid such dangerous operations.
>
> With this solution, as part of the initial connect request, backend
> path can be stored in the sysfs per device config, so that on a reconfigure
> request it's easy to check if the backend path matches with the initial
> connect backend path.
>
> Please note, ioctl interface to nbd will not have these changes, as there
> won't be any reconfigure.
>
> Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
> ---
>  drivers/block/nbd.c              | 60 +++++++++++++++++++++++++++++++-
>  include/uapi/linux/nbd-netlink.h |  1 +
>  2 files changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index 4ff71b579cfc..b5022187ad9c 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -79,6 +79,7 @@ struct link_dead_args {
>  #define NBD_RT_HAS_CONFIG_REF          4
>  #define NBD_RT_BOUND                   5
>  #define NBD_RT_DISCONNECT_ON_CLOSE     6
> +#define NBD_RT_HAS_BACKEND_FILE                7
>
>  #define NBD_DESTROY_ON_DISCONNECT      0
>  #define NBD_DISCONNECT_REQUESTED       1
> @@ -119,6 +120,8 @@ struct nbd_device {
>
>         struct completion *destroy_complete;
>         unsigned long flags;
> +
> +       char *backend;
>  };
>
>  #define NBD_CMD_REQUEUED       1
> @@ -216,6 +219,20 @@ static const struct device_attribute pid_attr = {
>         .show = pid_show,
>  };
>
> +static ssize_t backend_show(struct device *dev,
> +               struct device_attribute *attr, char *buf)
> +{
> +       struct gendisk *disk = dev_to_disk(dev);
> +       struct nbd_device *nbd = (struct nbd_device *)disk->private_data;
> +
> +       return sprintf(buf, "%s\n", nbd->backend ?: "");
> +}
> +
> +static const struct device_attribute backend_attr = {
> +       .attr = { .name = "backend", .mode = 0444},
> +       .show = backend_show,
> +};
> +
>  static void nbd_dev_remove(struct nbd_device *nbd)
>  {
>         struct gendisk *disk = nbd->disk;
> @@ -1215,6 +1232,12 @@ static void nbd_config_put(struct nbd_device *nbd)
>                                        &config->runtime_flags))
>                         device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
>                 nbd->task_recv = NULL;
> +               if (test_and_clear_bit(NBD_RT_HAS_BACKEND_FILE,
> +                                      &config->runtime_flags)) {
> +                       device_remove_file(disk_to_dev(nbd->disk), &backend_attr);
> +                       kfree(nbd->backend);
> +                       nbd->backend = NULL;
> +               }
>                 nbd_clear_sock(nbd);
>                 if (config->num_connections) {
>                         int i;
> @@ -1274,7 +1297,7 @@ static int nbd_start_device(struct nbd_device *nbd)
>
>         error = device_create_file(disk_to_dev(nbd->disk), &pid_attr);
>         if (error) {
> -               dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n");
> +               dev_err(disk_to_dev(nbd->disk), "device_create_file failed for pid!\n");
>                 return error;
>         }
>         set_bit(NBD_RT_HAS_PID_FILE, &config->runtime_flags);
> @@ -1681,6 +1704,7 @@ static int nbd_dev_add(int index)
>                 BLK_MQ_F_BLOCKING;
>         nbd->tag_set.driver_data = nbd;
>         nbd->destroy_complete = NULL;
> +       nbd->backend = NULL;
>
>         err = blk_mq_alloc_tag_set(&nbd->tag_set);
>         if (err)
> @@ -1754,6 +1778,7 @@ static const struct nla_policy nbd_attr_policy[NBD_ATTR_MAX + 1] = {
>         [NBD_ATTR_SOCKETS]              =       { .type = NLA_NESTED},
>         [NBD_ATTR_DEAD_CONN_TIMEOUT]    =       { .type = NLA_U64 },
>         [NBD_ATTR_DEVICE_LIST]          =       { .type = NLA_NESTED},
> +       [NBD_ATTR_BACKEND_IDENTIFIER]   =       { .type = NLA_STRING},
>  };
>
>  static const struct nla_policy nbd_sock_policy[NBD_SOCK_MAX + 1] = {
> @@ -1956,6 +1981,23 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
>                 }
>         }
>         ret = nbd_start_device(nbd);
> +       if (ret)
> +               goto out;
> +       if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
> +               nbd->backend = nla_strdup(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
> +                                         GFP_KERNEL);
> +               if (!nbd->backend) {
> +                       ret = -ENOMEM;
> +                       goto out;
> +               }
> +       }
> +       ret = device_create_file(disk_to_dev(nbd->disk), &backend_attr);
> +       if (ret) {
> +               dev_err(disk_to_dev(nbd->disk),
> +                       "device_create_file failed for backend!\n");
> +               goto out;
> +       }
> +       set_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags);
>  out:
>         mutex_unlock(&nbd->config_lock);
>         if (!ret) {
> @@ -2048,6 +2090,22 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
>                        index);
>                 return -EINVAL;
>         }
> +       if (nbd->backend) {
> +               if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
> +                       if (nla_strcmp(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
> +                                      nbd->backend)) {
> +                               mutex_unlock(&nbd_index_mutex);
> +                               dev_err(nbd_to_dev(nbd),
> +                                       "backend image doesn't match with %s\n",
> +                                       nbd->backend);
> +                               return -EINVAL;
> +                       }
> +               } else {
> +                       mutex_unlock(&nbd_index_mutex);
> +                       dev_err(nbd_to_dev(nbd), "must specify backend\n");
> +                       return -EINVAL;
> +               }
> +       }
>         if (!refcount_inc_not_zero(&nbd->refs)) {
>                 mutex_unlock(&nbd_index_mutex);
>                 printk(KERN_ERR "nbd: device at index %d is going down\n",
> diff --git a/include/uapi/linux/nbd-netlink.h b/include/uapi/linux/nbd-netlink.h
> index c5d0ef7aa7d5..2d0b90964227 100644
> --- a/include/uapi/linux/nbd-netlink.h
> +++ b/include/uapi/linux/nbd-netlink.h
> @@ -35,6 +35,7 @@ enum {
>         NBD_ATTR_SOCKETS,
>         NBD_ATTR_DEAD_CONN_TIMEOUT,
>         NBD_ATTR_DEVICE_LIST,
> +       NBD_ATTR_BACKEND_IDENTIFIER,
>         __NBD_ATTR_MAX,
>  };
>  #define NBD_ATTR_MAX (__NBD_ATTR_MAX - 1)
> --
> 2.30.2
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] nbd: provide a way for userspace processes to identify device backends
  2021-04-29 10:28 [PATCH] nbd: provide a way for userspace processes to identify device backends Prasanna Kumar Kalever
                   ` (2 preceding siblings ...)
  2021-06-16  8:42 ` Prasanna Kalever
@ 2021-06-16 12:59 ` Jens Axboe
  3 siblings, 0 replies; 14+ messages in thread
From: Jens Axboe @ 2021-06-16 12:59 UTC (permalink / raw)
  To: Prasanna Kumar Kalever, linux-kernel
  Cc: linux-block, nbd, josef, idryomov, xiubli

On 4/29/21 4:28 AM, Prasanna Kumar Kalever wrote:
> Problem:
> On reconfigure of device, there is no way to defend if the backend
> storage is matching with the initial backend storage.
> 
> Say, if an initial connect request for backend "pool1/image1" got
> mapped to /dev/nbd0 and the userspace process is terminated. A next
> reconfigure request within NBD_ATTR_DEAD_CONN_TIMEOUT is allowed to
> use /dev/nbd0 for a different backend "pool1/image2"
> 
> For example, an operation like below could be dangerous:
> 
> $ sudo rbd-nbd map --try-netlink rbd-pool/ext4-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="bfc444b4-64b1-418f-8b36-6e0d170cfc04" TYPE="ext4"
> $ sudo pkill -9 rbd-nbd
> $ sudo rbd-nbd attach --try-netlink --device /dev/nbd0 rbd-pool/xfs-image
> /dev/nbd0
> $ sudo blkid /dev/nbd0
> /dev/nbd0: UUID="d29bf343-6570-4069-a9ea-2fa156ced908" TYPE="xfs"
> 
> Solution:
> Provide a way for userspace processes to keep some metadata to identify
> between the device and the backend, so that when a reconfigure request is
> made, we can compare and avoid such dangerous operations.
> 
> With this solution, as part of the initial connect request, backend
> path can be stored in the sysfs per device config, so that on a reconfigure
> request it's easy to check if the backend path matches with the initial
> connect backend path.
> 
> Please note, ioctl interface to nbd will not have these changes, as there
> won't be any reconfigure.

Applied, thanks.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-06-16 12:59 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-29 10:28 [PATCH] nbd: provide a way for userspace processes to identify device backends Prasanna Kumar Kalever
2021-04-30  2:14 ` Xiubo Li
2021-05-17 14:42   ` Prasanna Kalever
2021-05-18  0:29 ` Ming Lei
2021-05-18  7:52   ` Prasanna Kalever
2021-05-18  9:24     ` Ming Lei
2021-05-18  9:49       ` Prasanna Kalever
2021-05-19  7:54         ` Ming Lei
2021-05-19 14:17           ` Prasanna Kalever
2021-05-19 14:33     ` Matteo Croce
2021-05-26 14:13       ` Matteo Croce
2021-05-27  5:22         ` Prasanna Kalever
2021-06-16  8:42 ` Prasanna Kalever
2021-06-16 12:59 ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).