mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
nbd: partition nbd_read_stat() into nbd_read_reply() and nbd_handle_reply()
Prepare to fix uaf in nbd_read_stat(), no functional changes. Signed-off-by: Yu Kuai <yukuai3@huawei.com> Reviewed-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Link: https://lore.kernel.org/r/20210916093350.1410403-7-yukuai3@huawei.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
f52c0e0823
commit
3fe1db626a
@ -700,38 +700,45 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* NULL returned = something went wrong, inform userspace */
|
||||
static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
|
||||
static int nbd_read_reply(struct nbd_device *nbd, int index,
|
||||
struct nbd_reply *reply)
|
||||
{
|
||||
struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)};
|
||||
struct iov_iter to;
|
||||
int result;
|
||||
|
||||
reply->magic = 0;
|
||||
iov_iter_kvec(&to, READ, &iov, 1, sizeof(*reply));
|
||||
result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL);
|
||||
if (result < 0) {
|
||||
if (!nbd_disconnected(nbd->config))
|
||||
dev_err(disk_to_dev(nbd->disk),
|
||||
"Receive control failed (result %d)\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (ntohl(reply->magic) != NBD_REPLY_MAGIC) {
|
||||
dev_err(disk_to_dev(nbd->disk), "Wrong magic (0x%lx)\n",
|
||||
(unsigned long)ntohl(reply->magic));
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* NULL returned = something went wrong, inform userspace */
|
||||
static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index,
|
||||
struct nbd_reply *reply)
|
||||
{
|
||||
struct nbd_config *config = nbd->config;
|
||||
int result;
|
||||
struct nbd_reply reply;
|
||||
struct nbd_cmd *cmd;
|
||||
struct request *req = NULL;
|
||||
u64 handle;
|
||||
u16 hwq;
|
||||
u32 tag;
|
||||
struct kvec iov = {.iov_base = &reply, .iov_len = sizeof(reply)};
|
||||
struct iov_iter to;
|
||||
int ret = 0;
|
||||
|
||||
reply.magic = 0;
|
||||
iov_iter_kvec(&to, READ, &iov, 1, sizeof(reply));
|
||||
result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL);
|
||||
if (result < 0) {
|
||||
if (!nbd_disconnected(config))
|
||||
dev_err(disk_to_dev(nbd->disk),
|
||||
"Receive control failed (result %d)\n", result);
|
||||
return ERR_PTR(result);
|
||||
}
|
||||
|
||||
if (ntohl(reply.magic) != NBD_REPLY_MAGIC) {
|
||||
dev_err(disk_to_dev(nbd->disk), "Wrong magic (0x%lx)\n",
|
||||
(unsigned long)ntohl(reply.magic));
|
||||
return ERR_PTR(-EPROTO);
|
||||
}
|
||||
|
||||
memcpy(&handle, reply.handle, sizeof(handle));
|
||||
memcpy(&handle, reply->handle, sizeof(handle));
|
||||
tag = nbd_handle_to_tag(handle);
|
||||
hwq = blk_mq_unique_tag_to_hwq(tag);
|
||||
if (hwq < nbd->tag_set.nr_hw_queues)
|
||||
@ -774,9 +781,9 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (ntohl(reply.error)) {
|
||||
if (ntohl(reply->error)) {
|
||||
dev_err(disk_to_dev(nbd->disk), "Other side returned error (%d)\n",
|
||||
ntohl(reply.error));
|
||||
ntohl(reply->error));
|
||||
cmd->status = BLK_STS_IOERR;
|
||||
goto out;
|
||||
}
|
||||
@ -785,6 +792,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
|
||||
if (rq_data_dir(req) != WRITE) {
|
||||
struct req_iterator iter;
|
||||
struct bio_vec bvec;
|
||||
struct iov_iter to;
|
||||
|
||||
rq_for_each_segment(bvec, req, iter) {
|
||||
iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len);
|
||||
@ -798,7 +806,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
|
||||
* and let the timeout stuff handle resubmitting
|
||||
* this request onto another connection.
|
||||
*/
|
||||
if (nbd_disconnected(config)) {
|
||||
if (nbd_disconnected(nbd->config)) {
|
||||
cmd->status = BLK_STS_IOERR;
|
||||
goto out;
|
||||
}
|
||||
@ -822,24 +830,30 @@ static void recv_work(struct work_struct *work)
|
||||
work);
|
||||
struct nbd_device *nbd = args->nbd;
|
||||
struct nbd_config *config = nbd->config;
|
||||
struct nbd_sock *nsock;
|
||||
struct nbd_cmd *cmd;
|
||||
struct request *rq;
|
||||
|
||||
while (1) {
|
||||
cmd = nbd_read_stat(nbd, args->index);
|
||||
if (IS_ERR(cmd)) {
|
||||
struct nbd_sock *nsock = config->socks[args->index];
|
||||
struct nbd_reply reply;
|
||||
|
||||
mutex_lock(&nsock->tx_lock);
|
||||
nbd_mark_nsock_dead(nbd, nsock, 1);
|
||||
mutex_unlock(&nsock->tx_lock);
|
||||
if (nbd_read_reply(nbd, args->index, &reply))
|
||||
break;
|
||||
|
||||
cmd = nbd_handle_reply(nbd, args->index, &reply);
|
||||
if (IS_ERR(cmd))
|
||||
break;
|
||||
}
|
||||
|
||||
rq = blk_mq_rq_from_pdu(cmd);
|
||||
if (likely(!blk_should_fake_timeout(rq->q)))
|
||||
blk_mq_complete_request(rq);
|
||||
}
|
||||
|
||||
nsock = config->socks[args->index];
|
||||
mutex_lock(&nsock->tx_lock);
|
||||
nbd_mark_nsock_dead(nbd, nsock, 1);
|
||||
mutex_unlock(&nsock->tx_lock);
|
||||
|
||||
nbd_config_put(nbd);
|
||||
atomic_dec(&config->recv_threads);
|
||||
wake_up(&config->recv_wq);
|
||||
|
Loading…
Reference in New Issue
Block a user