On Thu, May 09, 2019 at 10:12:49AM +0200, Hrvoje Popovski wrote:
> Hi all,
> 
> i update kernel from cvs few minutes ago and i'm seeing this stack trace
> in dmesg. i'm just reporting it.

The principe of the game is to look at the free() call that still use 0
as size, and found the right size to fill it.

> free with zero size: (2)
> Starting stack trace...
> free(ffff800000074100,2,0,ffff800000074100,1d5a05b47900fbf4,ffffffff81d287e8) 
> at free+0xd8
> isascan(ffff800000101200,ffff800000074100,9563e4d9af15796a,ffffffff81618690,ffff800000101200,ffffffff81d16d01)
>  at isascan+0x3f8

Here, isascan() calls free() on dev (a struct device).

the related malloc() call is done by config_make_softc() at line 248:
   247                          config_attach(parent, dev, &ia2, isaprint);
   248                          dev = config_make_softc(parent, cf);

The size used for malloc() is :

kern/subr_autoconf.c
   417  struct device *
   418  config_make_softc(struct device *parent, struct cfdata *cf)
   419  {
   420          struct device *dev;
   421          struct cfdriver *cd;
   422          struct cfattach *ca;
   423
   424          cd = cf->cf_driver;
   425          ca = cf->cf_attach;
   426          if (ca->ca_devsize < sizeof(struct device))
   427                  panic("config_make_softc");
   428
   429          /* get memory for all device vars */
   430          dev = malloc(ca->ca_devsize, M_DEVBUF, M_NOWAIT|M_ZERO);
   431          if (dev == NULL)
   432                  panic("config_make_softc: allocation for device softc 
failed");


So calling free() with cf->cf_attach->ca_devsize should be fine.
Diff below.

OK ?
-- 
Sebastien Marie

Index: dev/isa/isa.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/isa.c,v
retrieving revision 1.46
diff -u -p -r1.46 isa.c
--- dev/isa/isa.c       25 May 2015 15:19:22 -0000      1.46
+++ dev/isa/isa.c       9 May 2019 08:28:47 -0000
@@ -257,7 +257,7 @@ isascan(parent, match)
                if (autoconf_verbose)
                        printf(">>> probing for %s* finished\n",
                            cf->cf_driver->cd_name);
-               free(dev, M_DEVBUF, 0);
+               free(dev, M_DEVBUF, cf->cf_attach->ca_devsize);
                return;
        }
 
@@ -270,7 +270,7 @@ isascan(parent, match)
                    !isa_intr_check(sc->sc_ic, ia.ia_irq, IST_EDGE)) {
                        printf("%s%d: irq %d already in use\n",
                            cf->cf_driver->cd_name, cf->cf_unit, ia.ia_irq);
-                       free(dev, M_DEVBUF, 0);
+                       free(dev, M_DEVBUF, cf->cf_attach->ca_devsize);
                } else {
 #endif
                        if (autoconf_verbose)
@@ -291,7 +291,7 @@ isascan(parent, match)
                if (autoconf_verbose)
                        printf(">>> probing for %s%d failed\n",
                            cf->cf_driver->cd_name, cf->cf_unit);
-               free(dev, M_DEVBUF, 0);
+               free(dev, M_DEVBUF, cf->cf_attach->ca_devsize);
        }
 }
 

Reply via email to