Date: Wed, 1 Oct 2025 09:38:55 GMT From: Ahmad Khalifa <vexeduxr@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 6163ced966b4 - stable/14 - gpioc: fix race in ioctl(GPIOCONFIGEVENTS) Message-ID: <202510010938.5919ct0L016624@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by vexeduxr: URL: https://cgit.FreeBSD.org/src/commit/?id=6163ced966b4e37a987e514aa2d2a61781c98fa5 commit 6163ced966b4e37a987e514aa2d2a61781c98fa5 Author: Ahmad Khalifa <vexeduxr@FreeBSD.org> AuthorDate: 2025-09-30 11:09:50 +0000 Commit: Ahmad Khalifa <vexeduxr@FreeBSD.org> CommitDate: 2025-10-01 09:08:55 +0000 gpioc: fix race in ioctl(GPIOCONFIGEVENTS) A race can occur in gpioc_ioctl when it is called with GPIOCONFIGEVENTS closely followed by GPIOSETCONFIG. GPIOSETCONFIG can alter the priv->pins list, making it no longer empty and opening the door for access to priv->events while we are reallocating it. Fix this by holding priv->mtx while handling GPIOCONFIGEVENTS. Reported by: Qiu-ji Chen PR: 289120 Reviewed by: mmel MFC after: 1 day Differential Revision: https://reviews.freebsd.org/D52783 (cherry picked from commit d000adfe41e6f2fe8f3dbe92d8fc2d34ae882086) --- sys/dev/gpio/gpioc.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/sys/dev/gpio/gpioc.c b/sys/dev/gpio/gpioc.c index a3595c849a21..45757854b938 100644 --- a/sys/dev/gpio/gpioc.c +++ b/sys/dev/gpio/gpioc.c @@ -783,6 +783,7 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, struct gpio_access_32 *a32; struct gpio_config_32 *c32; struct gpio_event_config *evcfg; + struct gpioc_pin_event *tmp; uint32_t caps, intrflags; bus = GPIO_GET_BUS(sc->sc_pdev); @@ -892,27 +893,35 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, res = devfs_get_cdevpriv((void **)&priv); if (res != 0) break; - /* If any pins have been configured, changes aren't allowed. */ - if (!SLIST_EMPTY(&priv->pins)) { - res = EINVAL; - break; - } if (evcfg->gp_report_type != GPIO_EVENT_REPORT_DETAIL && evcfg->gp_report_type != GPIO_EVENT_REPORT_SUMMARY) { res = EINVAL; break; } - priv->report_option = evcfg->gp_report_type; /* Reallocate the events buffer if the user wants it bigger. */ - if (priv->report_option == GPIO_EVENT_REPORT_DETAIL && + tmp = NULL; + if (evcfg->gp_report_type == GPIO_EVENT_REPORT_DETAIL && priv->numevents < evcfg->gp_fifo_size) { - free(priv->events, M_GPIOC); - priv->numevents = evcfg->gp_fifo_size; - priv->events = malloc(priv->numevents * + tmp = malloc(priv->numevents * sizeof(struct gpioc_pin_event), M_GPIOC, M_WAITOK | M_ZERO); + } + mtx_lock(&priv->mtx); + /* If any pins have been configured, changes aren't allowed. */ + if (!SLIST_EMPTY(&priv->pins)) { + mtx_unlock(&priv->mtx); + free(tmp, M_GPIOC); + res = EINVAL; + break; + } + if (tmp != NULL) { + free(priv->events, M_GPIOC); + priv->events = tmp; + priv->numevents = evcfg->gp_fifo_size; priv->evidx_head = priv->evidx_tail = 0; } + priv->report_option = evcfg->gp_report_type; + mtx_unlock(&priv->mtx); break; case FIONBIO: /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202510010938.5919ct0L016624>