Re: [PATCH] EDAC/i3000: Fix mci_pdev reference leak in i3000_init_one()
From: Borislav Petkov
Date: Sat Sep 19 2026 - 01:36:48 EST
On Wed, Sep 16, 2026 at 02:53:02PM +0000, Leo Zhuo wrote:
> > From: Wentao Liang <vulab@xxxxxxxxxxx>
> > Sent: Wednesday, September 16, 2026 5:14 PM
> > To: akpm@xxxxxxxxxxxxxxxxxxxx
> > Cc: bp@xxxxxxxxx; dougthompson@xxxxxxxxxxxx; juhlenko@xxxxxxxxxx; linux-
> > edac@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; tony.luck@xxxxxxxxx; Wentao
> > Liang <vulab@xxxxxxxxxxx>; stable@xxxxxxxxxxxxxxx
> > Subject: [PATCH] EDAC/i3000: Fix mci_pdev reference leak in i3000_init_one()
> >
> >
> > In i3000_init_one(), a reference to the PCI device is taken with
> > pci_dev_get() and stored in the global mci_pdev even when
> > i3000_probe1() fails. On that path i3000_registered keeps its initial value of 1, so
> > i3000_exit() skips the pci_dev_put() and the reference is leaked.
> >
> > Only take the reference after i3000_probe1() succeeds.
> >
> > Fixes: 535c6a53035d ("drivers/edac: new inte 30x0 MC driver")
> > Cc: stable@xxxxxxxxxxxxxxx
> > Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
> > ---
> > drivers/edac/i3000_edac.c | 5 ++++-
> > 1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c index
> > 9065bc4386ff..d4ee6e185c80 100644
> > --- a/drivers/edac/i3000_edac.c
> > +++ b/drivers/edac/i3000_edac.c
> > @@ -461,10 +461,13 @@ static int i3000_init_one(struct pci_dev *pdev, const
> > struct pci_device_id *ent)
> > return -EIO;
> >
> > rc = i3000_probe1(pdev, ent->driver_data);
> > + if (rc)
> > + return rc;
> > +
> > if (!mci_pdev)
> > mci_pdev = pci_dev_get(pdev);
> >
> > - return rc;
> > + return 0;
>
> For a successful normal probe() and exit() path,
> the extra mci_pdev reference is not released because i3200_exit() skips pci_dev_put().
> How about the following fix:
>
> diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
> index d600b6c05217..ddfbbbbf8147 100644
> --- a/drivers/edac/i3200_edac.c
> +++ b/drivers/edac/i3200_edac.c
> @@ -439,10 +439,13 @@ static int i3200_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> return -EIO;
>
> rc = i3200_probe1(pdev, ent->driver_data);
> + if (rc)
> + return rc;
> +
> if (!mci_pdev)
> mci_pdev = pci_dev_get(pdev);
>
> - return rc;
> + return 0;
> }
>
> static void i3200_remove_one(struct pci_dev *pdev)
> @@ -529,10 +532,10 @@ static void __exit i3200_exit(void)
> edac_dbg(3, "MC:\n");
>
> pci_unregister_driver(&i3200_driver);
> - if (!i3200_registered) {
> + if (!i3200_registered)
> i3200_remove_one(mci_pdev);
> - pci_dev_put(mci_pdev);
> - }
> +
> + pci_dev_put(mci_pdev);
> }
>
> module_init(i3200_init);
$ ./scripts/get_maintainer.pl -f drivers/edac/i3000_edac.c
...
EDAC-I3000 status: Orphan
No need to fix anything here.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette