Fix a null pointer de-ref when passthrough ioctls are issued. This

involves some code shuffle to avoid locking problems.

MFC After: 3 days
This commit is contained in:
scottl 2005-03-13 06:25:53 +00:00
parent 7da6777fea
commit 4d55eb47b4

View File

@ -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 @@ amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *
* 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);
}