From e8447f70271fad637dabefb07d915920dc47bb21 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Sun, 13 Mar 2005 06:25:53 +0000 Subject: [PATCH] Fix a null pointer de-ref when passthrough ioctls are issued. This involves some code shuffle to avoid locking problems. MFC After: 3 days --- sys/dev/amr/amr.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c index 1600020c479..4fe9ba7aadc 100644 --- a/sys/dev/amr/amr.c +++ b/sys/dev/amr/amr.c @@ -471,11 +471,7 @@ amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t * /* handle inbound data buffer */ if (au_length != 0 && au_cmd[0] != 0x06) { - if ((dp = malloc(au_length, M_DEVBUF, M_WAITOK)) == NULL) - return(ENOMEM); - - if ((ap = malloc(sizeof(struct amr_passthrough ), M_DEVBUF, M_WAITOK)) == NULL) - return(ENOMEM); + dp = malloc(au_length, M_DEVBUF, M_WAITOK|M_ZERO); if ((error = copyin(au_buffer, dp, au_length)) != 0) { free(dp, M_DEVBUF); @@ -484,6 +480,10 @@ amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t * debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp); } + /* Allocate this now before the mutex gets held */ + if (au_cmd[0] == AMR_CMD_PASS) + ap = malloc(sizeof(struct amr_passthrough), M_DEVBUF, M_WAITOK|M_ZERO); + mtx_lock(&sc->amr_io_lock); if ((ac = amr_alloccmd(sc)) == NULL) { error = ENOMEM; @@ -563,10 +563,13 @@ out: * At this point, we know that there is a lock held and that these * objects have been allocated. */ - free(dp, M_DEVBUF); - free(ap, M_DEVBUF); - amr_releasecmd(ac); + if (ac != NULL) + amr_releasecmd(ac); mtx_unlock(&sc->amr_io_lock); + if (dp != NULL) + free(dp, M_DEVBUF); + if (ap != NULL) + free(ap, M_DEVBUF); return(error); }