add fortified implementations of fread/fwrite
A __size_mul_overflow utility is used to take advantage of the checked
overflow intrinsics in Clang and GCC (>= 5). The fallback for older
compilers is the optimized but less than ideal overflow checking pattern
used in OpenBSD.
Change-Id: Ibb0d4fd9b5acb67983e6a9f46844c2fd444f7e69
diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_compilation_test.cpp
index 537b341..166e8d9 100644
--- a/tests/fortify_compilation_test.cpp
+++ b/tests/fortify_compilation_test.cpp
@@ -230,3 +230,35 @@
// clang should emit a warning, but doesn't
ppoll(fds, 2, &timeout, NULL);
}
+
+void test_fread_overflow() {
+ char buf[4];
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: error: call to '__fread_overflow' declared with attribute error: fread called with overflowing size * count
+ // clang should emit a warning, but doesn't
+ fread(buf, 2, (size_t)-1, stdin);
+}
+
+void test_fread_too_big() {
+ char buf[4];
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: error: call to '__fread_too_big_error' declared with attribute error: fread called with size * count bigger than buffer
+ // clang should emit a warning, but doesn't
+ fread(buf, 1, 5, stdin);
+}
+
+void test_fwrite_overflow() {
+ char buf[4];
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: error: call to '__fwrite_overflow' declared with attribute error: fwrite called with overflowing size * count
+ // clang should emit a warning, but doesn't
+ fwrite(buf, 2, (size_t)-1, stdout);
+}
+
+void test_fwrite_too_big() {
+ char buf[4] = {0};
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: error: call to '__fwrite_too_big_error' declared with attribute error: fwrite called with size * count bigger than buffer
+ // clang should emit a warning, but doesn't
+ fwrite(buf, 1, 5, stdout);
+}