From 9e0897f67f98606dbdc7e5c056f39714e5903365 Mon Sep 17 00:00:00 2001 From: Kernel Build Daemon Date: Mar 09 2023 06:24:54 +0000 Subject: Merge branch 'SLE15-SP4' into SLE15-SP4-AZURE --- diff --git a/blacklist.conf b/blacklist.conf index 5881da5..98dffe7 100644 --- a/blacklist.conf +++ b/blacklist.conf @@ -729,3 +729,5 @@ d19a7af73b5ecaac8168712d18be72b9db166768 # fix for bug we don't have 64158668ac8b31626a8ce48db4cad08496eb8340 # have fix in different form c265de257f558a05c1859ee9e3fed04883b9ec0e # have fix in different form da48f267f90d9dc9f930fd9a67753643657b404f # not obviously safe, not really necessary +9fd5a04d8efcbf511286dd36c46fd70a645b167d # cosmetic fix that breaks kABI +3b90954419d4c05651de9cce6d7632bcf6977678 # false positive from stable. Bug introduced in e9e7870f90e3587b712e05db2ded947a3f617119 diff --git a/patches.suse/drm-virtio-Fix-NULL-vs-IS_ERR-checking-in-virtio_gpu.patch b/patches.suse/drm-virtio-Fix-NULL-vs-IS_ERR-checking-in-virtio_gpu.patch new file mode 100644 index 0000000..9c9f999 --- /dev/null +++ b/patches.suse/drm-virtio-Fix-NULL-vs-IS_ERR-checking-in-virtio_gpu.patch @@ -0,0 +1,36 @@ +From c24968734abfed81c8f93dc5f44a7b7a9aecadfa Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Thu, 2 Jun 2022 14:42:22 +0400 +Subject: drm/virtio: Fix NULL vs IS_ERR checking in + virtio_gpu_object_shmem_init +Git-commit: c24968734abfed81c8f93dc5f44a7b7a9aecadfa +Patch-mainline: v6.0-rc1 +References: bsc#1208776 CVE-2023-22998 + +Since drm_prime_pages_to_sg() function return error pointers. +The drm_gem_shmem_get_sg_table() function returns error pointers too. +Using IS_ERR() to check the return value to fix this. + +Fixes: 2f2aa13724d5 ("drm/virtio: move virtio_gpu_mem_entry initialization to new function") +Signed-off-by: Miaoqian Lin +Link: http://patchwork.freedesktop.org/patch/msgid/20220602104223.54527-1-linmq006@gmail.com +Signed-off-by: Gerd Hoffmann +Acked-by: Patrik Jakobsson +--- + drivers/gpu/drm/virtio/virtgpu_object.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -168,9 +168,9 @@ + * since virtio_gpu doesn't support dma-buf import from other devices. + */ + shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base); +- if (!shmem->pages) { ++ if (IS_ERR(shmem->pages)) { + drm_gem_shmem_unpin(&bo->base.base); +- return -EINVAL; ++ return PTR_ERR(shmem->pages); + } + + if (use_dma_api) { diff --git a/patches.suse/malidp-Fix-NULL-vs-IS_ERR-checking.patch b/patches.suse/malidp-Fix-NULL-vs-IS_ERR-checking.patch new file mode 100644 index 0000000..ba517a2 --- /dev/null +++ b/patches.suse/malidp-Fix-NULL-vs-IS_ERR-checking.patch @@ -0,0 +1,35 @@ +From 15342f930ebebcfe36f2415049736a77d7d2e045 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 13 Dec 2021 07:21:15 +0000 +Subject: malidp: Fix NULL vs IS_ERR() checking +Git-commit: 15342f930ebebcfe36f2415049736a77d7d2e045 +Patch-mainline: v5.19-rc1 +References: bsc#1208843 CVE-2023-23004 + +The get_sg_table() function does not return NULL. +It returns error pointers. + +Signed-off-by: Miaoqian Lin +Signed-off-by: Liviu Dudau +Link: https://lore.kernel.org/dri-devel/20211213072115.18098-1-linmq006@gmail.com/ +Acked-by: Patrik Jakobsson +--- + drivers/gpu/drm/arm/malidp_planes.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c +index 81d9f5004025..338cec4a3fff 100644 +--- a/drivers/gpu/drm/arm/malidp_planes.c ++++ b/drivers/gpu/drm/arm/malidp_planes.c +@@ -344,7 +344,7 @@ static bool malidp_check_pages_threshold(struct malidp_plane_state *ms, + else + sgt = obj->funcs->get_sg_table(obj); + +- if (!sgt) ++ if (IS_ERR(sgt)) + return false; + + sgl = sgt->sgl; +-- +2.39.2 + diff --git a/patches.suse/nvme-auth-check-chap-ctrl_key-once-constructed.patch b/patches.suse/nvme-auth-check-chap-ctrl_key-once-constructed.patch new file mode 100644 index 0000000..f2b33a9 --- /dev/null +++ b/patches.suse/nvme-auth-check-chap-ctrl_key-once-constructed.patch @@ -0,0 +1,40 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:18 +0200 +Subject: nvme-auth: check chap ctrl_key once constructed +Patch-mainline: v6.2-rc1 +Git-commit: 546dea18c99928bb81392de63092da0e25d07b10 +References: bsc#1202633 + +ctrl ctrl_key member may be overwritten from a sysfs context driven +by the user. Once a queue local copy was created, use that instead +to minimize checks on a shared resource. + +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -333,7 +333,7 @@ static int nvme_auth_process_dhchap_succ + struct nvmf_auth_dhchap_success1_data *data = chap->buf; + size_t size = sizeof(*data); + +- if (ctrl->ctrl_key) ++ if (chap->ctrl_key) + size += chap->hash_len; + + if (size > CHAP_BUF_SIZE) { +@@ -811,7 +811,7 @@ static void nvme_queue_auth_work(struct + goto fail2; + } + +- if (ctrl->ctrl_key) { ++ if (chap->ctrl_key) { + /* DH-HMAC-CHAP Step 5: send success2 */ + dev_dbg(ctrl->device, "%s: qid %d send success2\n", + __func__, chap->qid); diff --git a/patches.suse/nvme-auth-clear-sensitive-info-right-after-authentic.patch b/patches.suse/nvme-auth-clear-sensitive-info-right-after-authentic.patch new file mode 100644 index 0000000..5ee6804 --- /dev/null +++ b/patches.suse/nvme-auth-clear-sensitive-info-right-after-authentic.patch @@ -0,0 +1,30 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:15 +0200 +Subject: nvme-auth: clear sensitive info right after authentication completes +Patch-mainline: v6.2-rc1 +Git-commit: 8d1c1904e94757b78c28fbbef9285e4101d86ee9 +References: bsc#1202633 + +We don't want to keep authentication sensitive info in memory for unlimited +amount of time. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -912,6 +912,8 @@ int nvme_auth_wait(struct nvme_ctrl *ctr + mutex_unlock(&ctrl->dhchap_auth_mutex); + flush_work(&chap->auth_work); + ret = chap->error; ++ /* clear sensitive info */ ++ nvme_auth_reset_dhchap(chap); + return ret; + } + mutex_unlock(&ctrl->dhchap_auth_mutex); diff --git a/patches.suse/nvme-auth-convert-dhchap_auth_list-to-an-array.patch b/patches.suse/nvme-auth-convert-dhchap_auth_list-to-an-array.patch new file mode 100644 index 0000000..c6d5496 --- /dev/null +++ b/patches.suse/nvme-auth-convert-dhchap_auth_list-to-an-array.patch @@ -0,0 +1,286 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:20 +0200 +Subject: nvme-auth: convert dhchap_auth_list to an array +Patch-mainline: v6.2-rc1 +Git-commit: aa36d711e945e65fa87410927800f01878a8faed +References: bsc#1202633 + +We know exactly how many dhchap contexts we will need, there is no need +to hold a list that we need to protect with a mutex. Convert to +a dynamically allocated array. And dhchap_context access state is +maintained by the chap itself. + +Make dhchap_auth_mutex protect only the ctrl host_key and ctrl_key +in a fine-grained lock such that there is no long lasting acquisition +of the lock and no need to take/release this lock when flushing +authentication works. + +Signed-off-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 118 +++++++++++++++++++++------------------ + drivers/nvme/host/core.c | 4 ++ + drivers/nvme/host/nvme.h | 2 +- + 3 files changed, 69 insertions(+), 55 deletions(-) + +diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c +index 781a6003109d..24726683d4bc 100644 +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -50,6 +50,12 @@ struct nvme_dhchap_queue_context { + #define nvme_auth_queue_from_qid(ctrl, qid) \ + (qid == 0) ? (ctrl)->fabrics_q : (ctrl)->connect_q + ++static inline int ctrl_max_dhchaps(struct nvme_ctrl *ctrl) ++{ ++ return ctrl->opts->nr_io_queues + ctrl->opts->nr_write_queues + ++ ctrl->opts->nr_poll_queues + 1; ++} ++ + static int nvme_auth_submit(struct nvme_ctrl *ctrl, int qid, + void *data, size_t data_len, bool auth_send) + { +@@ -510,6 +516,7 @@ static int nvme_auth_dhchap_setup_ctrl_response(struct nvme_ctrl *ctrl, + ret = PTR_ERR(ctrl_response); + return ret; + } ++ + ret = crypto_shash_setkey(chap->shash_tfm, + ctrl_response, ctrl->ctrl_key->len); + if (ret) { +@@ -668,7 +675,6 @@ static void nvme_auth_free_dhchap(struct nvme_dhchap_queue_context *chap) + crypto_free_shash(chap->shash_tfm); + if (chap->dh_tfm) + crypto_free_kpp(chap->dh_tfm); +- kfree(chap); + } + + static void nvme_queue_auth_work(struct work_struct *work) +@@ -748,11 +754,14 @@ static void nvme_queue_auth_work(struct work_struct *work) + + dev_dbg(ctrl->device, "%s: qid %d host response\n", + __func__, chap->qid); ++ mutex_lock(&ctrl->dhchap_auth_mutex); + ret = nvme_auth_dhchap_setup_host_response(ctrl, chap); + if (ret) { ++ mutex_unlock(&ctrl->dhchap_auth_mutex); + chap->error = ret; + goto fail2; + } ++ mutex_unlock(&ctrl->dhchap_auth_mutex); + + /* DH-HMAC-CHAP Step 3: send reply */ + dev_dbg(ctrl->device, "%s: qid %d send reply\n", +@@ -793,16 +802,19 @@ static void nvme_queue_auth_work(struct work_struct *work) + return; + } + ++ mutex_lock(&ctrl->dhchap_auth_mutex); + if (ctrl->ctrl_key) { + dev_dbg(ctrl->device, + "%s: qid %d controller response\n", + __func__, chap->qid); + ret = nvme_auth_dhchap_setup_ctrl_response(ctrl, chap); + if (ret) { ++ mutex_unlock(&ctrl->dhchap_auth_mutex); + chap->error = ret; + goto fail2; + } + } ++ mutex_unlock(&ctrl->dhchap_auth_mutex); + + ret = nvme_auth_process_dhchap_success1(ctrl, chap); + if (ret) { +@@ -852,29 +864,8 @@ int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid) + return -ENOKEY; + } + +- mutex_lock(&ctrl->dhchap_auth_mutex); +- /* Check if the context is already queued */ +- list_for_each_entry(chap, &ctrl->dhchap_auth_list, entry) { +- WARN_ON(!chap->buf); +- if (chap->qid == qid) { +- dev_dbg(ctrl->device, "qid %d: re-using context\n", qid); +- mutex_unlock(&ctrl->dhchap_auth_mutex); +- flush_work(&chap->auth_work); +- nvme_auth_reset_dhchap(chap); +- queue_work(nvme_wq, &chap->auth_work); +- return 0; +- } +- } +- chap = kzalloc(sizeof(*chap), GFP_KERNEL); +- if (!chap) { +- mutex_unlock(&ctrl->dhchap_auth_mutex); +- return -ENOMEM; +- } +- chap->qid = qid; +- chap->ctrl = ctrl; +- INIT_WORK(&chap->auth_work, nvme_queue_auth_work); +- list_add(&chap->entry, &ctrl->dhchap_auth_list); +- mutex_unlock(&ctrl->dhchap_auth_mutex); ++ chap = &ctrl->dhchap_ctxs[qid]; ++ cancel_work_sync(&chap->auth_work); + queue_work(nvme_wq, &chap->auth_work); + return 0; + } +@@ -885,19 +876,12 @@ int nvme_auth_wait(struct nvme_ctrl *ctrl, int qid) + struct nvme_dhchap_queue_context *chap; + int ret; + +- mutex_lock(&ctrl->dhchap_auth_mutex); +- list_for_each_entry(chap, &ctrl->dhchap_auth_list, entry) { +- if (chap->qid != qid) +- continue; +- mutex_unlock(&ctrl->dhchap_auth_mutex); +- flush_work(&chap->auth_work); +- ret = chap->error; +- /* clear sensitive info */ +- nvme_auth_reset_dhchap(chap); +- return ret; +- } +- mutex_unlock(&ctrl->dhchap_auth_mutex); +- return -ENXIO; ++ chap = &ctrl->dhchap_ctxs[qid]; ++ flush_work(&chap->auth_work); ++ ret = chap->error; ++ /* clear sensitive info */ ++ nvme_auth_reset_dhchap(chap); ++ return ret; + } + EXPORT_SYMBOL_GPL(nvme_auth_wait); + +@@ -946,11 +930,11 @@ static void nvme_ctrl_auth_work(struct work_struct *work) + + int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) + { +- int ret; ++ struct nvme_dhchap_queue_context *chap; ++ int i, ret; + +- INIT_LIST_HEAD(&ctrl->dhchap_auth_list); +- INIT_WORK(&ctrl->dhchap_auth_work, nvme_ctrl_auth_work); + mutex_init(&ctrl->dhchap_auth_mutex); ++ INIT_WORK(&ctrl->dhchap_auth_work, nvme_ctrl_auth_work); + if (!ctrl->opts) + return 0; + ret = nvme_auth_generate_key(ctrl->opts->dhchap_secret, +@@ -959,37 +943,63 @@ int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) + return ret; + ret = nvme_auth_generate_key(ctrl->opts->dhchap_ctrl_secret, + &ctrl->ctrl_key); +- if (ret) { +- nvme_auth_free_key(ctrl->host_key); +- ctrl->host_key = NULL; ++ if (ret) ++ goto err_free_dhchap_secret; ++ ++ if (!ctrl->opts->dhchap_secret && !ctrl->opts->dhchap_ctrl_secret) ++ return ret; ++ ++ ctrl->dhchap_ctxs = kvcalloc(ctrl_max_dhchaps(ctrl), ++ sizeof(*chap), GFP_KERNEL); ++ if (!ctrl->dhchap_ctxs) { ++ ret = -ENOMEM; ++ goto err_free_dhchap_ctrl_secret; + } ++ ++ for (i = 0; i < ctrl_max_dhchaps(ctrl); i++) { ++ chap = &ctrl->dhchap_ctxs[i]; ++ chap->qid = i; ++ chap->ctrl = ctrl; ++ INIT_WORK(&chap->auth_work, nvme_queue_auth_work); ++ } ++ ++ return 0; ++err_free_dhchap_ctrl_secret: ++ nvme_auth_free_key(ctrl->ctrl_key); ++ ctrl->ctrl_key = NULL; ++err_free_dhchap_secret: ++ nvme_auth_free_key(ctrl->host_key); ++ ctrl->host_key = NULL; + return ret; + } + EXPORT_SYMBOL_GPL(nvme_auth_init_ctrl); + + void nvme_auth_stop(struct nvme_ctrl *ctrl) + { +- struct nvme_dhchap_queue_context *chap = NULL, *tmp; ++ struct nvme_dhchap_queue_context *chap; ++ int i; + + cancel_work_sync(&ctrl->dhchap_auth_work); +- mutex_lock(&ctrl->dhchap_auth_mutex); +- list_for_each_entry_safe(chap, tmp, &ctrl->dhchap_auth_list, entry) ++ for (i = 0; i < ctrl_max_dhchaps(ctrl); i++) { ++ chap = &ctrl->dhchap_ctxs[i]; + cancel_work_sync(&chap->auth_work); +- mutex_unlock(&ctrl->dhchap_auth_mutex); ++ } + } + EXPORT_SYMBOL_GPL(nvme_auth_stop); + + void nvme_auth_free(struct nvme_ctrl *ctrl) + { +- struct nvme_dhchap_queue_context *chap = NULL, *tmp; ++ struct nvme_dhchap_queue_context *chap; ++ int i; + +- mutex_lock(&ctrl->dhchap_auth_mutex); +- list_for_each_entry_safe(chap, tmp, &ctrl->dhchap_auth_list, entry) { +- list_del_init(&chap->entry); +- flush_work(&chap->auth_work); +- nvme_auth_free_dhchap(chap); ++ if (ctrl->dhchap_ctxs) { ++ for (i = 0; i < ctrl_max_dhchaps(ctrl); i++) { ++ chap = &ctrl->dhchap_ctxs[i]; ++ flush_work(&chap->auth_work); ++ nvme_auth_free_dhchap(chap); ++ } ++ kfree(ctrl->dhchap_ctxs); + } +- mutex_unlock(&ctrl->dhchap_auth_mutex); + if (ctrl->host_key) { + nvme_auth_free_key(ctrl->host_key); + ctrl->host_key = NULL; +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 2944d9b565a2..bc0eede419cb 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -3785,7 +3785,9 @@ static ssize_t nvme_ctrl_dhchap_secret_store(struct device *dev, + kfree(opts->dhchap_secret); + opts->dhchap_secret = dhchap_secret; + host_key = ctrl->host_key; ++ mutex_lock(&ctrl->dhchap_auth_mutex); + ctrl->host_key = key; ++ mutex_unlock(&ctrl->dhchap_auth_mutex); + nvme_auth_free_key(host_key); + } + /* Start re-authentication */ +@@ -3837,7 +3839,9 @@ static ssize_t nvme_ctrl_dhchap_ctrl_secret_store(struct device *dev, + kfree(opts->dhchap_ctrl_secret); + opts->dhchap_ctrl_secret = dhchap_secret; + ctrl_key = ctrl->ctrl_key; ++ mutex_lock(&ctrl->dhchap_auth_mutex); + ctrl->ctrl_key = key; ++ mutex_unlock(&ctrl->dhchap_auth_mutex); + nvme_auth_free_key(ctrl_key); + } + /* Start re-authentication */ +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index e431ec348d52..ef23c6c6e2a3 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -337,8 +337,8 @@ struct nvme_ctrl { + + #ifdef CONFIG_NVME_AUTH + struct work_struct dhchap_auth_work; +- struct list_head dhchap_auth_list; + struct mutex dhchap_auth_mutex; ++ struct nvme_dhchap_queue_context *dhchap_ctxs; + struct nvme_dhchap_key *host_key; + struct nvme_dhchap_key *ctrl_key; + u16 transaction; +-- +2.35.3 + diff --git a/patches.suse/nvme-auth-don-t-ignore-key-generation-failures-when-.patch b/patches.suse/nvme-auth-don-t-ignore-key-generation-failures-when-.patch new file mode 100644 index 0000000..5422393 --- /dev/null +++ b/patches.suse/nvme-auth-don-t-ignore-key-generation-failures-when-.patch @@ -0,0 +1,93 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:10 +0200 +Subject: nvme-auth: don't ignore key generation failures when initializing + ctrl keys +Patch-mainline: v6.2-rc1 +Git-commit: 193a8c7e5f1a8481841636cec9c185543ec5c759 +References: bsc#1202633 + +nvme_auth_generate_key can fail, don't ignore it upon initialization. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 19 +++++++++++++++---- + drivers/nvme/host/core.c | 6 +++++- + drivers/nvme/host/nvme.h | 7 +++++-- + 3 files changed, 25 insertions(+), 7 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -972,15 +972,26 @@ static void nvme_ctrl_auth_work(struct w + */ + } + +-void nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) ++int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) + { ++ int ret; ++ + INIT_LIST_HEAD(&ctrl->dhchap_auth_list); + INIT_WORK(&ctrl->dhchap_auth_work, nvme_ctrl_auth_work); + mutex_init(&ctrl->dhchap_auth_mutex); + if (!ctrl->opts) +- return; +- nvme_auth_generate_key(ctrl->opts->dhchap_secret, &ctrl->host_key); +- nvme_auth_generate_key(ctrl->opts->dhchap_ctrl_secret, &ctrl->ctrl_key); ++ return 0; ++ ret = nvme_auth_generate_key(ctrl->opts->dhchap_secret, ++ &ctrl->host_key); ++ if (ret) ++ return ret; ++ ret = nvme_auth_generate_key(ctrl->opts->dhchap_ctrl_secret, ++ &ctrl->ctrl_key); ++ if (ret) { ++ nvme_auth_free_key(ctrl->host_key); ++ ctrl->host_key = NULL; ++ } ++ return ret; + } + EXPORT_SYMBOL_GPL(nvme_auth_init_ctrl); + +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -4679,9 +4679,13 @@ int nvme_init_ctrl(struct nvme_ctrl *ctr + + nvme_fault_inject_init(&ctrl->fault_inject, dev_name(ctrl->device)); + nvme_mpath_init_ctrl(ctrl); +- nvme_auth_init_ctrl(ctrl); ++ ret = nvme_auth_init_ctrl(ctrl); ++ if (ret) ++ goto out_free_cdev; + + return 0; ++out_free_cdev: ++ cdev_device_del(&ctrl->cdev, ctrl->device); + out_free_name: + nvme_put_ctrl(ctrl); + kfree_const(ctrl->device->kobj.name); +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -928,14 +928,17 @@ static inline bool nvme_ctrl_sgl_support + } + + #ifdef CONFIG_NVME_AUTH +-void nvme_auth_init_ctrl(struct nvme_ctrl *ctrl); ++int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl); + void nvme_auth_stop(struct nvme_ctrl *ctrl); + int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid); + int nvme_auth_wait(struct nvme_ctrl *ctrl, int qid); + void nvme_auth_reset(struct nvme_ctrl *ctrl); + void nvme_auth_free(struct nvme_ctrl *ctrl); + #else +-static inline void nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) {}; ++static inline int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) ++{ ++ return 0; ++} + static inline void nvme_auth_stop(struct nvme_ctrl *ctrl) {}; + static inline int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid) + { diff --git a/patches.suse/nvme-auth-don-t-keep-long-lived-4k-dhchap-buffer.patch b/patches.suse/nvme-auth-don-t-keep-long-lived-4k-dhchap-buffer.patch new file mode 100644 index 0000000..78bd0d2 --- /dev/null +++ b/patches.suse/nvme-auth-don-t-keep-long-lived-4k-dhchap-buffer.patch @@ -0,0 +1,157 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:13 +0200 +Subject: nvme-auth: don't keep long lived 4k dhchap buffer +Patch-mainline: v6.2-rc1 +Git-commit: b7d604cae8f6edde53ac8aa9038ee154be562eb5 +References: bsc#1202633 + +dhchap structure is per-queue, it is wasteful to keep it for the entire +lifetime of the queue. Allocate it dynamically and get rid of it after +authentication. We don't need kzalloc because all accessors are clearing +it before writing to it. + +Also, remove redundant chap buf_size which is always 4096, use a define +instead. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 47 ++++++++++++++++++++++++----------------------- + 1 file changed, 24 insertions(+), 23 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -13,6 +13,8 @@ + #include "fabrics.h" + #include + ++#define CHAP_BUF_SIZE 4096 ++ + struct nvme_dhchap_queue_context { + struct list_head entry; + struct work_struct auth_work; +@@ -20,7 +22,6 @@ struct nvme_dhchap_queue_context { + struct crypto_shash *shash_tfm; + struct crypto_kpp *dh_tfm; + void *buf; +- size_t buf_size; + int qid; + int error; + u32 s1; +@@ -112,7 +113,7 @@ static int nvme_auth_set_dhchap_negotiat + struct nvmf_auth_dhchap_negotiate_data *data = chap->buf; + size_t size = sizeof(*data) + sizeof(union nvmf_auth_protocol); + +- if (chap->buf_size < size) { ++ if (size > CHAP_BUF_SIZE) { + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; + return -EINVAL; + } +@@ -147,7 +148,7 @@ static int nvme_auth_process_dhchap_chal + const char *gid_name = nvme_auth_dhgroup_name(data->dhgid); + const char *hmac_name, *kpp_name; + +- if (chap->buf_size < size) { ++ if (size > CHAP_BUF_SIZE) { + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; + return NVME_SC_INVALID_FIELD; + } +@@ -302,7 +303,7 @@ static int nvme_auth_set_dhchap_reply_da + if (chap->host_key_len) + size += chap->host_key_len; + +- if (chap->buf_size < size) { ++ if (size > CHAP_BUF_SIZE) { + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; + return -EINVAL; + } +@@ -347,7 +348,7 @@ static int nvme_auth_process_dhchap_succ + if (ctrl->ctrl_key) + size += chap->hash_len; + +- if (chap->buf_size < size) { ++ if (size > CHAP_BUF_SIZE) { + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; + return NVME_SC_INVALID_FIELD; + } +@@ -674,6 +675,8 @@ static void nvme_auth_reset_dhchap(struc + chap->transaction = 0; + memset(chap->c1, 0, sizeof(chap->c1)); + memset(chap->c2, 0, sizeof(chap->c2)); ++ kfree(chap->buf); ++ chap->buf = NULL; + } + + static void nvme_auth_free_dhchap(struct nvme_dhchap_queue_context *chap) +@@ -683,7 +686,6 @@ static void nvme_auth_free_dhchap(struct + crypto_free_shash(chap->shash_tfm); + if (chap->dh_tfm) + crypto_free_kpp(chap->dh_tfm); +- kfree(chap->buf); + kfree(chap); + } + +@@ -695,6 +697,16 @@ static void nvme_queue_auth_work(struct + size_t tl; + int ret = 0; + ++ /* ++ * Allocate a large enough buffer for the entire negotiation: ++ * 4k is enough to ffdhe8192. ++ */ ++ chap->buf = kmalloc(CHAP_BUF_SIZE, GFP_KERNEL); ++ if (!chap->buf) { ++ chap->error = -ENOMEM; ++ return; ++ } ++ + chap->transaction = ctrl->transaction++; + + /* DH-HMAC-CHAP Step 1: send negotiate */ +@@ -716,8 +728,9 @@ static void nvme_queue_auth_work(struct + dev_dbg(ctrl->device, "%s: qid %d receive challenge\n", + __func__, chap->qid); + +- memset(chap->buf, 0, chap->buf_size); +- ret = nvme_auth_submit(ctrl, chap->qid, chap->buf, chap->buf_size, false); ++ memset(chap->buf, 0, CHAP_BUF_SIZE); ++ ret = nvme_auth_submit(ctrl, chap->qid, chap->buf, CHAP_BUF_SIZE, ++ false); + if (ret) { + dev_warn(ctrl->device, + "qid %d failed to receive challenge, %s %d\n", +@@ -779,8 +792,9 @@ static void nvme_queue_auth_work(struct + dev_dbg(ctrl->device, "%s: qid %d receive success1\n", + __func__, chap->qid); + +- memset(chap->buf, 0, chap->buf_size); +- ret = nvme_auth_submit(ctrl, chap->qid, chap->buf, chap->buf_size, false); ++ memset(chap->buf, 0, CHAP_BUF_SIZE); ++ ret = nvme_auth_submit(ctrl, chap->qid, chap->buf, CHAP_BUF_SIZE, ++ false); + if (ret) { + dev_warn(ctrl->device, + "qid %d failed to receive success1, %s %d\n", +@@ -876,19 +890,6 @@ int nvme_auth_negotiate(struct nvme_ctrl + } + chap->qid = qid; + chap->ctrl = ctrl; +- +- /* +- * Allocate a large enough buffer for the entire negotiation: +- * 4k should be enough to ffdhe8192. +- */ +- chap->buf_size = 4096; +- chap->buf = kzalloc(chap->buf_size, GFP_KERNEL); +- if (!chap->buf) { +- mutex_unlock(&ctrl->dhchap_auth_mutex); +- kfree(chap); +- return -ENOMEM; +- } +- + INIT_WORK(&chap->auth_work, nvme_queue_auth_work); + list_add(&chap->entry, &ctrl->dhchap_auth_list); + mutex_unlock(&ctrl->dhchap_auth_mutex); diff --git a/patches.suse/nvme-auth-don-t-override-ctrl-keys-before-validation.patch b/patches.suse/nvme-auth-don-t-override-ctrl-keys-before-validation.patch new file mode 100644 index 0000000..5766607 --- /dev/null +++ b/patches.suse/nvme-auth-don-t-override-ctrl-keys-before-validation.patch @@ -0,0 +1,59 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:11 +0200 +Subject: nvme-auth: don't override ctrl keys before validation +Patch-mainline: v6.2-rc1 +Git-commit: 01604350e14560d4d69323eb1ba12a257a643ea8 +References: bsc#1202633 + +Replace ctrl ctrl_key/host_key only after nvme_auth_generate_key is successful. +Also, this fixes a bug where the keys are leaked. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/core.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -3576,13 +3576,17 @@ static ssize_t nvme_ctrl_dhchap_secret_s + memcpy(dhchap_secret, buf, count); + nvme_auth_stop(ctrl); + if (strcmp(dhchap_secret, opts->dhchap_secret)) { ++ struct nvme_dhchap_key *key, *host_key; + int ret; + +- ret = nvme_auth_generate_key(dhchap_secret, &ctrl->host_key); ++ ret = nvme_auth_generate_key(dhchap_secret, &key); + if (ret) + return ret; + kfree(opts->dhchap_secret); + opts->dhchap_secret = dhchap_secret; ++ host_key = ctrl->host_key; ++ ctrl->host_key = key; ++ nvme_auth_free_key(host_key); + /* Key has changed; re-authentication with new key */ + nvme_auth_reset(ctrl); + } +@@ -3626,13 +3630,17 @@ static ssize_t nvme_ctrl_dhchap_ctrl_sec + memcpy(dhchap_secret, buf, count); + nvme_auth_stop(ctrl); + if (strcmp(dhchap_secret, opts->dhchap_ctrl_secret)) { ++ struct nvme_dhchap_key *key, *ctrl_key; + int ret; + +- ret = nvme_auth_generate_key(dhchap_secret, &ctrl->ctrl_key); ++ ret = nvme_auth_generate_key(dhchap_secret, &key); + if (ret) + return ret; + kfree(opts->dhchap_ctrl_secret); + opts->dhchap_ctrl_secret = dhchap_secret; ++ ctrl_key = ctrl->ctrl_key; ++ ctrl->ctrl_key = key; ++ nvme_auth_free_key(ctrl_key); + /* Key has changed; re-authentication with new key */ + nvme_auth_reset(ctrl); + } diff --git a/patches.suse/nvme-auth-don-t-re-authenticate-if-the-controller-is.patch b/patches.suse/nvme-auth-don-t-re-authenticate-if-the-controller-is.patch new file mode 100644 index 0000000..e0ebf96 --- /dev/null +++ b/patches.suse/nvme-auth-don-t-re-authenticate-if-the-controller-is.patch @@ -0,0 +1,34 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:08 +0200 +Subject: nvme-auth: don't re-authenticate if the controller is not LIVE +Patch-mainline: v6.2-rc1 +Git-commit: c7390f132a896ff1a3fa26ea2b0be4f9ceb9041e +References: bsc#1202633 + +The connect sequence will re-authenticate. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -939,6 +939,13 @@ static void nvme_ctrl_auth_work(struct w + container_of(work, struct nvme_ctrl, dhchap_auth_work); + int ret, q; + ++ /* ++ * If the ctrl is no connected, bail as reconnect will handle ++ * authentication. ++ */ ++ if (ctrl->state != NVME_CTRL_LIVE) ++ return; ++ + /* Authenticate admin queue first */ + ret = nvme_auth_negotiate(ctrl, 0); + if (ret) { diff --git a/patches.suse/nvme-auth-don-t-use-NVMe-status-codes.patch b/patches.suse/nvme-auth-don-t-use-NVMe-status-codes.patch new file mode 100644 index 0000000..d1eff09 --- /dev/null +++ b/patches.suse/nvme-auth-don-t-use-NVMe-status-codes.patch @@ -0,0 +1,158 @@ +From: Hannes Reinecke +Date: Tue, 13 Dec 2022 20:00:26 +0100 +Subject: nvme-auth: don't use NVMe status codes +Patch-mainline: v6.3-rc1 +Git-commit: b0ef1b11d3909d8f246dd3af9c94e38880d349b0 +References: bsc#1202633 + +NVMe status codes are part of the wire protocol, and shouldn't be +fabricated in the stack. So with this patch the authentication code +is switched over to use error codes; as a side effect authentication +failures due to internal error won't be retried anymore. +But that shouldn't have happened anyway. + +Signed-off-by: Hannes Reinecke +Reviewed-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -160,7 +160,7 @@ static int nvme_auth_process_dhchap_chal + + if (size > CHAP_BUF_SIZE) { + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; +- return NVME_SC_INVALID_FIELD; ++ return -EINVAL; + } + + hmac_name = nvme_auth_hmac_name(data->hashid); +@@ -169,7 +169,7 @@ static int nvme_auth_process_dhchap_chal + "qid %d: invalid HASH ID %d\n", + chap->qid, data->hashid); + chap->status = NVME_AUTH_DHCHAP_FAILURE_HASH_UNUSABLE; +- return NVME_SC_INVALID_FIELD; ++ return -EPROTO; + } + + if (chap->hash_id == data->hashid && chap->shash_tfm && +@@ -195,7 +195,7 @@ static int nvme_auth_process_dhchap_chal + chap->qid, hmac_name, PTR_ERR(chap->shash_tfm)); + chap->shash_tfm = NULL; + chap->status = NVME_AUTH_DHCHAP_FAILURE_FAILED; +- return NVME_SC_AUTH_REQUIRED; ++ return -ENOMEM; + } + + if (crypto_shash_digestsize(chap->shash_tfm) != data->hl) { +@@ -205,7 +205,7 @@ static int nvme_auth_process_dhchap_chal + crypto_free_shash(chap->shash_tfm); + chap->shash_tfm = NULL; + chap->status = NVME_AUTH_DHCHAP_FAILURE_HASH_UNUSABLE; +- return NVME_SC_AUTH_REQUIRED; ++ return -EPROTO; + } + + chap->hash_id = data->hashid; +@@ -221,7 +221,7 @@ static int nvme_auth_process_dhchap_chal + chap->qid, data->dhgid); + chap->status = NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE; + /* Leave previous dh_tfm intact */ +- return NVME_SC_AUTH_REQUIRED; ++ return -EPROTO; + } + + if (chap->dhgroup_id == data->dhgid && +@@ -244,7 +244,7 @@ static int nvme_auth_process_dhchap_chal + "qid %d: empty DH value\n", + chap->qid); + chap->status = NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE; +- return NVME_SC_INVALID_FIELD; ++ return -EPROTO; + } + + chap->dh_tfm = crypto_alloc_kpp(kpp_name, 0, 0); +@@ -256,7 +256,7 @@ static int nvme_auth_process_dhchap_chal + chap->qid, ret, gid_name); + chap->status = NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE; + chap->dh_tfm = NULL; +- return NVME_SC_AUTH_REQUIRED; ++ return -ret; + } + dev_dbg(ctrl->device, "qid %d: selected DH group %s\n", + chap->qid, gid_name); +@@ -265,7 +265,7 @@ static int nvme_auth_process_dhchap_chal + "qid %d: invalid DH value for NULL DH\n", + chap->qid); + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; +- return NVME_SC_INVALID_FIELD; ++ return -EPROTO; + } + chap->dhgroup_id = data->dhgid; + +@@ -276,7 +276,7 @@ static int nvme_auth_process_dhchap_chal + chap->ctrl_key = kmalloc(dhvlen, GFP_KERNEL); + if (!chap->ctrl_key) { + chap->status = NVME_AUTH_DHCHAP_FAILURE_FAILED; +- return NVME_SC_AUTH_REQUIRED; ++ return -ENOMEM; + } + chap->ctrl_key_len = dhvlen; + memcpy(chap->ctrl_key, data->cval + chap->hash_len, +@@ -346,7 +346,7 @@ static int nvme_auth_process_dhchap_succ + + if (size > CHAP_BUF_SIZE) { + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; +- return NVME_SC_INVALID_FIELD; ++ return -EINVAL; + } + + if (data->hl != chap->hash_len) { +@@ -354,7 +354,7 @@ static int nvme_auth_process_dhchap_succ + "qid %d: invalid hash length %u\n", + chap->qid, data->hl); + chap->status = NVME_AUTH_DHCHAP_FAILURE_HASH_UNUSABLE; +- return NVME_SC_INVALID_FIELD; ++ return -EPROTO; + } + + /* Just print out information for the admin queue */ +@@ -378,7 +378,7 @@ static int nvme_auth_process_dhchap_succ + "qid %d: controller authentication failed\n", + chap->qid); + chap->status = NVME_AUTH_DHCHAP_FAILURE_FAILED; +- return NVME_SC_AUTH_REQUIRED; ++ return -ECONNREFUSED; + } + + /* Just print out information for the admin queue */ +@@ -732,7 +732,7 @@ static void nvme_queue_auth_work(struct + NVME_AUTH_DHCHAP_MESSAGE_CHALLENGE); + if (ret) { + chap->status = ret; +- chap->error = NVME_SC_AUTH_REQUIRED; ++ chap->error = -ECONNREFUSED; + return; + } + +@@ -800,7 +800,7 @@ static void nvme_queue_auth_work(struct + NVME_AUTH_DHCHAP_MESSAGE_SUCCESS1); + if (ret) { + chap->status = ret; +- chap->error = NVME_SC_AUTH_REQUIRED; ++ chap->error = -ECONNREFUSED; + return; + } + +@@ -821,7 +821,7 @@ static void nvme_queue_auth_work(struct + ret = nvme_auth_process_dhchap_success1(ctrl, chap); + if (ret) { + /* Controller authentication failed */ +- chap->error = NVME_SC_AUTH_REQUIRED; ++ chap->error = -ECONNREFUSED; + goto fail2; + } + diff --git a/patches.suse/nvme-auth-fix-an-error-code-in-nvme_auth_process_dhc.patch b/patches.suse/nvme-auth-fix-an-error-code-in-nvme_auth_process_dhc.patch new file mode 100644 index 0000000..44a5b67 --- /dev/null +++ b/patches.suse/nvme-auth-fix-an-error-code-in-nvme_auth_process_dhc.patch @@ -0,0 +1,31 @@ +From: Dan Carpenter +Date: Thu, 16 Feb 2023 15:14:49 +0300 +Subject: nvme-auth: fix an error code in nvme_auth_process_dhchap_challenge() +Patch-mainline: v6.3-rc1 +Git-commit: 51d24f701f453c18cb5f4596d8bbe8034e5d3fb4 +References: bsc#1202633 + +This function was transitioned from returning NVMe status codes to +returning traditional kernel error codes. However, this particular +return now accidentally returns positive error codes like ENOMEM instead +of negative -ENOMEM. + +Fixes: b0ef1b11d390 ("nvme-auth: don't use NVMe status codes") +Signed-off-by: Dan Carpenter +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -256,7 +256,7 @@ static int nvme_auth_process_dhchap_chal + chap->qid, ret, gid_name); + chap->status = NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE; + chap->dh_tfm = NULL; +- return -ret; ++ return ret; + } + dev_dbg(ctrl->device, "qid %d: selected DH group %s\n", + chap->qid, gid_name); diff --git a/patches.suse/nvme-auth-fix-smatch-warning-complaints.patch b/patches.suse/nvme-auth-fix-smatch-warning-complaints.patch new file mode 100644 index 0000000..50e3d5a --- /dev/null +++ b/patches.suse/nvme-auth-fix-smatch-warning-complaints.patch @@ -0,0 +1,33 @@ +From: Sagi Grimberg +Date: Sun, 25 Dec 2022 13:28:51 +0200 +Subject: nvme-auth: fix smatch warning complaints +Patch-mainline: v6.2-rc2 +Git-commit: 76807fcd73b818eb9f245ef1035aed34ecdd9813 +References: bsc#1202633 + +When initializing auth context, there may be no secrets passed +by the user. Make return code explicit when returning successfully. + +smatch warnings: +drivers/nvme/host/auth.c:950 nvme_auth_init_ctrl() warn: missing error code? 'ret' + +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -953,7 +953,7 @@ int nvme_auth_init_ctrl(struct nvme_ctrl + goto err_free_dhchap_secret; + + if (!ctrl->opts->dhchap_secret && !ctrl->opts->dhchap_ctrl_secret) +- return ret; ++ return 0; + + ctrl->dhchap_ctxs = kvcalloc(ctrl_max_dhchaps(ctrl), + sizeof(*chap), GFP_KERNEL); diff --git a/patches.suse/nvme-auth-guarantee-dhchap-buffers-under-memory-pres.patch b/patches.suse/nvme-auth-guarantee-dhchap-buffers-under-memory-pres.patch new file mode 100644 index 0000000..24f48a4 --- /dev/null +++ b/patches.suse/nvme-auth-guarantee-dhchap-buffers-under-memory-pres.patch @@ -0,0 +1,126 @@ +From: Sagi Grimberg +Date: Tue, 15 Nov 2022 17:08:06 +0100 +Subject: nvme-auth: guarantee dhchap buffers under memory pressure +Patch-mainline: v6.2-rc1 +Git-commit: e481fc0a377798976d5c3044c7f10c86a8372b92 +References: bsc#1202633 + +We want to guarantee that we have chap buffers when a controller +reconnects under memory pressure. Add a mempool specifically +for that. + +Signed-off-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 30 ++++++++++++++++++++++++++++-- + drivers/nvme/host/core.c | 6 ++++++ + drivers/nvme/host/nvme.h | 9 +++++++++ + 3 files changed, 43 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -14,6 +14,8 @@ + #include + + #define CHAP_BUF_SIZE 4096 ++static struct kmem_cache *nvme_chap_buf_cache; ++static mempool_t *nvme_chap_buf_pool; + + struct nvme_dhchap_queue_context { + struct list_head entry; +@@ -675,7 +677,7 @@ static void nvme_auth_reset_dhchap(struc + chap->transaction = 0; + memset(chap->c1, 0, sizeof(chap->c1)); + memset(chap->c2, 0, sizeof(chap->c2)); +- kfree(chap->buf); ++ mempool_free(chap->buf, nvme_chap_buf_pool); + chap->buf = NULL; + } + +@@ -701,7 +703,7 @@ static void nvme_queue_auth_work(struct + * Allocate a large enough buffer for the entire negotiation: + * 4k is enough to ffdhe8192. + */ +- chap->buf = kmalloc(CHAP_BUF_SIZE, GFP_KERNEL); ++ chap->buf = mempool_alloc(nvme_chap_buf_pool, GFP_KERNEL); + if (!chap->buf) { + chap->error = -ENOMEM; + return; +@@ -1029,3 +1031,27 @@ void nvme_auth_free(struct nvme_ctrl *ct + } + } + EXPORT_SYMBOL_GPL(nvme_auth_free); ++ ++int __init nvme_init_auth(void) ++{ ++ nvme_chap_buf_cache = kmem_cache_create("nvme-chap-buf-cache", ++ CHAP_BUF_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL); ++ if (!nvme_chap_buf_cache) ++ return -ENOMEM; ++ ++ nvme_chap_buf_pool = mempool_create(16, mempool_alloc_slab, ++ mempool_free_slab, nvme_chap_buf_cache); ++ if (!nvme_chap_buf_pool) ++ goto err_destroy_chap_buf_cache; ++ ++ return 0; ++err_destroy_chap_buf_cache: ++ kmem_cache_destroy(nvme_chap_buf_cache); ++ return -ENOMEM; ++} ++ ++void __exit nvme_exit_auth(void) ++{ ++ mempool_destroy(nvme_chap_buf_pool); ++ kmem_cache_destroy(nvme_chap_buf_cache); ++} +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -4946,8 +4946,13 @@ static int __init nvme_core_init(void) + goto unregister_generic_ns; + } + ++ result = nvme_init_auth(); ++ if (result) ++ goto destroy_ns_chr; + return 0; + ++destroy_ns_chr: ++ class_destroy(nvme_ns_chr_class); + unregister_generic_ns: + unregister_chrdev_region(nvme_ns_chr_devt, NVME_MINORS); + destroy_subsys_class: +@@ -4968,6 +4973,7 @@ static int __init nvme_core_init(void) + + static void __exit nvme_core_exit(void) + { ++ nvme_exit_auth(); + class_destroy(nvme_ns_chr_class); + class_destroy(nvme_subsys_class); + class_destroy(nvme_class); +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -928,6 +928,8 @@ static inline bool nvme_ctrl_sgl_support + } + + #ifdef CONFIG_NVME_AUTH ++int __init nvme_init_auth(void); ++void __exit nvme_exit_auth(void); + int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl); + void nvme_auth_stop(struct nvme_ctrl *ctrl); + int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid); +@@ -939,6 +941,13 @@ static inline int nvme_auth_init_ctrl(st + { + return 0; + } ++static inline int __init nvme_init_auth(void) ++{ ++ return 0; ++} ++static inline void __exit nvme_exit_auth(void) ++{ ++} + static inline void nvme_auth_stop(struct nvme_ctrl *ctrl) {}; + static inline int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid) + { diff --git a/patches.suse/nvme-auth-have-dhchap_auth_work-wait-for-queues-auth.patch b/patches.suse/nvme-auth-have-dhchap_auth_work-wait-for-queues-auth.patch new file mode 100644 index 0000000..190cedd --- /dev/null +++ b/patches.suse/nvme-auth-have-dhchap_auth_work-wait-for-queues-auth.patch @@ -0,0 +1,51 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:22 +0200 +Subject: nvme-auth: have dhchap_auth_work wait for queues auth to complete +Patch-mainline: v6.2-rc1 +Git-commit: d061a1bd1fff5332ee48601947abb414007a9610 +References: bsc#1202633 + +It triggered the queue authentication work elements in parallel, but +the ctrl authentication work itself completes when all of them +completes. Hence wait for queues auth completions. + +This also makes nvme_auth_stop simply a sync cancel of ctrl +dhchap_auth_work. + +Signed-off-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -926,6 +926,12 @@ static void nvme_ctrl_auth_work(struct w + * Failure is a soft-state; credentials remain valid until + * the controller terminates the connection. + */ ++ for (q = 1; q < ctrl->queue_count; q++) { ++ ret = nvme_auth_wait(ctrl, q); ++ if (ret) ++ dev_warn(ctrl->device, ++ "qid %d: authentication failed\n", q); ++ } + } + + int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) +@@ -976,14 +982,7 @@ EXPORT_SYMBOL_GPL(nvme_auth_init_ctrl); + + void nvme_auth_stop(struct nvme_ctrl *ctrl) + { +- struct nvme_dhchap_queue_context *chap; +- int i; +- + cancel_work_sync(&ctrl->dhchap_auth_work); +- for (i = 0; i < ctrl_max_dhchaps(ctrl); i++) { +- chap = &ctrl->dhchap_ctxs[i]; +- cancel_work_sync(&chap->auth_work); +- } + } + EXPORT_SYMBOL_GPL(nvme_auth_stop); + diff --git a/patches.suse/nvme-auth-mark-nvme_auth_wq-static.patch b/patches.suse/nvme-auth-mark-nvme_auth_wq-static.patch new file mode 100644 index 0000000..d30b2e2 --- /dev/null +++ b/patches.suse/nvme-auth-mark-nvme_auth_wq-static.patch @@ -0,0 +1,33 @@ +From: Tom Rix +Date: Mon, 6 Feb 2023 06:57:00 -0800 +Subject: nvme-auth: mark nvme_auth_wq static +Patch-mainline: v6.2-rc8 +Git-commit: 70daa5c8f001e351af174c40ac21eb0a25600483 +References: bsc#1202633 + +Fix a smatch report for the newly added nvme_auth_wq. + +Signed-off-by: Tom Rix +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c +index b57630d1d3b8..bdb97496ba2d 100644 +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -45,7 +45,7 @@ struct nvme_dhchap_queue_context { + int sess_key_len; + }; + +-struct workqueue_struct *nvme_auth_wq; ++static struct workqueue_struct *nvme_auth_wq; + + #define nvme_auth_flags_from_qid(qid) \ + (qid == 0) ? 0 : BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED +-- +2.35.3 + diff --git a/patches.suse/nvme-auth-no-need-to-reset-chap-contexts-on-re-authe.patch b/patches.suse/nvme-auth-no-need-to-reset-chap-contexts-on-re-authe.patch new file mode 100644 index 0000000..24b1585 --- /dev/null +++ b/patches.suse/nvme-auth-no-need-to-reset-chap-contexts-on-re-authe.patch @@ -0,0 +1,73 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:17 +0200 +Subject: nvme-auth: no need to reset chap contexts on re-authentication +Patch-mainline: v6.2-rc1 +Git-commit: e8a420efb637f52c586596283d6fd96f2a7ecb5c +References: bsc#1202633 + +Now that the chap context is reset upon completion, this is no longer +needed. Also remove nvme_auth_reset as no callers are left. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 13 ------------- + drivers/nvme/host/core.c | 4 ---- + drivers/nvme/host/nvme.h | 1 - + 3 files changed, 18 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -901,19 +901,6 @@ int nvme_auth_wait(struct nvme_ctrl *ctr + } + EXPORT_SYMBOL_GPL(nvme_auth_wait); + +-void nvme_auth_reset(struct nvme_ctrl *ctrl) +-{ +- struct nvme_dhchap_queue_context *chap; +- +- mutex_lock(&ctrl->dhchap_auth_mutex); +- list_for_each_entry(chap, &ctrl->dhchap_auth_list, entry) { +- mutex_unlock(&ctrl->dhchap_auth_mutex); +- flush_work(&chap->auth_work); +- nvme_auth_reset_dhchap(chap); +- } +- mutex_unlock(&ctrl->dhchap_auth_mutex); +-} +- + static void nvme_ctrl_auth_work(struct work_struct *work) + { + struct nvme_ctrl *ctrl = +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -3587,8 +3587,6 @@ static ssize_t nvme_ctrl_dhchap_secret_s + host_key = ctrl->host_key; + ctrl->host_key = key; + nvme_auth_free_key(host_key); +- /* Key has changed; re-authentication with new key */ +- nvme_auth_reset(ctrl); + } + /* Start re-authentication */ + dev_info(ctrl->device, "re-authenticating controller\n"); +@@ -3641,8 +3639,6 @@ static ssize_t nvme_ctrl_dhchap_ctrl_sec + ctrl_key = ctrl->ctrl_key; + ctrl->ctrl_key = key; + nvme_auth_free_key(ctrl_key); +- /* Key has changed; re-authentication with new key */ +- nvme_auth_reset(ctrl); + } + /* Start re-authentication */ + dev_info(ctrl->device, "re-authenticating controller\n"); +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -934,7 +934,6 @@ int nvme_auth_init_ctrl(struct nvme_ctrl + void nvme_auth_stop(struct nvme_ctrl *ctrl); + int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid); + int nvme_auth_wait(struct nvme_ctrl *ctrl, int qid); +-void nvme_auth_reset(struct nvme_ctrl *ctrl); + void nvme_auth_free(struct nvme_ctrl *ctrl); + #else + static inline int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) diff --git a/patches.suse/nvme-auth-remove-redundant-auth_work-flush.patch b/patches.suse/nvme-auth-remove-redundant-auth_work-flush.patch new file mode 100644 index 0000000..1b6b0d5 --- /dev/null +++ b/patches.suse/nvme-auth-remove-redundant-auth_work-flush.patch @@ -0,0 +1,41 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:21 +0200 +Subject: nvme-auth: remove redundant auth_work flush +Patch-mainline: v6.2-rc1 +Git-commit: a2a00d2a66e480c8b225012db538dca6e389a92d +References: bsc#1202633 + +only ctrl deletion calls nvme_auth_free, which was stopped prior in the +teardown stage, so there is no possibility that it should ever run when +nvme_auth_free is called. As a result, we can remove a local chap pointer +variable. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -989,15 +989,11 @@ EXPORT_SYMBOL_GPL(nvme_auth_stop); + + void nvme_auth_free(struct nvme_ctrl *ctrl) + { +- struct nvme_dhchap_queue_context *chap; + int i; + + if (ctrl->dhchap_ctxs) { +- for (i = 0; i < ctrl_max_dhchaps(ctrl); i++) { +- chap = &ctrl->dhchap_ctxs[i]; +- flush_work(&chap->auth_work); +- nvme_auth_free_dhchap(chap); +- } ++ for (i = 0; i < ctrl_max_dhchaps(ctrl); i++) ++ nvme_auth_free_dhchap(&ctrl->dhchap_ctxs[i]); + kfree(ctrl->dhchap_ctxs); + } + if (ctrl->host_key) { diff --git a/patches.suse/nvme-auth-remove-redundant-buffer-deallocations.patch b/patches.suse/nvme-auth-remove-redundant-buffer-deallocations.patch new file mode 100644 index 0000000..c04323e --- /dev/null +++ b/patches.suse/nvme-auth-remove-redundant-buffer-deallocations.patch @@ -0,0 +1,33 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:09 +0200 +Subject: nvme-auth: remove redundant buffer deallocations +Patch-mainline: v6.2-rc1 +Git-commit: f6b182fbd5c608bd6cbaaaee35b1325443f48043 +References: bsc#1202633 + +host_response, host_key, ctrl_key and sess_key are +freed in nvme_auth_reset_dhchap which is called from +nvme_auth_free_dhchap. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -683,10 +683,6 @@ static void nvme_auth_free_dhchap(struct + crypto_free_shash(chap->shash_tfm); + if (chap->dh_tfm) + crypto_free_kpp(chap->dh_tfm); +- kfree_sensitive(chap->ctrl_key); +- kfree_sensitive(chap->host_key); +- kfree_sensitive(chap->sess_key); +- kfree_sensitive(chap->host_response); + kfree(chap->buf); + kfree(chap); + } diff --git a/patches.suse/nvme-auth-remove-redundant-deallocations.patch b/patches.suse/nvme-auth-remove-redundant-deallocations.patch new file mode 100644 index 0000000..8e92f95 --- /dev/null +++ b/patches.suse/nvme-auth-remove-redundant-deallocations.patch @@ -0,0 +1,69 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:16 +0200 +Subject: nvme-auth: remove redundant deallocations +Patch-mainline: v6.2-rc1 +Git-commit: 96df31839354c2bb9d2f0d51eb6c6f6b762fd150 +References: bsc#1202633 + +These are now redundant as the dhchap context is +removed after authentication completes. + +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 20 -------------------- + 1 file changed, 20 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -200,12 +200,6 @@ static int nvme_auth_process_dhchap_chal + return NVME_SC_AUTH_REQUIRED; + } + +- /* Reset host response if the hash had been changed */ +- if (chap->hash_id != data->hashid) { +- kfree(chap->host_response); +- chap->host_response = NULL; +- } +- + chap->hash_id = data->hashid; + chap->hash_len = data->hl; + dev_dbg(ctrl->device, "qid %d: selected hash %s\n", +@@ -222,14 +216,6 @@ static int nvme_auth_process_dhchap_chal + return NVME_SC_AUTH_REQUIRED; + } + +- /* Clear host and controller key to avoid accidental reuse */ +- kfree_sensitive(chap->host_key); +- chap->host_key = NULL; +- chap->host_key_len = 0; +- kfree_sensitive(chap->ctrl_key); +- chap->ctrl_key = NULL; +- chap->ctrl_key_len = 0; +- + if (chap->dhgroup_id == data->dhgid && + (data->dhgid == NVME_AUTH_DHGROUP_NULL || chap->dh_tfm)) { + dev_dbg(ctrl->device, +@@ -624,9 +610,6 @@ static int nvme_auth_dhchap_exponential( + if (ret) { + dev_dbg(ctrl->device, + "failed to generate public key, error %d\n", ret); +- kfree(chap->host_key); +- chap->host_key = NULL; +- chap->host_key_len = 0; + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; + return ret; + } +@@ -646,9 +629,6 @@ static int nvme_auth_dhchap_exponential( + if (ret) { + dev_dbg(ctrl->device, + "failed to generate shared secret, error %d\n", ret); +- kfree_sensitive(chap->sess_key); +- chap->sess_key = NULL; +- chap->sess_key_len = 0; + chap->status = NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD; + return ret; + } diff --git a/patches.suse/nvme-auth-remove-redundant-if-statement.patch b/patches.suse/nvme-auth-remove-redundant-if-statement.patch new file mode 100644 index 0000000..234f1d7 --- /dev/null +++ b/patches.suse/nvme-auth-remove-redundant-if-statement.patch @@ -0,0 +1,29 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:12 +0200 +Subject: nvme-auth: remove redundant if statement +Patch-mainline: v6.2-rc1 +Git-commit: bfc4068e1e55e30a86f0e82e15163a60f99a894d +References: bsc#1202633 + +No one passes NVME_QID_ANY to nvme_auth_negotiate. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -874,7 +874,7 @@ int nvme_auth_negotiate(struct nvme_ctrl + mutex_unlock(&ctrl->dhchap_auth_mutex); + return -ENOMEM; + } +- chap->qid = (qid == NVME_QID_ANY) ? 0 : qid; ++ chap->qid = qid; + chap->ctrl = ctrl; + + /* diff --git a/patches.suse/nvme-auth-remove-symbol-export-from-nvme_auth_reset.patch b/patches.suse/nvme-auth-remove-symbol-export-from-nvme_auth_reset.patch new file mode 100644 index 0000000..8be17ec --- /dev/null +++ b/patches.suse/nvme-auth-remove-symbol-export-from-nvme_auth_reset.patch @@ -0,0 +1,28 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:07 +0200 +Subject: nvme-auth: remove symbol export from nvme_auth_reset +Patch-mainline: v6.2-rc1 +Git-commit: 100b555bc204fc754108351676297805f5affa49 +References: bsc#1202633 + +Only the nvme module calls it. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -932,7 +932,6 @@ void nvme_auth_reset(struct nvme_ctrl *c + } + mutex_unlock(&ctrl->dhchap_auth_mutex); + } +-EXPORT_SYMBOL_GPL(nvme_auth_reset); + + static void nvme_ctrl_auth_work(struct work_struct *work) + { diff --git a/patches.suse/nvme-auth-rename-__nvme_auth_-reset-free-to-nvme_aut.patch b/patches.suse/nvme-auth-rename-__nvme_auth_-reset-free-to-nvme_aut.patch new file mode 100644 index 0000000..c9476df --- /dev/null +++ b/patches.suse/nvme-auth-rename-__nvme_auth_-reset-free-to-nvme_aut.patch @@ -0,0 +1,71 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:05 +0200 +Subject: nvme-auth: rename __nvme_auth_[reset|free] to + nvme_auth[reset|free]_dhchap +Patch-mainline: v6.2-rc1 +Git-commit: 0a7ce375f83f4ade7c2a835444093b6870fb8257 +References: bsc#1202633 + +nvme_auth_[reset|free] operate on the controller while +__nvme_auth_[reset|free] operate on a chap struct (which maps to a queue +context). Rename it for clarity. + +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -654,7 +654,7 @@ static int nvme_auth_dhchap_exponential( + return 0; + } + +-static void __nvme_auth_reset(struct nvme_dhchap_queue_context *chap) ++static void nvme_auth_reset_dhchap(struct nvme_dhchap_queue_context *chap) + { + kfree_sensitive(chap->host_response); + chap->host_response = NULL; +@@ -676,9 +676,9 @@ static void __nvme_auth_reset(struct nvm + memset(chap->c2, 0, sizeof(chap->c2)); + } + +-static void __nvme_auth_free(struct nvme_dhchap_queue_context *chap) ++static void nvme_auth_free_dhchap(struct nvme_dhchap_queue_context *chap) + { +- __nvme_auth_reset(chap); ++ nvme_auth_reset_dhchap(chap); + if (chap->shash_tfm) + crypto_free_shash(chap->shash_tfm); + if (chap->dh_tfm) +@@ -868,7 +868,7 @@ int nvme_auth_negotiate(struct nvme_ctrl + dev_dbg(ctrl->device, "qid %d: re-using context\n", qid); + mutex_unlock(&ctrl->dhchap_auth_mutex); + flush_work(&chap->auth_work); +- __nvme_auth_reset(chap); ++ nvme_auth_reset_dhchap(chap); + queue_work(nvme_wq, &chap->auth_work); + return 0; + } +@@ -928,7 +928,7 @@ void nvme_auth_reset(struct nvme_ctrl *c + list_for_each_entry(chap, &ctrl->dhchap_auth_list, entry) { + mutex_unlock(&ctrl->dhchap_auth_mutex); + flush_work(&chap->auth_work); +- __nvme_auth_reset(chap); ++ nvme_auth_reset_dhchap(chap); + } + mutex_unlock(&ctrl->dhchap_auth_mutex); + } +@@ -1002,7 +1002,7 @@ void nvme_auth_free(struct nvme_ctrl *ct + list_for_each_entry_safe(chap, tmp, &ctrl->dhchap_auth_list, entry) { + list_del_init(&chap->entry); + flush_work(&chap->auth_work); +- __nvme_auth_free(chap); ++ nvme_auth_free_dhchap(chap); + } + mutex_unlock(&ctrl->dhchap_auth_mutex); + if (ctrl->host_key) { diff --git a/patches.suse/nvme-auth-rename-authentication-work-elements.patch b/patches.suse/nvme-auth-rename-authentication-work-elements.patch new file mode 100644 index 0000000..f80de64 --- /dev/null +++ b/patches.suse/nvme-auth-rename-authentication-work-elements.patch @@ -0,0 +1,57 @@ +From: Sagi Grimberg +Date: Sun, 13 Nov 2022 13:24:06 +0200 +Subject: nvme-auth: rename authentication work elements +Patch-mainline: v6.2-rc1 +Git-commit: 0c999e69c40a87285f910c400b550fad866e99d0 +References: bsc#1202633 + +Use nvme_ctrl_auth_work and nvme_queue_auth_work for better +readability. + +Signed-off-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -691,7 +691,7 @@ static void nvme_auth_free_dhchap(struct + kfree(chap); + } + +-static void __nvme_auth_work(struct work_struct *work) ++static void nvme_queue_auth_work(struct work_struct *work) + { + struct nvme_dhchap_queue_context *chap = + container_of(work, struct nvme_dhchap_queue_context, auth_work); +@@ -893,7 +893,7 @@ int nvme_auth_negotiate(struct nvme_ctrl + return -ENOMEM; + } + +- INIT_WORK(&chap->auth_work, __nvme_auth_work); ++ INIT_WORK(&chap->auth_work, nvme_queue_auth_work); + list_add(&chap->entry, &ctrl->dhchap_auth_list); + mutex_unlock(&ctrl->dhchap_auth_mutex); + queue_work(nvme_wq, &chap->auth_work); +@@ -934,7 +934,7 @@ void nvme_auth_reset(struct nvme_ctrl *c + } + EXPORT_SYMBOL_GPL(nvme_auth_reset); + +-static void nvme_dhchap_auth_work(struct work_struct *work) ++static void nvme_ctrl_auth_work(struct work_struct *work) + { + struct nvme_ctrl *ctrl = + container_of(work, struct nvme_ctrl, dhchap_auth_work); +@@ -973,7 +973,7 @@ static void nvme_dhchap_auth_work(struct + void nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) + { + INIT_LIST_HEAD(&ctrl->dhchap_auth_list); +- INIT_WORK(&ctrl->dhchap_auth_work, nvme_dhchap_auth_work); ++ INIT_WORK(&ctrl->dhchap_auth_work, nvme_ctrl_auth_work); + mutex_init(&ctrl->dhchap_auth_mutex); + if (!ctrl->opts) + return; diff --git a/patches.suse/nvme-auth-use-workqueue-dedicated-to-authentication.patch b/patches.suse/nvme-auth-use-workqueue-dedicated-to-authentication.patch new file mode 100644 index 0000000..6879f8f --- /dev/null +++ b/patches.suse/nvme-auth-use-workqueue-dedicated-to-authentication.patch @@ -0,0 +1,88 @@ +From: Shin'ichiro Kawasaki +Date: Tue, 31 Jan 2023 18:26:44 +0900 +Subject: nvme-auth: use workqueue dedicated to authentication +Patch-mainline: v6.2-rc7 +Git-commit: bd97a59da6a866e3dee5d2a2d582ec71dbbc84cd +References: bsc#1202633 + +NVMe In-Band authentication uses two kinds of works: chap->auth_work and +ctrl->dhchap_auth_work. The latter work flushes or cancels the former +work. However, the both works are queued to the same workqueue nvme-wq. +It results in the lockdep WARNING as follows: + + WARNING: possible recursive locking detected + 6.2.0-rc4+ #1 Not tainted + -------------------------------------------- + kworker/u16:7/69 is trying to acquire lock: + ffff902d52e65548 ((wq_completion)nvme-wq){+.+.}-{0:0}, at: start_flush_work+0x2c5/0x380 + + but task is already holding lock: + ffff902d52e65548 ((wq_completion)nvme-wq){+.+.}-{0:0}, at: process_one_work+0x210/0x410 + +To avoid the WARNING, introduce a new workqueue nvme-auth-wq dedicated +to chap->auth_work. + +Reported-by: Daniel Wagner +Link: https://lore.kernel.org/linux-nvme/20230130110802.paafkiipmitwtnwr@carbon.lan/ +Fixes: f50fff73d620 ("nvme: implement In-Band authentication") +Signed-off-by: Shin'ichiro Kawasaki +Tested-by: Daniel Wagner +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/auth.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -45,6 +45,8 @@ struct nvme_dhchap_queue_context { + int sess_key_len; + }; + ++struct workqueue_struct *nvme_auth_wq; ++ + #define nvme_auth_flags_from_qid(qid) \ + (qid == 0) ? 0 : BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED + #define nvme_auth_queue_from_qid(ctrl, qid) \ +@@ -866,7 +868,7 @@ int nvme_auth_negotiate(struct nvme_ctrl + + chap = &ctrl->dhchap_ctxs[qid]; + cancel_work_sync(&chap->auth_work); +- queue_work(nvme_wq, &chap->auth_work); ++ queue_work(nvme_auth_wq, &chap->auth_work); + return 0; + } + EXPORT_SYMBOL_GPL(nvme_auth_negotiate); +@@ -1008,10 +1010,15 @@ EXPORT_SYMBOL_GPL(nvme_auth_free); + + int __init nvme_init_auth(void) + { ++ nvme_auth_wq = alloc_workqueue("nvme-auth-wq", ++ WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0); ++ if (!nvme_auth_wq) ++ return -ENOMEM; ++ + nvme_chap_buf_cache = kmem_cache_create("nvme-chap-buf-cache", + CHAP_BUF_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL); + if (!nvme_chap_buf_cache) +- return -ENOMEM; ++ goto err_destroy_workqueue; + + nvme_chap_buf_pool = mempool_create(16, mempool_alloc_slab, + mempool_free_slab, nvme_chap_buf_cache); +@@ -1021,6 +1028,8 @@ int __init nvme_init_auth(void) + return 0; + err_destroy_chap_buf_cache: + kmem_cache_destroy(nvme_chap_buf_cache); ++err_destroy_workqueue: ++ destroy_workqueue(nvme_auth_wq); + return -ENOMEM; + } + +@@ -1028,4 +1037,5 @@ void __exit nvme_exit_auth(void) + { + mempool_destroy(nvme_chap_buf_pool); + kmem_cache_destroy(nvme_chap_buf_cache); ++ destroy_workqueue(nvme_auth_wq); + } diff --git a/series.conf b/series.conf index d53210a..34d2196 100644 --- a/series.conf +++ b/series.conf @@ -12995,6 +12995,7 @@ patches.suse/drm-panel-simple-Add-missing-bus-flags-for-Innolux-G.patch patches.suse/drm-amdgpu-sdma-Fix-incorrect-calculations-of-the-wp.patch patches.suse/drm-amdgpu-disable-runtime-pm-on-several-sienna-cich.patch + patches.suse/malidp-Fix-NULL-vs-IS_ERR-checking.patch patches.suse/drm-plane-Move-range-check-for-format_count-earlier.patch patches.suse/drm-bridge-tc358767-Fix-e-DP-bridge-endpoint-parsing.patch patches.suse/drm-panel-panel-simple-Fix-proper-bpc-for-AM-1280800.patch @@ -14523,6 +14524,7 @@ patches.suse/drm-bridge-lt9611uxc-Cancel-only-driver-s-work.patch patches.suse/virtio-gpu-fix-a-missing-check-to-avoid-NULL-derefer.patch patches.suse/udmabuf-Set-the-DMA-mask-for-the-udmabuf-device-v2.patch + patches.suse/drm-virtio-Fix-NULL-vs-IS_ERR-checking-in-virtio_gpu.patch patches.suse/drm-adv7511-override-i2c-address-of-cec-before-acces.patch patches.suse/0009-fbcon-Fix-accelerated-fbdev-scrolling-while-logo-is-.patch patches.suse/fbcon-Fix-boundary-checks-for-fbcon-vc-n1-n2-paramet.patch @@ -17152,6 +17154,23 @@ patches.suse/drbd-destroy-workqueue-when-drbd-device-was-freed.patch patches.suse/blk-mq-fix-possible-memleak-when-register-hctx-failed-4b7a.patch patches.suse/block-mq-deadline-Rename-deadline_is_seq_writes-3692.patch + patches.suse/nvme-auth-rename-__nvme_auth_-reset-free-to-nvme_aut.patch + patches.suse/nvme-auth-rename-authentication-work-elements.patch + patches.suse/nvme-auth-remove-symbol-export-from-nvme_auth_reset.patch + patches.suse/nvme-auth-don-t-re-authenticate-if-the-controller-is.patch + patches.suse/nvme-auth-remove-redundant-buffer-deallocations.patch + patches.suse/nvme-auth-don-t-ignore-key-generation-failures-when-.patch + patches.suse/nvme-auth-don-t-override-ctrl-keys-before-validation.patch + patches.suse/nvme-auth-remove-redundant-if-statement.patch + patches.suse/nvme-auth-don-t-keep-long-lived-4k-dhchap-buffer.patch + patches.suse/nvme-auth-guarantee-dhchap-buffers-under-memory-pres.patch + patches.suse/nvme-auth-clear-sensitive-info-right-after-authentic.patch + patches.suse/nvme-auth-remove-redundant-deallocations.patch + patches.suse/nvme-auth-no-need-to-reset-chap-contexts-on-re-authe.patch + patches.suse/nvme-auth-check-chap-ctrl_key-once-constructed.patch + patches.suse/nvme-auth-convert-dhchap_auth_list-to-an-array.patch + patches.suse/nvme-auth-remove-redundant-auth_work-flush.patch + patches.suse/nvme-auth-have-dhchap_auth_work-wait-for-queues-auth.patch patches.suse/block-Do-not-reread-partition-table-on-exclusively-o.patch patches.suse/floppy-Fix-memory-leak-in-do_floppy_init.patch patches.suse/0043-blktrace-Fix-output-non-blktrace-event-when-blk_classic-option-enabled.patch @@ -17663,6 +17682,7 @@ patches.suse/0001-exit-Use-READ_ONCE-for-all-oops-warn-limit-reads.patch patches.suse/regulator-core-fix-deadlock-on-regulator-enable.patch patches.suse/0054-block-bfq-fix-uaf-for-bfqq-in-bfq_exit_icq_bfqq.patch + patches.suse/nvme-auth-fix-smatch-warning-complaints.patch patches.suse/ALSA-line6-correct-midi-status-byte-when-receiving-d.patch patches.suse/ALSA-line6-fix-stack-overflow-in-line6_midi_transmit.patch patches.suse/ALSA-hda-realtek-Apply-dual-codec-fixup-for-Dell-Lat.patch @@ -17955,6 +17975,7 @@ patches.suse/efi-Accept-version-2-of-memory-attributes-table.patch patches.suse/efi-fix-potential-NULL-deref-in-efi_mem_reserve_pers.patch patches.suse/block-bfq-fix-uaf-for-bfqq-in-bic_set_bfqq-b600.patch + patches.suse/nvme-auth-use-workqueue-dedicated-to-authentication.patch patches.suse/powerpc-64s-Fix-local-irq-disable-when-PMIs-are-disa.patch patches.suse/powerpc-kexec_file-Fix-division-by-zero-in-extra-siz.patch patches.suse/powerpc-64s-radix-Fix-crash-with-unaligned-relocated.patch @@ -18010,6 +18031,7 @@ patches.suse/ASoC-rt715-sdca-fix-clock-stop-prepare-timeout-issue.patch patches.suse/ASoC-topology-Return-ENOMEM-on-memory-allocation-fai.patch patches.suse/ALSA-hda-realtek-Add-Positivo-N14KP6-TG.patch + patches.suse/nvme-auth-mark-nvme_auth_wq-static.patch patches.suse/ceph-flush-cap-releases-when-the-session-is-flushed.patch patches.suse/arm64-dts-rockchip-drop-unused-LED-mode-property-fro.patch patches.suse/ARM-dts-rockchip-add-power-domains-property-to-dp-no.patch @@ -18037,6 +18059,7 @@ patches.suse/mmc-jz4740-Work-around-bug-on-JZ4760-B.patch patches.suse/ALSA-hda-conexant-add-a-new-hda-codec-SN6180.patch patches.suse/ALSA-hda-realtek-fixed-wrong-gpio-assigned.patch + patches.suse/nvme-auth-don-t-use-NVMe-status-codes.patch patches.suse/s390-dasd-Fix-potential-memleak-in-dasd_eckd_init.patch patches.suse/block-bio-integrity-Copy-flags-when-bio_integrity_pa.patch patches.suse/ARM-OMAP2-Fix-memory-leak-in-realtime_counter_init.patch @@ -18392,6 +18415,7 @@ patches.suse/rtc-sun6i-Always-export-the-internal-oscillator.patch patches.suse/rtc-pm8xxx-fix-set-alarm-race.patch patches.suse/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch + patches.suse/nvme-auth-fix-an-error-code-in-nvme_auth_process_dhc.patch patches.suse/nvme-fabrics-show-well-known-discovery-name.patch patches.suse/thermal-intel-quark_dts-fix-error-pointer-dereferenc.patch patches.suse/thermal-intel-BXT_PMIC-select-REGMAP-instead-of-depe.patch