linux/drivers/edac
Fengguang Wu ef6e7816b4 edac_mc: fix messy kfree calls in the error path
coccinelle warns about:

+ drivers/edac/edac_mc.c:429:9-23: ERROR: reference preceded by free on line 429

   421         if (mci->csrows) {
 > 422                 for (chn = 0; chn < tot_channels; chn++) {
   423                         csr = mci->csrows[chn];
   424                         if (csr) {
 > 425                                 for (chn = 0; chn < tot_channels; chn++)
   426                                          kfree(csr->channels[chn]);
   427                                  kfree(csr);
   428                          }
 > 429                          kfree(mci->csrows[i]);
   430                  }
   431                  kfree(mci->csrows);
   432          }

and that code block seem to mess things up in several ways (double free, memory
leak, out-of-bound reads etc.):

L422: The iterator "chn" and bound "tot_channels" are totally wrong. Should be
      "row" and "tot_csrows" respectively. Which means either memory leak, or
      out-of-bound reads (which if does not trigger an immediate page fault
      error, will further lead to kfree() on random addresses).

L425: The inner loop is reusing the same iterator "chn" as the outer loop,
      which could lead to premature end of the outer loop, and hence memory leak.

L429: The array index 'i' in mci->csrows[i] is a temporary value used in
      previous loops, and won't change at all in the current loop. Which
      means either out-of-bound read and possibly kfree(random number), or the
      same mci->csrows[i] get freed once and again, and possibly double free
      for the kfree(csr) in L427.

L426/L427: a kfree(csr->channels) is needed in between to avoid leaking the memory.

The buggy code was introduced by commit de3910eb ("edac: change the mem
allocation scheme to make Documentation/kobject.txt happy") in the 3.6-rc1
merge window. Fix it by freeing up resources in this order:

  free csrows[i]->channels[j]
  free csrows[i]->channels
  free csrows[i]
  free csrows

CC: Mauro Carvalho Chehab <mchehab@redhat.com>
CC: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-09-23 14:45:26 -07:00
..
amd64_edac_dbg.c amd64_edac: convert sysfs logic to use struct device 2012-06-11 13:23:40 -03:00
amd64_edac_inj.c edac: Convert debugfX to edac_dbg(X, 2012-06-11 13:23:49 -03:00
amd64_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
amd64_edac.h amd64_edac: convert sysfs logic to use struct device 2012-06-11 13:23:40 -03:00
amd76x_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
amd8111_edac.c edac: Drop __DATE__ usage 2011-04-19 00:23:22 +02:00
amd8111_edac.h edac: AMD8111 driver header file 2009-04-02 19:05:03 -07:00
amd8131_edac.c edac: Drop __DATE__ usage 2011-04-19 00:23:22 +02:00
amd8131_edac.h tree-wide: fix comment/printk typos 2010-11-01 15:38:34 -04:00
cell_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
cpc925_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
e7xxx_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
e752x_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
edac_core.h Merge branch 'devel' 2012-07-29 21:11:05 -03:00
edac_device_sysfs.c edac: Convert debugfX to edac_dbg(X, 2012-06-11 13:23:49 -03:00
edac_device.c Merge branch 'devel' 2012-07-29 21:11:05 -03:00
edac_mc_sysfs.c edac: allow specifying the error count with fake_inject 2012-06-27 09:01:30 -03:00
edac_mc.c edac_mc: fix messy kfree calls in the error path 2012-09-23 14:45:26 -07:00
edac_module.c edac: create top-level debugfs directory 2012-06-12 12:15:49 -03:00
edac_module.h edac: create top-level debugfs directory 2012-06-12 12:15:49 -03:00
edac_pci_sysfs.c edac: Convert debugfX to edac_dbg(X, 2012-06-11 13:23:49 -03:00
edac_pci.c edac: Convert debugfX to edac_dbg(X, 2012-06-11 13:23:49 -03:00
edac_stub.c device.h: cleanup users outside of linux/include (C files) 2012-03-11 14:27:37 -04:00
highbank_l2_edac.c edac: add support for Calxeda highbank L2 cache ecc 2012-06-27 09:01:29 -03:00
highbank_mc_edac.c edac: add support for Calxeda highbank memory controller 2012-06-27 09:00:57 -03:00
i7core_edac.c Merge branch 'devel' 2012-07-29 21:11:05 -03:00
i3000_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
i3200_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
i5000_edac.c edac i5000, i5400: fix pointer math in i5000_get_mc_regs() 2012-06-27 09:08:40 -03:00
i5100_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
i5400_edac.c edac i5000, i5400: fix pointer math in i5000_get_mc_regs() 2012-06-27 09:08:40 -03:00
i7300_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
i82443bxgx_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
i82860_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
i82875p_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
i82975x_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
Kconfig edac: add support for Calxeda highbank L2 cache ecc 2012-06-27 09:01:29 -03:00
Makefile edac: add support for Calxeda highbank L2 cache ecc 2012-06-27 09:01:29 -03:00
mce_amd_inj.c device.h: cleanup users outside of linux/include (C files) 2012-03-11 14:27:37 -04:00
mce_amd.c MCE, AMD: Drop too granulary family model checks 2012-04-04 15:50:11 +02:00
mce_amd.h x86/bitops: Move BIT_64() for a wider use 2012-05-23 17:16:42 +02:00
mpc85xx_edac.c Merge branch 'devel' 2012-07-29 21:11:05 -03:00
mpc85xx_edac.h edac: Drop __DATE__ usage 2011-04-19 00:23:22 +02:00
mv64x60_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
mv64x60_edac.h edac: Drop __DATE__ usage 2011-04-19 00:23:22 +02:00
pasemi_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
ppc4xx_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
ppc4xx_edac.h edac: new ppc4xx driver module 2009-04-02 19:05:03 -07:00
r82600_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
sb_edac.c Merge branch 'devel' 2012-07-29 21:11:05 -03:00
tile_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00
x38_edac.c edac: edac_mc_handle_error(): add an error_count parameter 2012-06-12 12:15:47 -03:00