diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:25:40 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:25:40 -0700 |
| commit | 3b7cab693ba2bab63774bf5b988e8a61b2ef0f32 (patch) | |
| tree | 90e364f2004af7eb6c8ff0c205ffd15fd0c2144b /drivers/nvme/target | |
| parent | 3f1fe48a36b0b6722dc3fd421d93512bac138e9a (diff) | |
| parent | 684b413b5483f57c890c171b9400076a0143b918 (diff) | |
| download | linux-stable-3b7cab693ba2bab63774bf5b988e8a61b2ef0f32.tar.gz linux-stable-3b7cab693ba2bab63774bf5b988e8a61b2ef0f32.zip | |
Merge tag 'block-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull block fixes from Jens Axboe:
- NVMe fixes via Keith:
- Fix an out-of-bounds write in nvmet_auth_challenge(), where
sizeof() on a void pointer undercounted the challenge header and
let a short AUTH_RECEIVE buffer pass the check
- nvme-multipath fixes for an ANA log bounds check underflow, the
command effects log lifetime for multipath heads, and only
setting BLK_FEAT_ZONED after the zone info is known.
- nvmet fixes for ns->enabled teardown ordering, rejecting I/O
after the percpu ns reference is killed, device path preservation
on allocation failure, and too-short SGL segments in pci-epf
- nvme-tcp: revert the per-socket dynamic lockdep keys, and delay
the socket reclassification
- A DMA pool alignment quirk for the Micron 4100AT
- Controller state/reset race fixes, and -Wformat-security
workarounds
- blk-mq: set RQF_USE_SCHED when the operation is known, and allow
cached requests to be used for flush operations
- Reject polled dio with user integrity metadata
- Save the IRQ state in blkg_tryget_closest()
- Set the zone write granularity in virtio_blk
- ublk selftest fixes
* tag 'block-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: (23 commits)
virtio_blk: set the zone write granularity
nvme-multipath: set BLK_FEAT_ZONED only after the zone info is known
nvme: fix command effects log lifetime for multipath heads
nvmet: don't allow I/O admission after percpu ns reference is killed
nvmet: defer setting ns->enabled to false in nvmet_ns_disable()
nvmet: copy the hostid into the ctrl before creating PR pc_refs
nvmet-auth: fix out-of-bounds write in nvmet_auth_challenge()
nvmet: pci-epf: reject too-short SGL segments
nvme-multipath: fix underflow in ANA log bounds checks
nvme: work around all -Wformat-security warnings
nvme: work around -Wformat-security warning
nvme: do not reset controllers in NVME_CTRL_NEW state
nvme-tcp: delay nvme_tcp_reclassify_socket()
Revert "nvme-tcp: lockdep: use dynamic lockdep keys per socket instance"
drbd: remove unused drbd_nl_mcgrps[] array
blk-mq: allow cached requests to be used for flush operations
blk-mq: set RQF_USE_SCHED when the operation is known
block: reject polled dio with user integrity metadata
selftests: ublk: fix unused_result error
blk-cgroup: save IRQ state in blkg_tryget_closest()
...
Diffstat (limited to 'drivers/nvme/target')
| -rw-r--r-- | drivers/nvme/target/configfs.c | 9 | ||||
| -rw-r--r-- | drivers/nvme/target/core.c | 33 | ||||
| -rw-r--r-- | drivers/nvme/target/fabrics-cmd-auth.c | 2 | ||||
| -rw-r--r-- | drivers/nvme/target/nvmet.h | 2 | ||||
| -rw-r--r-- | drivers/nvme/target/pci-epf.c | 3 |
5 files changed, 32 insertions, 17 deletions
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 6286e3843..b03b5d1c2 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -534,6 +534,7 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item, struct nvmet_subsys *subsys = ns->subsys; size_t len; int ret; + char *new_path = NULL; mutex_lock(&subsys->lock); ret = -EBUSY; @@ -545,12 +546,14 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item, if (!len) goto out_unlock; - kfree(ns->device_path); ret = -ENOMEM; - ns->device_path = kmemdup_nul(page, len, GFP_KERNEL); - if (!ns->device_path) + new_path = kmemdup_nul(page, len, GFP_KERNEL); + if (!new_path) goto out_unlock; + kfree(ns->device_path); + ns->device_path = new_path; + mutex_unlock(&subsys->lock); return count; diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 43871a8f5..8eea0a504 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -446,20 +446,27 @@ u16 nvmet_req_find_ns(struct nvmet_req *req) { u32 nsid = le32_to_cpu(req->cmd->common.nsid); struct nvmet_subsys *subsys = nvmet_req_subsys(req); + u16 status = NVME_SC_SUCCESS; + rcu_read_lock(); req->ns = xa_load(&subsys->namespaces, nsid); - if (unlikely(!req->ns || !req->ns->enabled)) { + if (unlikely(!req->ns) || + !test_bit(NVMET_NS_IO_LIVE, &req->ns->flags) || + !percpu_ref_tryget_live_rcu(&req->ns->ref)) { req->error_loc = offsetof(struct nvme_common_command, nsid); - if (!req->ns) /* ns doesn't exist! */ - return NVME_SC_INVALID_NS | NVME_STATUS_DNR; + if (!req->ns) { /* ns doesn't exist! */ + status = NVME_SC_INVALID_NS | NVME_STATUS_DNR; + goto unlock; + } /* ns exists but it's disabled */ req->ns = NULL; - return NVME_SC_INTERNAL_PATH_ERROR; + status = NVME_SC_INTERNAL_PATH_ERROR; } +unlock: + rcu_read_unlock(); - percpu_ref_get(&req->ns->ref); - return NVME_SC_SUCCESS; + return status; } static void nvmet_destroy_namespace(struct percpu_ref *ref) @@ -623,6 +630,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns) ns->enabled = true; xa_set_mark(&subsys->namespaces, ns->nsid, NVMET_NS_ENABLED); nvmet_debugfs_ns_setup(ns); + set_bit(NVMET_NS_IO_LIVE, &ns->flags); ret = 0; out_unlock: mutex_unlock(&subsys->lock); @@ -643,11 +651,11 @@ void nvmet_ns_disable(struct nvmet_ns *ns) struct nvmet_subsys *subsys = ns->subsys; struct nvmet_ctrl *ctrl; + if (!test_and_clear_bit(NVMET_NS_IO_LIVE, &ns->flags)) + return; + mutex_lock(&subsys->lock); - if (!ns->enabled) - goto out_unlock; - ns->enabled = false; xa_clear_mark(&subsys->namespaces, ns->nsid, NVMET_NS_ENABLED); nvmet_debugfs_ns_free(ns); @@ -675,7 +683,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns) mutex_lock(&subsys->lock); nvmet_ns_changed(subsys, ns->nsid); nvmet_ns_dev_disable(ns); -out_unlock: + ns->enabled = false; mutex_unlock(&subsys->lock); } @@ -1648,6 +1656,8 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) INIT_DELAYED_WORK(&ctrl->ka_work, nvmet_keep_alive_timer); memcpy(ctrl->hostnqn, args->hostnqn, NVMF_NQN_SIZE); + if (args->hostid) + uuid_copy(&ctrl->hostid, args->hostid); kref_init(&ctrl->ref); ctrl->subsys = subsys; @@ -1706,9 +1716,6 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) nvmet_start_keep_alive_timer(ctrl); - if (args->hostid) - uuid_copy(&ctrl->hostid, args->hostid); - dhchap_status = nvmet_setup_auth(ctrl, args->sq, false); if (dhchap_status) { pr_err("Failed to setup authentication, dhchap status %u\n", diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c index 92f8a76f1..dccdb55a3 100644 --- a/drivers/nvme/target/fabrics-cmd-auth.c +++ b/drivers/nvme/target/fabrics-cmd-auth.c @@ -427,7 +427,7 @@ static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al) struct nvmet_ctrl *ctrl = req->sq->ctrl; int ret = 0; int hash_len = nvme_auth_hmac_hash_len(ctrl->shash_id); - int data_size = sizeof(*d) + hash_len; + int data_size = sizeof(*data) + hash_len; if (ctrl->dh_tfm) data_size += ctrl->dh_keysize; diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index dbda55895..162e2fdd8 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -112,6 +112,8 @@ struct nvmet_ns { bool buffered_io; bool enabled; +#define NVMET_NS_IO_LIVE 0 + unsigned long flags; struct nvmet_subsys *subsys; const char *device_path; diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c index 9c2836743..c683450df 100644 --- a/drivers/nvme/target/pci-epf.c +++ b/drivers/nvme/target/pci-epf.c @@ -978,6 +978,9 @@ nvmet_pci_epf_get_sgl_segment(struct nvmet_pci_epf_ctrl *ctrl, int nr_descs, ret; void *buf; + if (length < sizeof(struct nvme_sgl_desc)) + return NULL; + buf = kmalloc(length, GFP_KERNEL); if (!buf) return NULL; |
