|
| 1 | +nvme-tcp: fix potential memory corruption in nvme_tcp_recv_pdu() |
| 2 | + |
| 3 | +jira LE-2974 |
| 4 | +cve CVE-2025-21927 |
| 5 | +Rebuild_History Non-Buildable kernel-5.14.0-503.40.1.el9_5 |
| 6 | +commit-author Maurizio Lombardi < [email protected]> |
| 7 | +commit ad95bab0cd28ed77c2c0d0b6e76e03e031391064 |
| 8 | +Empty-Commit: Cherry-Pick Conflicts during history rebuild. |
| 9 | +Will be included in final tarball splat. Ref for failed cherry-pick at: |
| 10 | +ciq/ciq_backports/kernel-5.14.0-503.40.1.el9_5/ad95bab0.failed |
| 11 | + |
| 12 | +nvme_tcp_recv_pdu() doesn't check the validity of the header length. |
| 13 | +When header digests are enabled, a target might send a packet with an |
| 14 | +invalid header length (e.g. 255), causing nvme_tcp_verify_hdgst() |
| 15 | +to access memory outside the allocated area and cause memory corruptions |
| 16 | +by overwriting it with the calculated digest. |
| 17 | + |
| 18 | +Fix this by rejecting packets with an unexpected header length. |
| 19 | + |
| 20 | +Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver") |
| 21 | + Signed-off-by: Maurizio Lombardi < [email protected]> |
| 22 | + Reviewed-by: Sagi Grimberg < [email protected]> |
| 23 | + Signed-off-by: Keith Busch < [email protected]> |
| 24 | +(cherry picked from commit ad95bab0cd28ed77c2c0d0b6e76e03e031391064) |
| 25 | + Signed-off-by: Jonathan Maple < [email protected]> |
| 26 | + |
| 27 | +# Conflicts: |
| 28 | +# drivers/nvme/host/tcp.c |
| 29 | +diff --cc drivers/nvme/host/tcp.c |
| 30 | +index 12d3a23bd4c1,23f11527d29d..000000000000 |
| 31 | +--- a/drivers/nvme/host/tcp.c |
| 32 | ++++ b/drivers/nvme/host/tcp.c |
| 33 | +@@@ -205,7 -217,34 +205,38 @@@ static inline int nvme_tcp_queue_id(str |
| 34 | + return queue - queue->ctrl->queues; |
| 35 | + } |
| 36 | + |
| 37 | +++<<<<<<< HEAD |
| 38 | + +static inline bool nvme_tcp_tls(struct nvme_ctrl *ctrl) |
| 39 | +++======= |
| 40 | ++ static inline bool nvme_tcp_recv_pdu_supported(enum nvme_tcp_pdu_type type) |
| 41 | ++ { |
| 42 | ++ switch (type) { |
| 43 | ++ case nvme_tcp_c2h_term: |
| 44 | ++ case nvme_tcp_c2h_data: |
| 45 | ++ case nvme_tcp_r2t: |
| 46 | ++ case nvme_tcp_rsp: |
| 47 | ++ return true; |
| 48 | ++ default: |
| 49 | ++ return false; |
| 50 | ++ } |
| 51 | ++ } |
| 52 | ++ |
| 53 | ++ /* |
| 54 | ++ * Check if the queue is TLS encrypted |
| 55 | ++ */ |
| 56 | ++ static inline bool nvme_tcp_queue_tls(struct nvme_tcp_queue *queue) |
| 57 | ++ { |
| 58 | ++ if (!IS_ENABLED(CONFIG_NVME_TCP_TLS)) |
| 59 | ++ return 0; |
| 60 | ++ |
| 61 | ++ return queue->tls_enabled; |
| 62 | ++ } |
| 63 | ++ |
| 64 | ++ /* |
| 65 | ++ * Check if TLS is configured for the controller. |
| 66 | ++ */ |
| 67 | ++ static inline bool nvme_tcp_tls_configured(struct nvme_ctrl *ctrl) |
| 68 | +++>>>>>>> ad95bab0cd28 (nvme-tcp: fix potential memory corruption in nvme_tcp_recv_pdu()) |
| 69 | + { |
| 70 | + if (!IS_ENABLED(CONFIG_NVME_TCP_TLS)) |
| 71 | + return 0; |
| 72 | +@@@ -758,6 -831,25 +789,28 @@@ static int nvme_tcp_recv_pdu(struct nvm |
| 73 | + return 0; |
| 74 | + |
| 75 | + hdr = queue->pdu; |
| 76 | +++<<<<<<< HEAD |
| 77 | +++======= |
| 78 | ++ if (unlikely(hdr->hlen != sizeof(struct nvme_tcp_rsp_pdu))) { |
| 79 | ++ if (!nvme_tcp_recv_pdu_supported(hdr->type)) |
| 80 | ++ goto unsupported_pdu; |
| 81 | ++ |
| 82 | ++ dev_err(queue->ctrl->ctrl.device, |
| 83 | ++ "pdu type %d has unexpected header length (%d)\n", |
| 84 | ++ hdr->type, hdr->hlen); |
| 85 | ++ return -EPROTO; |
| 86 | ++ } |
| 87 | ++ |
| 88 | ++ if (unlikely(hdr->type == nvme_tcp_c2h_term)) { |
| 89 | ++ /* |
| 90 | ++ * C2HTermReq never includes Header or Data digests. |
| 91 | ++ * Skip the checks. |
| 92 | ++ */ |
| 93 | ++ nvme_tcp_handle_c2h_term(queue, (void *)queue->pdu); |
| 94 | ++ return -EINVAL; |
| 95 | ++ } |
| 96 | ++ |
| 97 | +++>>>>>>> ad95bab0cd28 (nvme-tcp: fix potential memory corruption in nvme_tcp_recv_pdu()) |
| 98 | + if (queue->hdr_digest) { |
| 99 | + ret = nvme_tcp_verify_hdgst(queue, queue->pdu, hdr->hlen); |
| 100 | + if (unlikely(ret)) |
| 101 | +* Unmerged path drivers/nvme/host/tcp.c |
0 commit comments