summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/fwrite.c
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2014-05-01 16:40:36 +0000
committerderaadt <deraadt@openbsd.org>2014-05-01 16:40:36 +0000
commit044c262ab6d70c4b17b8b847f74a12fc7e06d829 (patch)
tree4db7ffe4651551eb0250eb724d6024061439bee8 /lib/libc/stdio/fwrite.c
parentNuke unused evptests.txt - the real one is over in regress. (diff)
downloadwireguard-openbsd-044c262ab6d70c4b17b8b847f74a12fc7e06d829.tar.xz
wireguard-openbsd-044c262ab6d70c4b17b8b847f74a12fc7e06d829.zip
Extend fread() and fwrite() to check for integer overflow, in which case
errno EOVERFLOW is returned and error is set on the FILE. ok kettenis miod beck
Diffstat (limited to 'lib/libc/stdio/fwrite.c')
-rw-r--r--lib/libc/stdio/fwrite.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c
index 41784f9312a..f0a17bfb9a8 100644
--- a/lib/libc/stdio/fwrite.c
+++ b/lib/libc/stdio/fwrite.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fwrite.c,v 1.10 2009/11/21 09:53:44 guenther Exp $ */
+/* $OpenBSD: fwrite.c,v 1.11 2014/05/01 16:40:36 deraadt Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -32,9 +32,14 @@
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
#include "local.h"
#include "fvwrite.h"
+#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
+
/*
* Write `count' objects (each size `size') from memory to the given file.
* Return the number of whole objects written.
@@ -48,6 +53,16 @@ fwrite(const void *buf, size_t size, size_t count, FILE *fp)
int ret;
/*
+ * Extension: Catch integer overflow
+ */
+ if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) &&
+ size > 0 && SIZE_MAX / size < count) {
+ errno = EOVERFLOW;
+ fp->_flags |= __SERR;
+ return (0);
+ }
+
+ /*
* ANSI and SUSv2 require a return value of 0 if size or count are 0.
*/
if ((n = count * size) == 0)