diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-30 20:52:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-30 20:52:08 -0700 |
commit | 47d154eb2ac4e508555937207031ba062119e371 (patch) | |
tree | 791a1e38a56f893dae48f9b2f5dc93d2b9876686 /drivers/nvdimm/pfn_devs.c | |
parent | 4debf77169ee459c46ec70e13dc503bc25efd7d2 (diff) | |
parent | 08ca6906a4b7e48f8e93b7c1f49a742a415be6d5 (diff) |
Merge tag 'libnvdimm-for-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull nvdimm updates from Dave Jiang:
"This is mostly small cleanups, fixes, and with a change to prevent
zero-sized namespace exposed to user for nvdimm.
Summary:
- kstrtobool() conversion for nvdimm
- Add REQ_OP_WRITE for virtio_pmem
- Header files update for of_pmem
- Restrict zero-sized namespace from being exposed to user
- Avoid unnecessary endian conversion
- Fix mem leak in nvdimm pmu
- Fix dereference after free in nvdimm pmu"
* tag 'libnvdimm-for-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
nvdimm: Fix dereference after free in register_nvdimm_pmu()
nvdimm: Fix memleak of pmu attr_groups in unregister_nvdimm_pmu()
nvdimm/pfn_dev: Avoid unnecessary endian conversion
nvdimm/pfn_dev: Prevent the creation of zero-sized namespaces
nvdimm: Explicitly include correct DT includes
virtio_pmem: add the missing REQ_OP_WRITE for flush bio
nvdimm: Use kstrtobool() instead of strtobool()
Diffstat (limited to 'drivers/nvdimm/pfn_devs.c')
-rw-r--r-- | drivers/nvdimm/pfn_devs.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 18ad315581ca..0d08e21a1cea 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -452,8 +452,9 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) u64 checksum, offset; struct resource *res; enum nd_pfn_mode mode; + resource_size_t res_size; struct nd_namespace_io *nsio; - unsigned long align, start_pad; + unsigned long align, start_pad, end_trunc; struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; struct nd_namespace_common *ndns = nd_pfn->ndns; const uuid_t *parent_uuid = nd_dev_to_uuid(&ndns->dev); @@ -503,6 +504,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) align = le32_to_cpu(pfn_sb->align); offset = le64_to_cpu(pfn_sb->dataoff); start_pad = le32_to_cpu(pfn_sb->start_pad); + end_trunc = le32_to_cpu(pfn_sb->end_trunc); if (align == 0) align = 1UL << ilog2(offset); mode = le32_to_cpu(pfn_sb->mode); @@ -584,7 +586,8 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) */ nsio = to_nd_namespace_io(&ndns->dev); res = &nsio->res; - if (offset >= resource_size(res)) { + res_size = resource_size(res); + if (offset >= res_size) { dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n", dev_name(&ndns->dev)); return -EOPNOTSUPP; @@ -598,18 +601,20 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) return -EOPNOTSUPP; } - if (!IS_ALIGNED(res->start + le32_to_cpu(pfn_sb->start_pad), - memremap_compat_align())) { + if (!IS_ALIGNED(res->start + start_pad, memremap_compat_align())) { dev_err(&nd_pfn->dev, "resource start misaligned\n"); return -EOPNOTSUPP; } - if (!IS_ALIGNED(res->end + 1 - le32_to_cpu(pfn_sb->end_trunc), - memremap_compat_align())) { + if (!IS_ALIGNED(res->end + 1 - end_trunc, memremap_compat_align())) { dev_err(&nd_pfn->dev, "resource end misaligned\n"); return -EOPNOTSUPP; } + if (offset >= (res_size - start_pad - end_trunc)) { + dev_err(&nd_pfn->dev, "bad offset with small namespace\n"); + return -EOPNOTSUPP; + } return 0; } EXPORT_SYMBOL(nd_pfn_validate); @@ -810,7 +815,8 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) else return -ENXIO; - if (offset >= size) { + if (offset >= (size - end_trunc)) { + /* This results in zero size devices */ dev_err(&nd_pfn->dev, "%s unable to satisfy requested alignment\n", dev_name(&ndns->dev)); return -ENXIO; |