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:
parent
7da6777fea
commit
4d55eb47b4
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user