Message ID | 20191014171919.85044-3-james.morse@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | EDAC, ghes: Fix use after free and add reference | expand |
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index 955b59b6aade..0bb62857ffb2 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -553,6 +553,9 @@ void ghes_edac_unregister(struct ghes *ghes) if (!ghes_pvt) return; + if (atomic_dec_return(&ghes_init)) + return; + mci = ghes_pvt->mci; ghes_pvt = NULL; edac_mc_del_mc(mci->pdev);
ghes_edac only does work for the first GHES entry that registers it. The same is true for unregister: first come first served. This lack of symmetry is problematic if we have more than one GHES entry, as ghes_edac_register() can only be called once, nothing decrements ghes_init. Doing the unregister work on the first call is unsafe, as another CPU may be processing a notification in ghes_edac_report_mem_error(), using the memory we are about to free. ghes_init is already half of the reference counting. We only need to do the register work for the first call, and the unregister work for the last. Add the unregister check. This means we no longer free ghes_edac's memory while there are GHES entries that may receive a notification. Signed-off-by: James Morse <james.morse@arm.com> Fixes: 0fe5f281f749 ("EDAC, ghes: Model a single, logical memory controller") --- drivers/edac/ghes_edac.c | 3 +++ 1 file changed, 3 insertions(+)