mpr/mps/mpt: verify cfg page ioctl lengths
*_CFG_PAGE ioctl handlers in the mpr, mps, and mpt drivers allocated a buffer of a caller-specified size, but copied to it a fixed size header. Add checks that the size is at least the required minimum. Note that the device nodes are owned by root:operator with 0640 permissions so the ioctls are not available to unprivileged users. This change includes suggestions from scottl, markj and mav. Two of the mpt cases were reported by Lucas Leong (@_wmliang_) of Trend Micro Zero Day Initiative; scottl reported the third case in mpt. Same issue found in mpr and mps after discussion with imp. Reported by: Lucas Leong (@_wmliang_), Trend Micro Zero Day Initiative Reviewed by: imp, mav MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34692
This commit is contained in:
parent
5ac91821f5
commit
8276c4149b
@ -2266,6 +2266,10 @@ mpr_ioctl(struct cdev *dev, u_long cmd, void *arg, int flag,
|
||||
mpr_unlock(sc);
|
||||
break;
|
||||
case MPRIO_READ_CFG_PAGE:
|
||||
if (page_req->len < (int)sizeof(MPI2_CONFIG_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mpr_page = malloc(page_req->len, M_MPRUSER, M_WAITOK | M_ZERO);
|
||||
error = copyin(page_req->buf, mpr_page,
|
||||
sizeof(MPI2_CONFIG_PAGE_HEADER));
|
||||
@ -2284,6 +2288,11 @@ mpr_ioctl(struct cdev *dev, u_long cmd, void *arg, int flag,
|
||||
mpr_unlock(sc);
|
||||
break;
|
||||
case MPRIO_READ_EXT_CFG_PAGE:
|
||||
if (ext_page_req->len <
|
||||
(int)sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mpr_page = malloc(ext_page_req->len, M_MPRUSER,
|
||||
M_WAITOK | M_ZERO);
|
||||
error = copyin(ext_page_req->buf, mpr_page,
|
||||
@ -2298,6 +2307,10 @@ mpr_ioctl(struct cdev *dev, u_long cmd, void *arg, int flag,
|
||||
error = copyout(mpr_page, ext_page_req->buf, ext_page_req->len);
|
||||
break;
|
||||
case MPRIO_WRITE_CFG_PAGE:
|
||||
if (page_req->len < (int)sizeof(MPI2_CONFIG_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mpr_page = malloc(page_req->len, M_MPRUSER, M_WAITOK|M_ZERO);
|
||||
error = copyin(page_req->buf, mpr_page, page_req->len);
|
||||
if (error)
|
||||
|
@ -2156,6 +2156,10 @@ mps_ioctl(struct cdev *dev, u_long cmd, void *arg, int flag,
|
||||
mps_unlock(sc);
|
||||
break;
|
||||
case MPSIO_READ_CFG_PAGE:
|
||||
if (page_req->len < (int)sizeof(MPI2_CONFIG_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mps_page = malloc(page_req->len, M_MPSUSER, M_WAITOK | M_ZERO);
|
||||
error = copyin(page_req->buf, mps_page,
|
||||
sizeof(MPI2_CONFIG_PAGE_HEADER));
|
||||
@ -2174,6 +2178,11 @@ mps_ioctl(struct cdev *dev, u_long cmd, void *arg, int flag,
|
||||
mps_unlock(sc);
|
||||
break;
|
||||
case MPSIO_READ_EXT_CFG_PAGE:
|
||||
if (ext_page_req->len <
|
||||
(int)sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mps_page = malloc(ext_page_req->len, M_MPSUSER, M_WAITOK|M_ZERO);
|
||||
error = copyin(ext_page_req->buf, mps_page,
|
||||
sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
|
||||
@ -2187,6 +2196,10 @@ mps_ioctl(struct cdev *dev, u_long cmd, void *arg, int flag,
|
||||
error = copyout(mps_page, ext_page_req->buf, ext_page_req->len);
|
||||
break;
|
||||
case MPSIO_WRITE_CFG_PAGE:
|
||||
if (page_req->len < (int)sizeof(MPI2_CONFIG_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mps_page = malloc(page_req->len, M_MPSUSER, M_WAITOK|M_ZERO);
|
||||
error = copyin(page_req->buf, mps_page, page_req->len);
|
||||
if (error)
|
||||
|
@ -672,6 +672,10 @@ mpt_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
case MPTIO_READ_CFG_PAGE32:
|
||||
#endif
|
||||
case MPTIO_READ_CFG_PAGE:
|
||||
if (page_req->len < (int)sizeof(CONFIG_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = mpt_alloc_buffer(mpt, &mpt_page, page_req->len);
|
||||
if (error)
|
||||
break;
|
||||
@ -698,6 +702,11 @@ mpt_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
case MPTIO_READ_EXT_CFG_PAGE32:
|
||||
#endif
|
||||
case MPTIO_READ_EXT_CFG_PAGE:
|
||||
if (ext_page_req->len <
|
||||
(int)sizeof(CONFIG_EXTENDED_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = mpt_alloc_buffer(mpt, &mpt_page, ext_page_req->len);
|
||||
if (error)
|
||||
break;
|
||||
@ -717,6 +726,10 @@ mpt_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
case MPTIO_WRITE_CFG_PAGE32:
|
||||
#endif
|
||||
case MPTIO_WRITE_CFG_PAGE:
|
||||
if (page_req->len < (int)sizeof(CONFIG_PAGE_HEADER)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = mpt_alloc_buffer(mpt, &mpt_page, page_req->len);
|
||||
if (error)
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user