bnxt(4): Fix ioctls when user addresses are inaccessable.
Check copyin's error code (differ adding copyout checks at this time). Don't directly access user memory in the switch statement. Since bnxt_ioctl_data isn't all that big, use a stack allocation. Reviewed by: jhb MFC after: 3 days Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D23933
This commit is contained in:
parent
cc1efc23c8
commit
ac09be5297
@ -1650,25 +1650,26 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
{
|
||||
struct bnxt_softc *softc = iflib_get_softc(ctx);
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
struct ifreq_buffer *ifbuf = &ifr->ifr_ifru.ifru_buffer;
|
||||
struct bnxt_ioctl_header *ioh =
|
||||
(struct bnxt_ioctl_header *)(ifbuf->buffer);
|
||||
struct bnxt_ioctl_header *ioh;
|
||||
size_t iol;
|
||||
int rc = ENOTSUP;
|
||||
struct bnxt_ioctl_data *iod = NULL;
|
||||
struct bnxt_ioctl_data iod_storage, *iod = &iod_storage;
|
||||
|
||||
|
||||
switch (command) {
|
||||
case SIOCGPRIVATE_0:
|
||||
if ((rc = priv_check(curthread, PRIV_DRIVER)) != 0)
|
||||
goto exit;
|
||||
|
||||
iod = malloc(ifbuf->length, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (!iod) {
|
||||
rc = ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
copyin(ioh, iod, ifbuf->length);
|
||||
ioh = ifr_buffer_get_buffer(ifr);
|
||||
iol = ifr_buffer_get_length(ifr);
|
||||
if (iol > sizeof(iod_storage))
|
||||
return (EINVAL);
|
||||
|
||||
switch (ioh->type) {
|
||||
if ((rc = copyin(ioh, iod, iol)) != 0)
|
||||
goto exit;
|
||||
|
||||
switch (iod->hdr.type) {
|
||||
case BNXT_HWRM_NVM_FIND_DIR_ENTRY:
|
||||
{
|
||||
struct bnxt_ioctl_hwrm_nvm_find_dir_entry *find =
|
||||
@ -1686,7 +1687,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1726,7 +1727,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
remain -= csize;
|
||||
}
|
||||
if (iod->hdr.rc == 0)
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
|
||||
iflib_dma_free(&dma_data);
|
||||
rc = 0;
|
||||
@ -1746,7 +1747,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1766,7 +1767,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1788,7 +1789,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1807,7 +1808,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1827,7 +1828,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1854,7 +1855,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
copyout(dma_data.idi_vaddr, get->data,
|
||||
get->entry_length * get->entries);
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
iflib_dma_free(&dma_data);
|
||||
|
||||
@ -1875,7 +1876,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1897,7 +1898,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1916,7 +1917,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1937,7 +1938,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1958,7 +1959,7 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
else {
|
||||
iod->hdr.rc = 0;
|
||||
copyout(iod, ioh, ifbuf->length);
|
||||
copyout(iod, ioh, iol);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1969,8 +1970,6 @@ bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
|
||||
}
|
||||
|
||||
exit:
|
||||
if (iod)
|
||||
free(iod, M_DEVBUF);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user