This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] [BZ #15002] posix_fallocate: avoid undefined behavior in wraparound check
- From: Nickolai Zeldovich <nickolai at csail dot mit dot edu>
- To: libc-alpha at sourceware dot org
- Cc: Nickolai Zeldovich <nickolai at csail dot mit dot edu>
- Date: Wed, 15 May 2013 12:58:15 -0400
- Subject: [PATCH] [BZ #15002] posix_fallocate: avoid undefined behavior in wraparound check
posix_fallocate relies on wraparound to check whether offset + len overflows.
As both are signed values, this is undefined behavior in C, and some compilers
(e.g., gcc-4.7.2) will optimize away the if (offset + len < 0) check as dead
code, since it is already known that offset >= 0 and len >= 0. This patch
replaces the check with one that does not rely on undefined behavior.
---
sysdeps/posix/posix_fallocate.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c
index 99aaf01..b9fdc4b 100644
--- a/sysdeps/posix/posix_fallocate.c
+++ b/sysdeps/posix/posix_fallocate.c
@@ -21,6 +21,11 @@
#include <sys/stat.h>
#include <sys/statfs.h>
+#define __HALF_MAX_SIGNED(type) \
+ ((type)1 << (sizeof(type)*8-2))
+#define __MAX_SIGNED(type) \
+ (__HALF_MAX_SIGNED(type) - 1 + __HALF_MAX_SIGNED(type))
+
/* Reserve storage for the data of the file associated with FD. */
int
@@ -33,7 +38,7 @@ posix_fallocate (int fd, __off_t offset, __off_t len)
OFFSET + LEN is too large if it is a negative value. */
if (offset < 0 || len < 0)
return EINVAL;
- if (offset + len < 0)
+ if (offset > __MAX_SIGNED(__off_t) - len)
return EFBIG;
/* First thing we have to make sure is that this is really a regular
--
1.7.10.4