diff options
author | 2014-05-01 16:40:36 +0000 | |
---|---|---|
committer | 2014-05-01 16:40:36 +0000 | |
commit | 044c262ab6d70c4b17b8b847f74a12fc7e06d829 (patch) | |
tree | 4db7ffe4651551eb0250eb724d6024061439bee8 /lib/libc/stdio/fwrite.c | |
parent | Nuke unused evptests.txt - the real one is over in regress. (diff) | |
download | wireguard-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.c | 17 |
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) |