Pull block fixes from Jens Axboe: "A fix for a regression with sed-opal and saved keys, and outside of that an NVMe pull request fixing a few minor issues on that front" * tag 'block-6.6-2023-10-20' of git://git.kernel.dk/linux: nvme-pci: add BOGUS_NID for Intel 0a54 device nvmet-auth: complete a request only after freeing the dhchap pointers nvme: sanitize metadata bounce buffer for reads block: Fix regression in sed-opal for a saved key. nvme-auth: use chap->s2 to indicate bidirectional authentication nvmet-tcp: Fix a possible UAF in queue intialization setup nvme-rdma: do not try to stop unallocated queues
Unified · Split
| @@ -2888,12 +2888,11 @@ static int opal_lock_unlock(struct opal_dev *dev, · 2887 unmodified lines | ||
| 2888 | 2888 | if (lk_unlk->session.who > OPAL_USER9) |
| 2889 | 2889 | return -EINVAL; |
| 2890 | 2890 | |
| 2891 | − ret = opal_get_key(dev, &lk_unlk->session.opal_key); | |
| 2892 | − if (ret) | |
| 2893 | − return ret; | |
| 2894 | 2891 | mutex_lock(&dev->dev_lock); |
| 2895 | 2892 | opal_lock_check_for_saved_key(dev, lk_unlk); |
| 2896 | − ret = __opal_lock_unlock(dev, lk_unlk); | |
| 2893 | + ret = opal_get_key(dev, &lk_unlk->session.opal_key); | |
| 2894 | + if (!ret) | |
| 2895 | + ret = __opal_lock_unlock(dev, lk_unlk); | |
| 2897 | 2896 | mutex_unlock(&dev->dev_lock); |
| 2898 | 2897 | |
| 2899 | 2898 | return ret; |
| @@ -341,7 +341,7 @@ static int nvme_auth_process_dhchap_success1(struct nvme_ctrl *ctrl, · 340 unmodified lines | ||
| 341 | 341 | struct nvmf_auth_dhchap_success1_data *data = chap->buf; |
| 342 | 342 | size_t size = sizeof(*data); |
| 343 | 343 | |
| 344 | − if (chap->ctrl_key) | |
| 344 | + if (chap->s2) | |
| 345 | 345 | size += chap->hash_len; |
| 346 | 346 | |
| 347 | 347 | if (size > CHAP_BUF_SIZE) { |
| @@ -825,7 +825,7 @@ static void nvme_queue_auth_work(struct work_struct *work) · 477 unmodified lines | ||
| 825 | 825 | goto fail2; |
| 826 | 826 | } |
| 827 | 827 | |
| 828 | − if (chap->ctrl_key) { | |
| 828 | + if (chap->s2) { | |
| 829 | 829 | /* DH-HMAC-CHAP Step 5: send success2 */ |
| 830 | 830 | dev_dbg(ctrl->device, "%s: qid %d send success2\n", |
| 831 | 831 | __func__, chap->qid); |
| @@ -108,9 +108,13 @@ static void *nvme_add_user_metadata(struct request *req, void __user *ubuf, · 107 unmodified lines | ||
| 108 | 108 | if (!buf) |
| 109 | 109 | goto out; |
| 110 | 110 | |
| 111 | − ret = -EFAULT; | |
| 112 | − if ((req_op(req) == REQ_OP_DRV_OUT) && copy_from_user(buf, ubuf, len)) | |
| 113 | − goto out_free_meta; | |
| 111 | + if (req_op(req) == REQ_OP_DRV_OUT) { | |
| 112 | + ret = -EFAULT; | |
| 113 | + if (copy_from_user(buf, ubuf, len)) | |
| 114 | + goto out_free_meta; | |
| 115 | + } else { | |
| 116 | + memset(buf, 0, len); | |
| 117 | + } | |
| 114 | 118 | |
| 115 | 119 | bip = bio_integrity_alloc(bio, GFP_KERNEL, 1); |
| 116 | 120 | if (IS_ERR(bip)) { |
| @@ -3329,7 +3329,8 @@ static const struct pci_device_id nvme_id_table[] = { · 3328 unmodified lines | ||
| 3329 | 3329 | { PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */ |
| 3330 | 3330 | .driver_data = NVME_QUIRK_STRIPE_SIZE | |
| 3331 | 3331 | NVME_QUIRK_DEALLOCATE_ZEROES | |
| 3332 | − NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | |
| 3332 | + NVME_QUIRK_IGNORE_DEV_SUBNQN | | |
| 3333 | + NVME_QUIRK_BOGUS_NID, }, | |
| 3333 | 3334 | { PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */ |
| 3334 | 3335 | .driver_data = NVME_QUIRK_STRIPE_SIZE | |
| 3335 | 3336 | NVME_QUIRK_DEALLOCATE_ZEROES, }, |
| @@ -638,6 +638,9 @@ static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) · 637 unmodified lines | ||
| 638 | 638 | |
| 639 | 639 | static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) |
| 640 | 640 | { |
| 641 | + if (!test_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags)) | |
| 642 | + return; | |
| 643 | + | |
| 641 | 644 | mutex_lock(&queue->queue_lock); |
| 642 | 645 | if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) |
| 643 | 646 | __nvme_rdma_stop_queue(queue); |
| @@ -333,19 +333,21 @@ done: · 332 unmodified lines | ||
| 333 | 333 | __func__, ctrl->cntlid, req->sq->qid, |
| 334 | 334 | status, req->error_loc); |
| 335 | 335 | req->cqe->result.u64 = 0; |
| 336 | − nvmet_req_complete(req, status); | |
| 337 | 336 | if (req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2 && |
| 338 | 337 | req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) { |
| 339 | 338 | unsigned long auth_expire_secs = ctrl->kato ? ctrl->kato : 120; |
| 340 | 339 | |
| 341 | 340 | mod_delayed_work(system_wq, &req->sq->auth_expired_work, |
| 342 | 341 | auth_expire_secs * HZ); |
| 343 | − return; | |
| 342 | + goto complete; | |
| 344 | 343 | } |
| 345 | 344 | /* Final states, clear up variables */ |
| 346 | 345 | nvmet_auth_sq_free(req->sq); |
| 347 | 346 | if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) |
| 348 | 347 | nvmet_ctrl_fatal_error(ctrl); |
| 348 | + | |
| 349 | +complete: | |
| 350 | + nvmet_req_complete(req, status); | |
| 349 | 351 | } |
| 350 | 352 | |
| 351 | 353 | static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al) |
| @@ -514,11 +516,12 @@ void nvmet_execute_auth_receive(struct nvmet_req *req) · 162 unmodified lines | ||
| 514 | 516 | kfree(d); |
| 515 | 517 | done: |
| 516 | 518 | req->cqe->result.u64 = 0; |
| 517 | − nvmet_req_complete(req, status); | |
| 519 | + | |
| 518 | 520 | if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2) |
| 519 | 521 | nvmet_auth_sq_free(req->sq); |
| 520 | 522 | else if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE1) { |
| 521 | 523 | nvmet_auth_sq_free(req->sq); |
| 522 | 524 | nvmet_ctrl_fatal_error(ctrl); |
| 523 | 525 | } |
| 526 | + nvmet_req_complete(req, status); | |
| 524 | 527 | } |
| @@ -372,6 +372,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue) · 371 unmodified lines | ||
| 372 | 372 | |
| 373 | 373 | static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status) |
| 374 | 374 | { |
| 375 | + queue->rcv_state = NVMET_TCP_RECV_ERR; | |
| 375 | 376 | if (status == -EPIPE || status == -ECONNRESET) |
| 376 | 377 | kernel_sock_shutdown(queue->sock, SHUT_RDWR); |
| 377 | 378 | else |
| @@ -910,15 +911,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) · 532 unmodified lines | ||
| 910 | 911 | iov.iov_len = sizeof(*icresp); |
| 911 | 912 | ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len); |
| 912 | 913 | if (ret < 0) |
| 913 | − goto free_crypto; | |
| 914 | + return ret; /* queue removal will cleanup */ | |
| 914 | 915 | |
| 915 | 916 | queue->state = NVMET_TCP_Q_LIVE; |
| 916 | 917 | nvmet_prepare_receive_pdu(queue); |
| 917 | 918 | return 0; |
| 918 | −free_crypto: | |
| 919 | − if (queue->hdr_digest || queue->data_digest) | |
| 920 | − nvmet_tcp_free_crypto(queue); | |
| 921 | − return ret; | |
| 922 | 919 | } |
| 923 | 920 | |
| 924 | 921 | static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue, |