Commit b982df72 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'edac_urgent_for_5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC fixes from Borislav Petkov:
 "Two fixes for use-after-free and memory leaking in the EDAC core, by
  Robert Richter.

  Debug options like DEBUG_TEST_DRIVER_REMOVE, KASAN and DEBUG_KMEMLEAK
  unearthed issues with the lifespan of memory allocated by the EDAC
  memory controller descriptor due to misdesigned memory freeing, done
  partially by the EDAC core *and* the driver core, which is problematic
  to say the least.

  These two are minimal fixes to take care of stable - a proper rework
  is following which cleans up that mess properly"

* tag 'edac_urgent_for_5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
  EDAC/sysfs: Remove csrow objects on errors
  EDAC/mc: Fix use-after-free and memleaks during device removal
parents e29c6a13 4d59588c
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -505,16 +505,10 @@ void edac_mc_free(struct mem_ctl_info *mci)
{
	edac_dbg(1, "\n");

	/* If we're not yet registered with sysfs free only what was allocated
	 * in edac_mc_alloc().
	 */
	if (!device_is_registered(&mci->dev)) {
		_edac_mc_free(mci);
		return;
	}

	/* the mci instance is freed here, when the sysfs object is dropped */
	if (device_is_registered(&mci->dev))
		edac_unregister_sysfs(mci);

	_edac_mc_free(mci);
}
EXPORT_SYMBOL_GPL(edac_mc_free);

+4 −14
Original line number Diff line number Diff line
@@ -276,10 +276,7 @@ static const struct attribute_group *csrow_attr_groups[] = {

static void csrow_attr_release(struct device *dev)
{
	struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);

	edac_dbg(1, "device %s released\n", dev_name(dev));
	kfree(csrow);
	/* release device with _edac_mc_free() */
}

static const struct device_type csrow_attr_type = {
@@ -447,8 +444,7 @@ error:
		csrow = mci->csrows[i];
		if (!nr_pages_per_csrow(csrow))
			continue;

		device_del(&mci->csrows[i]->dev);
		device_unregister(&mci->csrows[i]->dev);
	}

	return err;
@@ -608,10 +604,7 @@ static const struct attribute_group *dimm_attr_groups[] = {

static void dimm_attr_release(struct device *dev)
{
	struct dimm_info *dimm = container_of(dev, struct dimm_info, dev);

	edac_dbg(1, "device %s released\n", dev_name(dev));
	kfree(dimm);
	/* release device with _edac_mc_free() */
}

static const struct device_type dimm_attr_type = {
@@ -893,10 +886,7 @@ static const struct attribute_group *mci_attr_groups[] = {

static void mci_attr_release(struct device *dev)
{
	struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);

	edac_dbg(1, "device %s released\n", dev_name(dev));
	kfree(mci);
	/* release device with _edac_mc_free() */
}

static const struct device_type mci_attr_type = {