diff options
author | alfred <alfred@FreeBSD.org> | 2001-02-26 09:07:55 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2001-02-26 09:07:55 +0000 |
commit | ead0072315c6f8c5d9242385cd07b56512a8ba34 (patch) | |
tree | e0bd7be330f90e9b2544a366c1593dcd522c966f /sys/net/if_media.c | |
parent | 9f97905571442c98ead0c97ddd37e19c3af04024 (diff) | |
download | FreeBSD-src-ead0072315c6f8c5d9242385cd07b56512a8ba34.zip FreeBSD-src-ead0072315c6f8c5d9242385cd07b56512a8ba34.tar.gz |
Santize a size variable passed to kernel malloc.
Since we know there's always an upper bound we force that bound,
otherwise users can cause a panic via malloc getting hit with a
odd (huge or negative) amount of memory to allocate.
Tested by: kris
Pointed out by: Andrey Valyaev <dron@infosec.ru>
Diffstat (limited to 'sys/net/if_media.c')
-rw-r--r-- | sys/net/if_media.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/sys/net/if_media.c b/sys/net/if_media.c index d6f9d26..7c83ad9 100644 --- a/sys/net/if_media.c +++ b/sys/net/if_media.c @@ -270,6 +270,7 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) { struct ifmedia_entry *ep; int *kptr, count; + int usermax; /* user requested max */ kptr = NULL; /* XXX gcc */ @@ -280,7 +281,22 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) (*ifm->ifm_status)(ifp, ifmr); count = 0; - ep = LIST_FIRST(&ifm->ifm_list); + usermax = 0; + + /* + * If there are more interfaces on the list, count + * them. This allows the caller to set ifmr->ifm_count + * to 0 on the first call to know how much space to + * callocate. + */ + LIST_FOREACH(ep, &ifm->ifm_list, ifm_list) + usermax++; + + /* + * Don't allow the user to ask for too many + */ + if (ifmr->ifm_count > usermax) + ifmr->ifm_count = usermax; if (ifmr->ifm_count != 0) { kptr = (int *)malloc(ifmr->ifm_count * sizeof(int), @@ -289,24 +305,18 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) /* * Get the media words from the interface's list. */ + ep = LIST_FIRST(&ifm->ifm_list); for (; ep != NULL && count < ifmr->ifm_count; ep = LIST_NEXT(ep, ifm_list), count++) kptr[count] = ep->ifm_media; if (ep != NULL) error = E2BIG; /* oops! */ + } else { + count = usermax; } /* - * If there are more interfaces on the list, count - * them. This allows the caller to set ifmr->ifm_count - * to 0 on the first call to know how much space to - * callocate. - */ - for (; ep != NULL; ep = LIST_NEXT(ep, ifm_list)) - count++; - - /* * We do the copyout on E2BIG, because that's * just our way of telling userland that there * are more. This is the behavior I've observed |