summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2014-01-19 05:19:28 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2014-01-19 05:19:28 +0000
commit3527585a93a86a878df66a86b3e7870f85ee8ac5 (patch)
treea0fbfb3423bc43b8b5a6a14bf78a111b0793f6a6 /sys
parent5e3bbc10852f76488001b4e5d9ee8b0a8b7eb178 (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.c25
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;