summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/fwrite.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2010-03-04 13:35:57 +0000
committerdes <des@FreeBSD.org>2010-03-04 13:35:57 +0000
commit834fb25a9ed2240101506d137b5be7d71c75f306 (patch)
tree4002c72cd1ed11909f7640bea343988cfcf63c5b /lib/libc/stdio/fwrite.c
parent98b742f57cafbed05c101e60cc131f5980f044d0 (diff)
parent787cf8d03f1c58ada088933408f30fd63de85bf2 (diff)
downloadFreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.zip
FreeBSD-src-834fb25a9ed2240101506d137b5be7d71c75f306.tar.gz
IFH@204581
Diffstat (limited to 'lib/libc/stdio/fwrite.c')
-rw-r--r--lib/libc/stdio/fwrite.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c
index cf52e42..acac943 100644
--- a/lib/libc/stdio/fwrite.c
+++ b/lib/libc/stdio/fwrite.c
@@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93";
__FBSDID("$FreeBSD$");
#include "namespace.h"
+#include <errno.h>
+#include <stdint.h>
#include <stdio.h>
#include "un-namespace.h"
#include "local.h"
@@ -60,10 +62,24 @@ fwrite(buf, size, count, fp)
/*
* ANSI and SUSv2 require a return value of 0 if size or count are 0.
*/
- n = count * size;
- if (n == 0)
+ if ((count == 0) || (size == 0))
return (0);
+ /*
+ * Check for integer overflow. As an optimization, first check that
+ * at least one of {count, size} is at least 2^16, since if both
+ * values are less than that, their product can't possible overflow
+ * (size_t is always at least 32 bits on FreeBSD).
+ */
+ if (((count | size) > 0xFFFF) &&
+ (count > SIZE_MAX / size)) {
+ errno = EINVAL;
+ fp->_flags |= __SERR;
+ return (0);
+ }
+
+ n = count * size;
+
iov.iov_base = (void *)buf;
uio.uio_resid = iov.iov_len = n;
uio.uio_iov = &iov;
OpenPOWER on IntegriCloud