commit 647c25ad9c482eeacc30f89feef49dfe265b3055
parent 0784beab029ba53201ef93a601cb8c10d6aaca7f
Author: sin <sin@2f30.org>
Date: Thu, 29 Jan 2015 20:31:30 +0000
Add read()/write() checks
Diffstat:
1 file changed, 49 insertions(+), 0 deletions(-)
diff --git a/include/unistd.h b/include/unistd.h
@@ -0,0 +1,49 @@
+/* See LICENSE file for copyright and license details. */
+#ifndef FORTIFY_UNISTD_H_
+#define FORTIFY_UNISTD_H_
+
+#include_next <unistd.h>
+
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
+
+#define __errordecl(name, msg) extern void name(void) __attribute__((__error__(msg)))
+
+__errordecl(__read_error, "read: buffer overflow detected");
+static inline __attribute__ ((always_inline))
+ssize_t
+__fortify_read(int fd, void *buf, size_t n)
+{
+ size_t bos = __builtin_object_size(buf, 0);
+
+ if (__builtin_constant_p(n) && n > bos)
+ __read_error();
+
+ if (n > bos)
+ __builtin_trap();
+ return read(fd, buf, n);
+}
+
+__errordecl(__write_error, "write: buffer overflow detected");
+static inline __attribute__ ((always_inline))
+ssize_t
+__fortify_write(int fd, void *buf, size_t n)
+{
+ size_t bos = __builtin_object_size(buf, 0);
+
+ if (__builtin_constant_p(n) && n > bos)
+ __write_error();
+
+ if (n > bos)
+ __builtin_trap();
+ return write(fd, buf, n);
+}
+
+#undef read
+#define read(fd, buf, n) __fortify_read(fd, buf, n)
+
+#undef write
+#define write(fd, buf, n) __fortify_write(fd, buf, n)
+
+#endif
+
+#endif