xref: /aosp_15_r20/bionic/tests/clang_fortify_tests.cpp (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //
18 // Clang compile-time and run-time tests for Bionic's FORTIFY.
19 //
20 
21 // This file is compiled in two configurations to give us reasonable coverage of clang's
22 // FORTIFY implementation:
23 //
24 // 1. For compile-time checks, we use clang's diagnostic consumer
25 // (https://clang.llvm.org/doxygen/classclang_1_1VerifyDiagnosticConsumer.html#details)
26 // to check diagnostics (e.g. the expected-* comments everywhere).
27 //
28 // 2. For run-time checks, we build and run as regular gtests.
29 
30 // Note that these tests do things like leaking memory. That's WAI.
31 
32 //
33 // Configuration for the compile-time checks. (These comments have side effects!)
34 //
35 // Silence all "from 'diagnose_if'" `note`s from anywhere, including headers; they're uninteresting
36 // for this test case, and their line numbers may change over time.
37 // expected-note@* 0+{{from 'diagnose_if'}}
38 //
39 // Similarly, there are a few overload tricks we have to emit errors. Ignore any notes from those.
40 // expected-note@* 0+{{candidate function}}
41 //
42 // And finally, all explicitly-unavailable-here complaints from headers are
43 // uninteresting
44 // expected-note@* 0+{{has been explicitly marked unavailable here}}
45 //
46 // Note that some of these diagnostics come from clang itself, while others come from
47 // `diagnose_if`s sprinkled throughout Bionic.
48 
49 #ifndef _FORTIFY_SOURCE
50 #error "_FORTIFY_SOURCE must be defined"
51 #endif
52 
53 #include <sys/cdefs.h>
54 
55 // This is a test specifically of bionic's FORTIFY machinery. Other stdlibs need not apply.
56 #ifndef __BIONIC__
57 // expected-no-diagnostics
58 #else
59 
60 // As alluded to above, we're going to be doing some obviously very broken things in this file.
61 // FORTIFY helpfully flags a lot of it at compile-time, but we want it to *actually* crash, too. So
62 // let's wipe out any build-time errors.
63 #ifndef COMPILATION_TESTS
64 #undef __clang_error_if
65 #define __clang_error_if(...)
66 #undef __clang_warning_if
67 #define __clang_warning_if(...)
68 #pragma clang diagnostic ignored "-Wfortify-source"
69 
70 // SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but
71 // blocks them otherwise. This is needed for diagnostics emitted with __enable_if.
72 #define SOMETIMES_CONST volatile
73 #else
74 #define SOMETIMES_CONST const
75 #endif
76 
77 #include <err.h>
78 #include <fcntl.h>
79 #include <limits.h>
80 #include <poll.h>
81 #include <signal.h>
82 #include <stdio.h>
83 #include <stdlib.h>
84 #include <string.h>
85 #include <sys/socket.h>
86 #include <sys/stat.h>
87 #include <sys/wait.h>
88 #include <syslog.h>
89 #include <unistd.h>
90 #include <wchar.h>
91 
92 #include <array>
93 
94 #include "DoNotOptimize.h"
95 
96 #ifndef COMPILATION_TESTS
97 #include <android-base/silent_death_test.h>
98 #include <gtest/gtest.h>
99 
100 #define CONCAT2(x, y) x##y
101 #define CONCAT(x, y) CONCAT2(x, y)
102 #define FORTIFY_TEST_NAME CONCAT(CONCAT(clang_fortify_test_, _FORTIFY_SOURCE), _DeathTest)
103 
104 using FORTIFY_TEST_NAME = SilentDeathTest;
105 
106 template <typename Fn>
ExitAfter(Fn && f)107 __attribute__((noreturn)) static void ExitAfter(Fn&& f) {
108   f();
109   // No need to tear things down; our parent process should handle that.
110   _exit(0);
111 }
112 
113 // In any case (including failing tests), we always want to die after this.
114 #define DIE_WITH(expr, cond, regex) EXPECT_EXIT(ExitAfter([&] { (expr); }), cond, regex)
115 
116 // EXPECT_NO_DEATH forks so that the test remains alive on a bug, and so that the environment
117 // doesn't get modified on no bug. (Environment modification is especially tricky to deal with given
118 // the *_STRUCT variants below.)
119 #define EXPECT_NO_DEATH(expr) DIE_WITH(expr, testing::ExitedWithCode(0), "")
120 #define EXPECT_FORTIFY_DEATH(expr) DIE_WITH(expr, testing::KilledBySignal(SIGABRT), "FORTIFY")
121 // Expecting death, but only if we're doing a "strict" struct-checking mode.
122 #if _FORTIFY_SOURCE > 1
123 #define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH
124 #else
125 #define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_NO_DEATH
126 #endif
127 
128 #define FORTIFY_TEST(test_name) TEST_F(FORTIFY_TEST_NAME, test_name)
129 
130 #else  // defined(COMPILATION_TESTS)
131 
132 #define EXPECT_NO_DEATH(expr) expr
133 #define EXPECT_FORTIFY_DEATH(expr) expr
134 #define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH
135 #define FORTIFY_TEST(test_name) void test_name()
136 #endif
137 
138 const static int kBogusFD = -1;
139 
FORTIFY_TEST(strlen)140 FORTIFY_TEST(strlen) {
141   auto run_strlen_with_contents = [&](std::array<char, 3> contents) {
142     // A lot of cruft is necessary to make this test DTRT. LLVM and Clang love to fold/optimize
143     // strlen calls, and that's the opposite of what we want to happen.
144 
145     // Loop to convince LLVM that `contents` can never be known (since `xor volatile_value` can flip
146     // any bit in each elem of `contents`).
147     volatile char always_zero = 0;
148     for (char& c : contents) {
149       c ^= always_zero;
150     }
151     DoNotOptimize(strlen(&contents.front()));
152   };
153 
154   EXPECT_NO_DEATH(run_strlen_with_contents({'f', 'o', '\0'}));
155   EXPECT_FORTIFY_DEATH(run_strlen_with_contents({'f', 'o', 'o'}));
156 }
157 
FORTIFY_TEST(string)158 FORTIFY_TEST(string) {
159   char small_buffer[8] = {};
160 
161   {
162     char large_buffer[sizeof(small_buffer) + 1] = {};
163     // expected-error@+1{{will always overflow}}
164     EXPECT_FORTIFY_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer)));
165     // expected-error@+1{{will always overflow}}
166     EXPECT_FORTIFY_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer)));
167     // FIXME(gbiv): look into removing mempcpy's diagnose_if bits once the b/149839606 roll sticks.
168     // expected-error@+2{{will always overflow}}
169     // expected-error@+1{{size bigger than buffer}}
170     EXPECT_FORTIFY_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer)));
171     // expected-error@+1{{will always overflow}}
172     EXPECT_FORTIFY_DEATH(memset(small_buffer, 0, sizeof(large_buffer)));
173     // expected-warning@+1{{arguments got flipped?}}
174     EXPECT_NO_DEATH(memset(small_buffer, sizeof(small_buffer), 0));
175     // expected-error@+1{{size bigger than buffer}}
176     EXPECT_FORTIFY_DEATH(bcopy(large_buffer, small_buffer, sizeof(large_buffer)));
177     // expected-error@+1{{size bigger than buffer}}
178     EXPECT_FORTIFY_DEATH(bzero(small_buffer, sizeof(large_buffer)));
179   }
180 
181   {
182     const char large_string[] = "Hello!!!";
183     static_assert(sizeof(large_string) > sizeof(small_buffer), "");
184 
185     // expected-error@+2{{will always overflow}}
186     // expected-error@+1{{string bigger than buffer}}
187     EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
188     // expected-error@+1{{string bigger than buffer}}
189     EXPECT_FORTIFY_DEATH(stpcpy(small_buffer, large_string));
190     // expected-error@+1{{size argument is too large}}
191     EXPECT_FORTIFY_DEATH(strncpy(small_buffer, large_string, sizeof(large_string)));
192     // expected-error@+1{{size argument is too large}}
193     EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
194     // expected-error@+1{{string bigger than buffer}}
195     EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string));
196     // expected-error@+1{{size argument is too large}}
197     EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
198     // expected-error@+1{{size bigger than buffer}}
199     EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string)));
200     // expected-error@+1{{size bigger than buffer}}
201     EXPECT_FORTIFY_DEATH(strlcat(small_buffer, large_string, sizeof(large_string)));
202   }
203 
204   {
205     struct {
206       char tiny_buffer[4];
207       char tiny_buffer2[4];
208     } split = {};
209 
210     EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
211     EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
212     EXPECT_NO_DEATH(memmove(split.tiny_buffer, &split, sizeof(split)));
213     EXPECT_NO_DEATH(mempcpy(split.tiny_buffer, &split, sizeof(split)));
214     EXPECT_NO_DEATH(memset(split.tiny_buffer, 0, sizeof(split)));
215 
216     EXPECT_NO_DEATH(bcopy(&split, split.tiny_buffer, sizeof(split)));
217     EXPECT_NO_DEATH(bzero(split.tiny_buffer, sizeof(split)));
218 
219     const char small_string[] = "Hi!!";
220     static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
221 
222 #if _FORTIFY_SOURCE > 1
223     // expected-error@+3{{will always overflow}}
224     // expected-error@+2{{string bigger than buffer}}
225 #endif
226     EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
227 
228 #if _FORTIFY_SOURCE > 1
229     // expected-error@+2{{string bigger than buffer}}
230 #endif
231     EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
232 
233 #if _FORTIFY_SOURCE > 1
234     // expected-error@+2{{size argument is too large}}
235 #endif
236     EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(small_string)));
237 
238 #if _FORTIFY_SOURCE > 1
239     // expected-error@+2{{size argument is too large}}
240 #endif
241     EXPECT_FORTIFY_DEATH_STRUCT(stpncpy(split.tiny_buffer, small_string, sizeof(small_string)));
242 
243 #if _FORTIFY_SOURCE > 1
244     // expected-error@+2{{string bigger than buffer}}
245 #endif
246     EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
247 
248 #if _FORTIFY_SOURCE > 1
249     // expected-error@+2{{size argument is too large}}
250 #endif
251     EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string)));
252 
253 #if _FORTIFY_SOURCE > 1
254     // expected-error@+2{{size bigger than buffer}}
255 #endif
256     EXPECT_FORTIFY_DEATH_STRUCT(strlcat(split.tiny_buffer, small_string, sizeof(small_string)));
257 
258 #if _FORTIFY_SOURCE > 1
259     // expected-error@+2{{size bigger than buffer}}
260 #endif
261     EXPECT_FORTIFY_DEATH_STRUCT(strlcpy(split.tiny_buffer, small_string, sizeof(small_string)));
262   }
263 }
264 
FORTIFY_TEST(fcntl)265 FORTIFY_TEST(fcntl) {
266   const char target[] = "/dev/null";
267   int dirfd = 0;
268 
269   // These all emit hard errors without diagnose_if, so running them is a bit
270   // more involved.
271 #ifdef COMPILATION_TESTS
272   // expected-error@+1{{too many arguments}}
273   open("/", 0, 0, 0);
274   // expected-error@+1{{too many arguments}}
275   open64("/", 0, 0, 0);
276   // expected-error@+1{{too many arguments}}
277   openat(0, "/", 0, 0, 0);
278   // expected-error@+1{{too many arguments}}
279   openat64(0, "/", 0, 0, 0);
280 #endif
281 
282   // expected-error@+1{{missing mode}}
283   EXPECT_FORTIFY_DEATH(open(target, O_CREAT));
284   // expected-error@+1{{missing mode}}
285   EXPECT_FORTIFY_DEATH(open(target, O_TMPFILE));
286   // expected-error@+1{{missing mode}}
287   EXPECT_FORTIFY_DEATH(open64(target, O_CREAT));
288   // expected-error@+1{{missing mode}}
289   EXPECT_FORTIFY_DEATH(open64(target, O_TMPFILE));
290   // expected-error@+1{{missing mode}}
291   EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_CREAT));
292   // expected-error@+1{{missing mode}}
293   EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_TMPFILE));
294   // expected-error@+1{{missing mode}}
295   EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_CREAT));
296   // expected-error@+1{{missing mode}}
297   EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_TMPFILE));
298 
299   // expected-warning@+1{{superfluous mode bits}}
300   EXPECT_NO_DEATH(open(target, O_RDONLY, 0777));
301   // expected-warning@+1{{superfluous mode bits}}
302   EXPECT_NO_DEATH(open64(target, O_RDONLY, 0777));
303   // expected-warning@+1{{superfluous mode bits}}
304   EXPECT_NO_DEATH(openat(dirfd, target, O_RDONLY, 0777));
305   // expected-warning@+1{{superfluous mode bits}}
306   EXPECT_NO_DEATH(openat64(dirfd, target, O_RDONLY, 0777));
307 }
308 
309 // Since these emit hard errors, it's sort of hard to run them...
310 #ifdef COMPILATION_TESTS
311 namespace compilation_tests {
312 template <typename T>
declval()313 static T declval() {
314   __builtin_unreachable();
315 }
316 
testFormatStrings()317 static void testFormatStrings() {
318   const auto unsigned_value = declval<unsigned long long>();
319   const auto* unknown_string = declval<const char*>();
320   const auto va = *declval<va_list*>();
321 
322   {
323     auto some_fd = declval<int>();
324     // expected-warning@+1{{format specifies type 'int'}}
325     dprintf(some_fd, "%d", unsigned_value);
326     // expected-warning@+1{{format string is not a string literal}}
327     dprintf(some_fd, unknown_string, unsigned_value);
328     // expected-warning@+1{{format string is not a string literal}}
329     vdprintf(1, unknown_string, va);
330   }
331 
332   {
333     auto* retval = declval<char*>();
334 #if 0
335     // expected-error@+2{{ignoring return value}}
336 #endif
337     // expected-warning@+1{{format specifies type 'int'}}
338     asprintf(&retval, "%d", unsigned_value);
339 #if 0
340     // expected-error@+2{{ignoring return value}}
341 #endif
342     // expected-warning@+1{{format string is not a string literal}}
343     asprintf(&retval, unknown_string, unsigned_value);
344 #if 0
345     // expected-error@+2{{ignoring return value}}
346 #endif
347     // expected-warning@+1{{format string is not a string literal}}
348     vasprintf(&retval, unknown_string, va);
349   }
350 
351   // expected-warning@+1{{format specifies type 'int'}}
352   syslog(0, "%d", unsigned_value);
353   // expected-warning@+1{{format string is not a string literal}}
354   syslog(0, unknown_string, unsigned_value);
355   // expected-warning@+1{{format string is not a string literal}}
356   vsyslog(0, unknown_string, va);
357 
358   {
359     auto* file = declval<FILE*>();
360     // expected-warning@+1{{format specifies type 'int'}}
361     fprintf(file, "%d", unsigned_value);
362     // expected-warning@+1{{format string is not a string literal}}
363     fprintf(file, unknown_string, unsigned_value);
364     // expected-warning@+1{{format string is not a string literal}}
365     vfprintf(file, unknown_string, va);
366   }
367 
368   // expected-warning@+1{{format specifies type 'int'}}
369   printf("%d", unsigned_value);
370   // expected-warning@+1{{format string is not a string literal}}
371   printf(unknown_string, unsigned_value);
372   // expected-warning@+1{{format string is not a string literal}}
373   vprintf(unknown_string, va);
374 
375   {
376     char buf[128];
377     // expected-warning@+1{{format specifies type 'int'}}
378     sprintf(buf, "%d", unsigned_value);
379     // expected-warning@+1{{format string is not a string literal}}
380     sprintf(buf, unknown_string, unsigned_value);
381     // expected-warning@+1{{format string is not a string literal}}
382     sprintf(buf, unknown_string, va);
383 
384     // expected-warning@+1{{format specifies type 'int'}}
385     snprintf(buf, sizeof(buf), "%d", unsigned_value);
386     // expected-warning@+1{{format string is not a string literal}}
387     snprintf(buf, sizeof(buf), unknown_string, unsigned_value);
388     // expected-warning@+1{{format string is not a string literal}}
389     vsnprintf(buf, sizeof(buf), unknown_string, va);
390   }
391 
392   // FIXME: below are general format string cases where clang should probably try to warn.
393   {
394     char buf[4];
395     sprintf(buf, "%s", "1234");
396     sprintf(buf, "1%s4", "23");
397     sprintf(buf, "%d", 1234);
398 
399     // Similar thoughts for strncpy, etc.
400   }
401 }
402 
testStdlib()403 static void testStdlib() {
404 #pragma clang diagnostic push
405 #pragma clang diagnostic ignored "-Wnonnull"
406   char path_buffer[PATH_MAX - 1];
407   // expected-warning@+2{{ignoring return value of function}}
408   // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
409   realpath("/", path_buffer);
410   // expected-warning@+1{{ignoring return value of function}}
411   realpath("/", nullptr);
412 
413   // expected-warning@+2{{ignoring return value of function}}
414   // expected-error@+1{{flipped arguments?}}
415   realpath(nullptr, path_buffer);
416 
417   // expected-warning@+2{{ignoring return value of function}}
418   // expected-error@+1{{flipped arguments?}}
419   realpath(nullptr, nullptr);
420 #pragma clang diagnostic pop
421 }
422 }  // namespace compilation_tests
423 #endif
424 
FORTIFY_TEST(poll)425 FORTIFY_TEST(poll) {
426   int pipe_fds[2];
427   if (pipe(pipe_fds)) err(1, "pipe failed");
428 
429   // after this, pipe_fds[0] should always report RDHUP
430   if (close(pipe_fds[1])) err(1, "close failed");
431 
432   struct pollfd poll_fd = { pipe_fds[0], POLLRDHUP, 0 };
433   {
434     struct pollfd few_fds[] = { poll_fd, poll_fd };
435     // expected-error@+1{{fd_count is larger than the given buffer}}
436     EXPECT_FORTIFY_DEATH(poll(few_fds, 3, 0));
437     // expected-error@+1{{fd_count is larger than the given buffer}}
438     EXPECT_FORTIFY_DEATH(ppoll(few_fds, 3, 0, 0));
439     // expected-error@+1{{fd_count is larger than the given buffer}}
440     EXPECT_FORTIFY_DEATH(ppoll64(few_fds, 3, 0, nullptr));
441   }
442 
443   {
444     struct {
445       struct pollfd few[2];
446       struct pollfd extra[1];
447     } fds = { { poll_fd, poll_fd }, { poll_fd } };
448     static_assert(sizeof(fds) >= sizeof(struct pollfd) * 3, "");
449 
450 #if _FORTIFY_SOURCE > 1
451     // expected-error@+2{{fd_count is larger than the given buffer}}
452 #endif
453     EXPECT_FORTIFY_DEATH_STRUCT(poll(fds.few, 3, 0));
454 
455     struct timespec timeout = {};
456 #if _FORTIFY_SOURCE > 1
457     // expected-error@+2{{fd_count is larger than the given buffer}}
458 #endif
459     EXPECT_FORTIFY_DEATH_STRUCT(ppoll(fds.few, 3, &timeout, 0));
460 
461 #if _FORTIFY_SOURCE > 1
462     // expected-error@+2{{fd_count is larger than the given buffer}}
463 #endif
464     EXPECT_FORTIFY_DEATH_STRUCT(ppoll64(fds.few, 3, 0, nullptr));
465   }
466 }
467 
FORTIFY_TEST(socket)468 FORTIFY_TEST(socket) {
469   {
470     char small_buffer[8];
471     // expected-error@+1{{size bigger than buffer}}
472     EXPECT_FORTIFY_DEATH(recv(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
473     // expected-error@+1{{size bigger than buffer}}
474     EXPECT_FORTIFY_DEATH(recvfrom(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
475 
476     // expected-error@+1{{size bigger than buffer}}
477     EXPECT_FORTIFY_DEATH(send(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
478     // expected-error@+1{{size bigger than buffer}}
479     EXPECT_FORTIFY_DEATH(sendto(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
480   }
481 
482   {
483     struct {
484       char tiny_buffer[4];
485       char tiny_buffer2;
486     } split = {};
487 
488     EXPECT_NO_DEATH(recv(kBogusFD, split.tiny_buffer, sizeof(split), 0));
489     EXPECT_NO_DEATH(recvfrom(kBogusFD, split.tiny_buffer, sizeof(split), 0, 0, 0));
490   }
491 }
492 
FORTIFY_TEST(sys_stat)493 FORTIFY_TEST(sys_stat) {
494   // expected-error@+1{{'umask' called with invalid mode}}
495   EXPECT_FORTIFY_DEATH(umask(01777));
496 }
497 
FORTIFY_TEST(stdio)498 FORTIFY_TEST(stdio) {
499   char small_buffer[8] = {};
500   {
501     // expected-error@+1{{size argument is too large}}
502     EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
503 
504     va_list va;
505     // expected-error@+2{{size argument is too large}}
506     // expected-warning@+1{{format string is empty}}
507     EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
508 
509     const char *SOMETIMES_CONST format_string = "aaaaaaaaa";
510 
511     // expected-error@+1{{format string will always overflow}}
512     EXPECT_FORTIFY_DEATH(sprintf(small_buffer, format_string));
513   }
514 
515   // expected-error@+1{{size should not be negative}}
516   EXPECT_FORTIFY_DEATH(fgets(small_buffer, -1, stdin));
517   // expected-error@+1{{size is larger than the destination buffer}}
518   EXPECT_FORTIFY_DEATH(fgets(small_buffer, sizeof(small_buffer) + 1, stdin));
519 
520   // expected-error@+1{{size * count overflows}}
521   EXPECT_NO_DEATH(fread(small_buffer, 2, (size_t)-1, stdin));
522   // expected-error@+1{{size * count is too large for the given buffer}}
523   EXPECT_FORTIFY_DEATH(fread(small_buffer, 1, sizeof(small_buffer) + 1, stdin));
524 
525   // expected-error@+1{{size * count overflows}}
526   EXPECT_NO_DEATH(fwrite(small_buffer, 2, (size_t)-1, stdout));
527   // expected-error@+1{{size * count is too large for the given buffer}}
528   EXPECT_FORTIFY_DEATH(fwrite(small_buffer, 1, sizeof(small_buffer) + 1, stdout));
529 }
530 
FORTIFY_TEST(unistd)531 FORTIFY_TEST(unistd) {
532   char small_buffer[8];
533 
534   // Return value warnings are (sort of) a part of FORTIFY, so we don't ignore them.
535 #if 0
536   // expected-error@+2{{ignoring return value of function}}
537 #endif
538   // expected-error@+1{{bytes overflows the given object}}
539   EXPECT_FORTIFY_DEATH(read(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
540 #if 0
541   // expected-error@+2{{ignoring return value of function}}
542 #endif
543   // expected-error@+1{{bytes overflows the given object}}
544   EXPECT_FORTIFY_DEATH(pread(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
545 #if 0
546   // expected-error@+2{{ignoring return value of function}}
547 #endif
548   // expected-error@+1{{bytes overflows the given object}}
549   EXPECT_FORTIFY_DEATH(pread64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
550 #if 0
551   // expected-error@+2{{ignoring return value of function}}
552 #endif
553   // expected-error@+1{{bytes overflows the given object}}
554   EXPECT_FORTIFY_DEATH(write(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
555 #if 0
556   // expected-error@+2{{ignoring return value of function}}
557 #endif
558   // expected-error@+1{{bytes overflows the given object}}
559   EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
560 #if 0
561   // expected-error@+2{{ignoring return value of function}}
562 #endif
563   // expected-error@+1{{bytes overflows the given object}}
564   EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
565 #if 0
566   // expected-error@+2{{ignoring return value of function}}
567 #endif
568   // expected-error@+1{{bytes overflows the given object}}
569   EXPECT_FORTIFY_DEATH(readlink("/", small_buffer, sizeof(small_buffer) + 1));
570 #if 0
571   // expected-error@+2{{ignoring return value of function}}
572 #endif
573   // expected-error@+1{{bytes overflows the given object}}
574   EXPECT_FORTIFY_DEATH(getcwd(small_buffer, sizeof(small_buffer) + 1));
575 
576   // getcwd allocates and returns a buffer if you pass null to getcwd
577   EXPECT_NO_DEATH(getcwd(nullptr, 0));
578   EXPECT_NO_DEATH(getcwd(nullptr, 4096));
579 
580   struct {
581     char tiny_buffer[4];
582     char tiny_buffer2[4];
583   } split;
584 
585   EXPECT_NO_DEATH(read(kBogusFD, split.tiny_buffer, sizeof(split)));
586   EXPECT_NO_DEATH(pread(kBogusFD, split.tiny_buffer, sizeof(split), 0));
587   EXPECT_NO_DEATH(pread64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
588   EXPECT_NO_DEATH(write(kBogusFD, split.tiny_buffer, sizeof(split)));
589   EXPECT_NO_DEATH(pwrite(kBogusFD, split.tiny_buffer, sizeof(split), 0));
590   EXPECT_NO_DEATH(pwrite64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
591 
592 #if _FORTIFY_SOURCE > 1
593   // expected-error@+2{{bytes overflows the given object}}
594 #endif
595   EXPECT_FORTIFY_DEATH_STRUCT(readlink("/", split.tiny_buffer, sizeof(split)));
596 #if _FORTIFY_SOURCE > 1
597   // expected-error@+2{{bytes overflows the given object}}
598 #endif
599   EXPECT_FORTIFY_DEATH_STRUCT(getcwd(split.tiny_buffer, sizeof(split)));
600 
601   {
602     char* volatile unknown = small_buffer;
603     const size_t count = static_cast<size_t>(SSIZE_MAX) + 1;
604     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
605     EXPECT_FORTIFY_DEATH(read(kBogusFD, unknown, count));
606     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
607     EXPECT_FORTIFY_DEATH(pread(kBogusFD, unknown, count, 0));
608     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
609     EXPECT_FORTIFY_DEATH(pread64(kBogusFD, unknown, count, 0));
610     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
611     EXPECT_FORTIFY_DEATH(write(kBogusFD, unknown, count));
612     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
613     EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, unknown, count, 0));
614     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
615     EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, unknown, count, 0));
616   }
617 }
618 
619 #endif  // defined(__BIONIC__)
620