Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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()

+26 -15
+2 -1
drivers/nvdimm/namespace_devs.c
··· 2 2 /* 3 3 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. 4 4 */ 5 + #include <linux/kstrtox.h> 5 6 #include <linux/module.h> 6 7 #include <linux/device.h> 7 8 #include <linux/sort.h> ··· 1339 1338 struct device_attribute *attr, const char *buf, size_t len) 1340 1339 { 1341 1340 bool force_raw; 1342 - int rc = strtobool(buf, &force_raw); 1341 + int rc = kstrtobool(buf, &force_raw); 1343 1342 1344 1343 if (rc) 1345 1344 return rc;
+2 -1
drivers/nvdimm/nd_perf.c
··· 308 308 309 309 rc = perf_pmu_register(&nd_pmu->pmu, nd_pmu->pmu.name, -1); 310 310 if (rc) { 311 - kfree(nd_pmu->pmu.attr_groups); 312 311 nvdimm_pmu_free_hotplug_memory(nd_pmu); 312 + kfree(nd_pmu->pmu.attr_groups); 313 313 return rc; 314 314 } 315 315 ··· 324 324 { 325 325 perf_pmu_unregister(&nd_pmu->pmu); 326 326 nvdimm_pmu_free_hotplug_memory(nd_pmu); 327 + kfree(nd_pmu->pmu.attr_groups); 327 328 kfree(nd_pmu); 328 329 } 329 330 EXPORT_SYMBOL_GPL(unregister_nvdimm_pmu);
+2 -1
drivers/nvdimm/nd_virtio.c
··· 105 105 * parent bio. Otherwise directly call nd_region flush. 106 106 */ 107 107 if (bio && bio->bi_iter.bi_sector != -1) { 108 - struct bio *child = bio_alloc(bio->bi_bdev, 0, REQ_PREFLUSH, 108 + struct bio *child = bio_alloc(bio->bi_bdev, 0, 109 + REQ_OP_WRITE | REQ_PREFLUSH, 109 110 GFP_ATOMIC); 110 111 111 112 if (!child)
+2 -2
drivers/nvdimm/of_pmem.c
··· 2 2 3 3 #define pr_fmt(fmt) "of_pmem: " fmt 4 4 5 - #include <linux/of_platform.h> 6 - #include <linux/of_address.h> 5 + #include <linux/of.h> 7 6 #include <linux/libnvdimm.h> 8 7 #include <linux/module.h> 9 8 #include <linux/ioport.h> 9 + #include <linux/platform_device.h> 10 10 #include <linux/slab.h> 11 11 12 12 struct of_pmem_private {
+13 -7
drivers/nvdimm/pfn_devs.c
··· 452 452 u64 checksum, offset; 453 453 struct resource *res; 454 454 enum nd_pfn_mode mode; 455 + resource_size_t res_size; 455 456 struct nd_namespace_io *nsio; 456 - unsigned long align, start_pad; 457 + unsigned long align, start_pad, end_trunc; 457 458 struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; 458 459 struct nd_namespace_common *ndns = nd_pfn->ndns; 459 460 const uuid_t *parent_uuid = nd_dev_to_uuid(&ndns->dev); ··· 504 503 align = le32_to_cpu(pfn_sb->align); 505 504 offset = le64_to_cpu(pfn_sb->dataoff); 506 505 start_pad = le32_to_cpu(pfn_sb->start_pad); 506 + end_trunc = le32_to_cpu(pfn_sb->end_trunc); 507 507 if (align == 0) 508 508 align = 1UL << ilog2(offset); 509 509 mode = le32_to_cpu(pfn_sb->mode); ··· 586 584 */ 587 585 nsio = to_nd_namespace_io(&ndns->dev); 588 586 res = &nsio->res; 589 - if (offset >= resource_size(res)) { 587 + res_size = resource_size(res); 588 + if (offset >= res_size) { 590 589 dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n", 591 590 dev_name(&ndns->dev)); 592 591 return -EOPNOTSUPP; ··· 601 598 return -EOPNOTSUPP; 602 599 } 603 600 604 - if (!IS_ALIGNED(res->start + le32_to_cpu(pfn_sb->start_pad), 605 - memremap_compat_align())) { 601 + if (!IS_ALIGNED(res->start + start_pad, memremap_compat_align())) { 606 602 dev_err(&nd_pfn->dev, "resource start misaligned\n"); 607 603 return -EOPNOTSUPP; 608 604 } 609 605 610 - if (!IS_ALIGNED(res->end + 1 - le32_to_cpu(pfn_sb->end_trunc), 611 - memremap_compat_align())) { 606 + if (!IS_ALIGNED(res->end + 1 - end_trunc, memremap_compat_align())) { 612 607 dev_err(&nd_pfn->dev, "resource end misaligned\n"); 613 608 return -EOPNOTSUPP; 614 609 } 615 610 611 + if (offset >= (res_size - start_pad - end_trunc)) { 612 + dev_err(&nd_pfn->dev, "bad offset with small namespace\n"); 613 + return -EOPNOTSUPP; 614 + } 616 615 return 0; 617 616 } 618 617 EXPORT_SYMBOL(nd_pfn_validate); ··· 815 810 else 816 811 return -ENXIO; 817 812 818 - if (offset >= size) { 813 + if (offset >= (size - end_trunc)) { 814 + /* This results in zero size devices */ 819 815 dev_err(&nd_pfn->dev, "%s unable to satisfy requested alignment\n", 820 816 dev_name(&ndns->dev)); 821 817 return -ENXIO;
+2 -1
drivers/nvdimm/pmem.c
··· 17 17 #include <linux/moduleparam.h> 18 18 #include <linux/badblocks.h> 19 19 #include <linux/memremap.h> 20 + #include <linux/kstrtox.h> 20 21 #include <linux/vmalloc.h> 21 22 #include <linux/blk-mq.h> 22 23 #include <linux/pfn_t.h> ··· 386 385 bool write_cache; 387 386 int rc; 388 387 389 - rc = strtobool(buf, &write_cache); 388 + rc = kstrtobool(buf, &write_cache); 390 389 if (rc) 391 390 return rc; 392 391 dax_write_cache(pmem->dax_dev, write_cache);
+3 -2
drivers/nvdimm/region_devs.c
··· 5 5 #include <linux/scatterlist.h> 6 6 #include <linux/memregion.h> 7 7 #include <linux/highmem.h> 8 + #include <linux/kstrtox.h> 8 9 #include <linux/sched.h> 9 10 #include <linux/slab.h> 10 11 #include <linux/hash.h> ··· 276 275 const char *buf, size_t len) 277 276 { 278 277 bool flush; 279 - int rc = strtobool(buf, &flush); 278 + int rc = kstrtobool(buf, &flush); 280 279 struct nd_region *nd_region = to_nd_region(dev); 281 280 282 281 if (rc) ··· 531 530 struct device_attribute *attr, const char *buf, size_t len) 532 531 { 533 532 bool ro; 534 - int rc = strtobool(buf, &ro); 533 + int rc = kstrtobool(buf, &ro); 535 534 struct nd_region *nd_region = to_nd_region(dev); 536 535 537 536 if (rc)