Commit cf1b2326 authored by Mike Christie's avatar Mike Christie Committed by Jens Axboe
Browse files

nbd: verify socket is supported during setup



nbd requires socket families to support the shutdown method so the nbd
recv workqueue can be woken up from its sock_recvmsg call. If the socket
does not support the callout we will leave recv works running or get hangs
later when the device or module is removed.

This adds a check during socket connection/reconnection to make sure the
socket being passed in supports the needed callout.

Reported-by: default avatar <syzbot+24c12fa8d218ed26011a@syzkaller.appspotmail.com>
Fixes: e9e006f5 ("nbd: fix max number of supported devs")
Tested-by: default avatarRichard W.M. Jones <rjones@redhat.com>
Signed-off-by: default avatarMike Christie <mchristi@redhat.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 962399bb
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -980,6 +980,25 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
	return ret;
}

static struct socket *nbd_get_socket(struct nbd_device *nbd, unsigned long fd,
				     int *err)
{
	struct socket *sock;

	*err = 0;
	sock = sockfd_lookup(fd, err);
	if (!sock)
		return NULL;

	if (sock->ops->shutdown == sock_no_shutdown) {
		dev_err(disk_to_dev(nbd->disk), "Unsupported socket: shutdown callout must be supported.\n");
		*err = -EINVAL;
		return NULL;
	}

	return sock;
}

static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
			  bool netlink)
{
@@ -989,7 +1008,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
	struct nbd_sock *nsock;
	int err;

	sock = sockfd_lookup(arg, &err);
	sock = nbd_get_socket(nbd, arg, &err);
	if (!sock)
		return err;

@@ -1041,7 +1060,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
	int i;
	int err;

	sock = sockfd_lookup(arg, &err);
	sock = nbd_get_socket(nbd, arg, &err);
	if (!sock)
		return err;