diff options
Diffstat (limited to 'lib/libc/stdio/fread.c')
-rw-r--r-- | lib/libc/stdio/fread.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c index 430865d022f..8a592f6d3f1 100644 --- a/lib/libc/stdio/fread.c +++ b/lib/libc/stdio/fread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fread.c,v 1.11 2009/11/21 09:53:44 guenther Exp $ */ +/* $OpenBSD: fread.c,v 1.12 2014/05/01 16:40:36 deraadt Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -33,8 +33,12 @@ #include <stdio.h> #include <string.h> +#include <stdint.h> +#include <errno.h> #include "local.h" +#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4)) + size_t fread(void *buf, size_t size, size_t count, FILE *fp) { @@ -44,6 +48,16 @@ fread(void *buf, size_t size, size_t count, FILE *fp) size_t total; /* + * 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 ((resid = count * size) == 0) |