1. 17 Feb, 2023 1 commit
    • Dan Williams's avatar
      dax/kmem: Fix leak of memory-hotplug resources · e686c325
      Dan Williams authored
      While experimenting with CXL region removal the following corruption of
      /proc/iomem appeared.
      
      Before:
      f010000000-f04fffffff : CXL Window 0
        f010000000-f02fffffff : region4
          f010000000-f02fffffff : dax4.0
            f010000000-f02fffffff : System RAM (kmem)
      
      After (modprobe -r cxl_test):
      f010000000-f02fffffff : **redacted binary garbage**
        f010000000-f02fffffff : System RAM (kmem)
      
      ...and testing further the same is visible with persistent memory
      assigned to kmem:
      
      Before:
      480000000-243fffffff : Persistent Memory
        480000000-57e1fffff : namespace3.0
        580000000-243fffffff : dax3.0
          580000000-243fffffff : System RAM (kmem)
      
      After (ndctl disable-region all):
      480000000-243fffffff : Persistent Memory
        580000000-243fffffff : ***redacted binary garbage***
          580000000-243fffffff : System RAM (kmem)
      
      The corrupted data is from a use-after-free of the "dax4.0" and "dax3.0"
      resources, and it also shows that the "System RAM (kmem)" resource is
      not being removed. The bug does not appear after "modprobe -r kmem", it
      requires the parent of "dax4.0" and "dax3.0" to be removed which
      re-parents the leaked "System RAM (kmem)" instances. Those in turn
      reference the freed resource as a parent.
      
      First up for the fix is release_mem_region_adjustable() needs to
      reliably delete the resource inserted by add_memory_driver_managed().
      That is thwarted by a check for IORESOURCE_SYSRAM that predates the
      dax/kmem driver, from commit:
      
      65c78784 ("kernel, resource: check for IORESOURCE_SYSRAM in release_mem_region_adjustable")
      
      That appears to be working around the behavior of HMM's
      "MEMORY_DEVICE_PUBLIC" facility that has since been deleted. With that
      check removed the "System RAM (kmem)" resource gets removed, but
      corruption still occurs occasionally because the "dax" resource is not
      reliably removed.
      
      The dax range information is freed before the device is unregistered, so
      the driver can not reliably recall (another use after free) what it is
      meant to release. Lastly if that use after free got lucky, the driver
      was covering up the leak of "System RAM (kmem)" due to its use of
      release_resource() which detaches, but does not free, child resources.
      The switch to remove_resource() forces remove_memory() to be responsible
      for the deletion of the resource added by add_memory_driver_managed().
      
      Fixes: c2f3011e ("device-dax: add an allocation interface for device-dax instances")
      Cc: <stable@vger.kernel.org>
      Cc: Oscar Salvador <osalvador@suse.de>
      Cc: David Hildenbrand <david@redhat.com>
      Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
      Reviewed-by: default avatarVishal Verma <vishal.l.verma@intel.com>
      Reviewed-by: default avatarPasha Tatashin <pasha.tatashin@soleen.com>
      Reviewed-by: default avatarDave Jiang <dave.jiang@intel.com>
      Link: https://lore.kernel.org/r/167653656244.3147810.5705900882794040229.stgit@dwillia2-xfh.jf.intel.comSigned-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      e686c325
  2. 16 Feb, 2023 5 commits
  3. 15 Feb, 2023 1 commit
  4. 14 Feb, 2023 15 commits
  5. 11 Feb, 2023 18 commits