From owner-svn-src-head@FreeBSD.ORG Sat Feb 28 20:02:44 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1FE0AED1; Sat, 28 Feb 2015 20:02:44 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 005BF166; Sat, 28 Feb 2015 20:02:44 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1SK2h3M057429; Sat, 28 Feb 2015 20:02:43 GMT (envelope-from loos@FreeBSD.org) Received: (from loos@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1SK2g2A057426; Sat, 28 Feb 2015 20:02:42 GMT (envelope-from loos@FreeBSD.org) Message-Id: <201502282002.t1SK2g2A057426@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: loos set sender to loos@FreeBSD.org using -f From: Luiz Otavio O Souza Date: Sat, 28 Feb 2015 20:02:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r279402 - head/sys/dev/gpio X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Feb 2015 20:02:44 -0000 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); }