Author: loos
Date: Sat Feb 28 20:02:41 2015
New Revision: 279402
URL: https://svnweb.freebsd.org/changeset/base/279402

Log:
  Rename and move gpiobus_alloc_ivars() and gpiobus_free_ivars() so they can
  be used on non FDT systems.
  
  This prevents access to uninitialized memory on drivers that try to access
  pin flags on non FDT systems.

Modified:
  head/sys/dev/gpio/gpiobus.c
  head/sys/dev/gpio/gpiobusvar.h
  head/sys/dev/gpio/ofw_gpiobus.c

Modified: head/sys/dev/gpio/gpiobus.c
==============================================================================
--- head/sys/dev/gpio/gpiobus.c Sat Feb 28 19:57:22 2015        (r279401)
+++ head/sys/dev/gpio/gpiobus.c Sat Feb 28 20:02:41 2015        (r279402)
@@ -195,6 +195,39 @@ gpiobus_init_softc(device_t dev)
        return (0);
 }
 
+int
+gpiobus_alloc_ivars(struct gpiobus_ivar *devi)
+{
+
+       /* Allocate pins and flags memory. */
+       devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF,
+           M_NOWAIT | M_ZERO);
+       if (devi->pins == NULL)
+               return (ENOMEM);
+       devi->flags = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF,
+           M_NOWAIT | M_ZERO);
+       if (devi->flags == NULL) {
+               free(devi->pins, M_DEVBUF);
+               return (ENOMEM);
+       }
+
+       return (0);
+}
+
+void
+gpiobus_free_ivars(struct gpiobus_ivar *devi)
+{
+
+       if (devi->flags) {
+               free(devi->flags, M_DEVBUF);
+               devi->flags = NULL;
+       }
+       if (devi->pins) {
+               free(devi->pins, M_DEVBUF);
+               devi->pins = NULL;
+       }
+}
+
 static int
 gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask)
 {
@@ -206,29 +239,23 @@ gpiobus_parse_pins(struct gpiobus_softc 
                if (mask & (1 << i))
                        npins++;
        }
-
        if (npins == 0) {
                device_printf(child, "empty pin mask\n");
                return (EINVAL);
        }
-
        devi->npins = npins;
-       devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF, 
-           M_NOWAIT | M_ZERO);
-
-       if (!devi->pins)
-               return (ENOMEM);
-
+       if (gpiobus_alloc_ivars(devi) != 0) {
+               device_printf(child, "cannot allocate device ivars\n");
+               return (EINVAL);
+       }
        npins = 0;
        for (i = 0; i < 32; i++) {
-
                if ((mask & (1 << i)) == 0)
                        continue;
-
                if (i >= sc->sc_npins) {
                        device_printf(child, 
                            "invalid pin %d, max: %d\n", i, sc->sc_npins - 1);
-                       free(devi->pins, M_DEVBUF);
+                       gpiobus_free_ivars(devi);
                        return (EINVAL);
                }
 
@@ -239,7 +266,7 @@ gpiobus_parse_pins(struct gpiobus_softc 
                if (sc->sc_pins_mapped[i]) {
                        device_printf(child, 
                            "warning: pin %d is already mapped\n", i);
-                       free(devi->pins, M_DEVBUF);
+                       gpiobus_free_ivars(devi);
                        return (EINVAL);
                }
                sc->sc_pins_mapped[i] = 1;
@@ -299,10 +326,7 @@ gpiobus_detach(device_t dev)
        for (i = 0; i < ndevs; i++) {
                device_delete_child(dev, devlist[i]);
                devi = GPIOBUS_IVAR(devlist[i]);
-               if (devi->pins) {
-                       free(devi->pins, M_DEVBUF);
-                       devi->pins = NULL;
-               }
+               gpiobus_free_ivars(devi);
        }
        free(devlist, M_TEMP);
 

Modified: head/sys/dev/gpio/gpiobusvar.h
==============================================================================
--- head/sys/dev/gpio/gpiobusvar.h      Sat Feb 28 19:57:22 2015        
(r279401)
+++ head/sys/dev/gpio/gpiobusvar.h      Sat Feb 28 20:02:41 2015        
(r279402)
@@ -100,6 +100,8 @@ int gpio_check_flags(uint32_t, uint32_t)
 device_t gpiobus_attach_bus(device_t);
 int gpiobus_detach_bus(device_t);
 int gpiobus_init_softc(device_t);
+int gpiobus_alloc_ivars(struct gpiobus_ivar *);
+void gpiobus_free_ivars(struct gpiobus_ivar *);
 
 extern driver_t gpiobus_driver;
 

Modified: head/sys/dev/gpio/ofw_gpiobus.c
==============================================================================
--- head/sys/dev/gpio/ofw_gpiobus.c     Sat Feb 28 19:57:22 2015        
(r279401)
+++ head/sys/dev/gpio/ofw_gpiobus.c     Sat Feb 28 20:02:41 2015        
(r279402)
@@ -70,33 +70,6 @@ ofw_gpiobus_add_fdt_child(device_t bus, 
 }
 
 static int
-ofw_gpiobus_alloc_ivars(struct gpiobus_ivar *dinfo)
-{
-
-       /* Allocate pins and flags memory. */
-       dinfo->pins = malloc(sizeof(uint32_t) * dinfo->npins, M_DEVBUF,
-           M_NOWAIT | M_ZERO);
-       if (dinfo->pins == NULL)
-               return (ENOMEM);
-       dinfo->flags = malloc(sizeof(uint32_t) * dinfo->npins, M_DEVBUF,
-           M_NOWAIT | M_ZERO);
-       if (dinfo->flags == NULL) {
-               free(dinfo->pins, M_DEVBUF);
-               return (ENOMEM);
-       }
-
-       return (0);
-}
-
-static void
-ofw_gpiobus_free_ivars(struct gpiobus_ivar *dinfo)
-{
-
-       free(dinfo->flags, M_DEVBUF);
-       free(dinfo->pins, M_DEVBUF);
-}
-
-static int
 ofw_gpiobus_parse_gpios(struct gpiobus_softc *sc, struct gpiobus_ivar *dinfo,
        phandle_t child)
 {
@@ -152,7 +125,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
        }
 
        /* Allocate the child resources. */
-       if (ofw_gpiobus_alloc_ivars(dinfo) != 0) {
+       if (gpiobus_alloc_ivars(dinfo) != 0) {
                free(gpios, M_DEVBUF);
                return (ENOMEM);
        }
@@ -172,7 +145,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
                /* Read gpio-cells property for this GPIO controller. */
                if (OF_getencprop(gpio, "#gpio-cells", &cells,
                    sizeof(cells)) < 0) {
-                       ofw_gpiobus_free_ivars(dinfo);
+                       gpiobus_free_ivars(dinfo);
                        free(gpios, M_DEVBUF);
                        return (EINVAL);
                }
@@ -180,7 +153,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
                /* Get the GPIO pin number and flags. */
                if (gpio_map_gpios(sc->sc_dev, child, gpio, cells,
                    &gpios[i + 1], &dinfo->pins[j], &dinfo->flags[j]) != 0) {
-                       ofw_gpiobus_free_ivars(dinfo);
+                       gpiobus_free_ivars(dinfo);
                        free(gpios, M_DEVBUF);
                        return (EINVAL);
                }
@@ -190,7 +163,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
                        device_printf(sc->sc_busdev,
                            "invalid pin %d, max: %d\n",
                            dinfo->pins[j], sc->sc_npins - 1);
-                       ofw_gpiobus_free_ivars(dinfo);
+                       gpiobus_free_ivars(dinfo);
                        free(gpios, M_DEVBUF);
                        return (EINVAL);
                }
@@ -202,7 +175,7 @@ ofw_gpiobus_parse_gpios(struct gpiobus_s
                        device_printf(sc->sc_busdev,
                            "warning: pin %d is already mapped\n",
                            dinfo->pins[j]);
-                       ofw_gpiobus_free_ivars(dinfo);
+                       gpiobus_free_ivars(dinfo);
                        free(gpios, M_DEVBUF);
                        return (EINVAL);
                }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to