7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Yehyeong Lee [ Upstream commit f9e43d924bc74feeb56197de82b2845de2a4b85a ] nvme_auth_process_dhchap_success1() returns success as soon as the controller clears the rvalid flag in its DH-HMAC-CHAP success1 message, without looking at whether the host had asked the controller to authenticate. A host configured with a controller secret sends a challenge in its reply, computes the expected controller response, and sets chap->bi_directional; if the controller then answers with rvalid = 0 the response is never compared, the host still sends success2, and the queue is marked as authenticated. A malicious or man-in-the-middle controller therefore only has to clear one flag to turn the configured bidirectional authentication into a one-way one, without holding any secret of its own. The target side already treats the mirror image of this as fatal: when the host supplied a challenge but no controller key is configured, nvmet_auth_success1() fails the authentication rather than answering with rvalid = 0. Refuse the connection if the controller returns no response although bidirectional authentication was requested. chap->bi_directional is the right condition rather than ctrl->ctrl_key, because secure concatenation sends a challenge only to derive the PSK and deliberately clears bi_directional; a one-way setup without a controller secret keeps returning success as before. Fixes: f50fff73d620 ("nvme: implement In-Band authentication") Cc: stable@vger.kernel.org Reviewed-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Signed-off-by: Yehyeong Lee Signed-off-by: Keith Busch Signed-off-by: Sasha Levin --- drivers/nvme/host/auth.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c index e55920642f2c1..cbb38935fa227 100644 --- a/drivers/nvme/host/auth.c +++ b/drivers/nvme/host/auth.c @@ -358,8 +358,21 @@ static int nvme_auth_process_dhchap_success1(struct nvme_ctrl *ctrl, nvme_auth_hmac_name(chap->hash_id), nvme_auth_dhgroup_name(chap->dhgroup_id)); - if (!data->rvalid) + if (!data->rvalid) { + /* + * The controller did not return a response. If we asked it to + * authenticate itself the session must not be used, otherwise + * mutual authentication would silently degrade to one-way. + */ + if (chap->bi_directional) { + dev_warn(ctrl->device, + "qid %d: controller did not authenticate\n", + chap->qid); + chap->status = NVME_AUTH_DHCHAP_FAILURE_FAILED; + return -ECONNREFUSED; + } return 0; + } /* Validate controller response */ if (crypto_memneq(chap->response, data->rval, data->hl)) { -- 2.53.0