diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2014-01-19 05:19:28 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2014-01-19 05:19:28 +0000 |
commit | 3527585a93a86a878df66a86b3e7870f85ee8ac5 (patch) | |
tree | a0fbfb3423bc43b8b5a6a14bf78a111b0793f6a6 /sys | |
parent | 5e3bbc10852f76488001b4e5d9ee8b0a8b7eb178 (diff) |
Count the number of media words required only once. If the media words
change during M_WAITOK (note: no driver does this at the moment), then
be careful to not copyout a truncated media word list, but return E2BIG.
ok mikeb guenther kettenis
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_media.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/sys/net/if_media.c b/sys/net/if_media.c index 3391c06f16f..edaf8438206 100644 --- a/sys/net/if_media.c +++ b/sys/net/if_media.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_media.c,v 1.20 2008/06/26 05:42:20 ray Exp $ */ +/* $OpenBSD: if_media.c,v 1.21 2014/01/19 05:19:27 deraadt Exp $ */ /* $NetBSD: if_media.c,v 1.10 2000/03/13 23:52:39 soren Exp $ */ /*- @@ -290,7 +290,7 @@ ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm, struct ifmedia_entry *ep; size_t nwords; - if(ifmr->ifm_count < 0) + if (ifmr->ifm_count < 0) return (EINVAL); ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ? @@ -308,23 +308,22 @@ ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm, nwords++; if (ifmr->ifm_count != 0) { - size_t count; size_t minwords = nwords > (size_t)ifmr->ifm_count ? (size_t)ifmr->ifm_count : nwords; - int *kptr = (int *)malloc(minwords * sizeof(int), - M_TEMP, M_WAITOK); + int *kptr = (int *)malloc(nwords * sizeof(int), + M_TEMP, M_WAITOK | M_ZERO); /* * Get the media words from the interface's list. */ ep = TAILQ_FIRST(&ifm->ifm_list); - for (count = 0; ep != NULL && count < minwords; - ep = TAILQ_NEXT(ep, ifm_list), count++) - kptr[count] = ep->ifm_media; - - error = copyout(kptr, ifmr->ifm_ulist, - minwords * sizeof(int)); - if (error == 0 && ep != NULL) - error = E2BIG; /* oops! */ + for (nwords = 0; ep != NULL && nwords < minwords; + ep = TAILQ_NEXT(ep, ifm_list)) + kptr[nwords++] = ep->ifm_media; + if (ep == NULL) + error = copyout(kptr, ifmr->ifm_ulist, + nwords * sizeof(int)); + else + error = E2BIG; free(kptr, M_TEMP); } ifmr->ifm_count = nwords; |