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 #ifndef __clang__
18 #error "Non-clang isn't supported"
19 #endif
20 
21 //
22 // Clang compile-time and run-time tests for Bionic's FORTIFY.
23 //
24 
25 // This file is compiled in two configurations to give us reasonable coverage of clang's
26 // FORTIFY implementation:
27 //
28 // 1. For compile-time checks, we use clang's diagnostic consumer
29 // (https://clang.llvm.org/doxygen/classclang_1_1VerifyDiagnosticConsumer.html#details)
30 // to check diagnostics (e.g. the expected-* comments everywhere).
31 //
32 // 2. For run-time checks, we build and run as regular gtests.
33 
34 // Note that these tests do things like leaking memory. That's WAI.
35 
36 //
37 // Configuration for the compile-time checks. (These comments have side effects!)
38 //
39 // Silence all "from 'diagnose_if'" `note`s from anywhere, including headers; they're uninteresting
40 // for this test case, and their line numbers may change over time.
41 // expected-note@* 0+{{from 'diagnose_if'}}
42 //
43 // Similarly, there are a few overload tricks we have to emit errors. Ignore any notes from those.
44 // expected-note@* 0+{{candidate function}}
45 //
46 // And finally, all explicitly-unavailable-here complaints from headers are
47 // uninteresting
48 // expected-note@* 0+{{has been explicitly marked unavailable here}}
49 //
50 // Note that some of these diagnostics come from clang itself, while others come from
51 // `diagnose_if`s sprinkled throughout Bionic.
52 
53 #ifndef _FORTIFY_SOURCE
54 #error "_FORTIFY_SOURCE must be defined"
55 #endif
56 
57 #include <sys/cdefs.h>
58 
59 // This is a test specifically of bionic's FORTIFY machinery. Other stdlibs need not apply.
60 #ifndef __BIONIC__
61 // expected-no-diagnostics
62 #else
63 
64 // As alluded to above, we're going to be doing some obviously very broken things in this file.
65 // FORTIFY helpfully flags a lot of it at compile-time, but we want it to *actually* crash, too. So
66 // let's wipe out any build-time errors.
67 #ifndef COMPILATION_TESTS
68 #undef __clang_error_if
69 #define __clang_error_if(...)
70 #undef __clang_warning_if
71 #define __clang_warning_if(...)
72 #pragma clang diagnostic ignored "-Wfortify-source"
73 
74 // SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but
75 // blocks them otherwise. This is needed for diagnostics emitted with __enable_if.
76 #define SOMETIMES_CONST volatile
77 #else
78 #define SOMETIMES_CONST const
79 #endif
80 
81 #include <err.h>
82 #include <fcntl.h>
83 #include <limits.h>
84 #include <poll.h>
85 #include <signal.h>
86 #include <stdio.h>
87 #include <stdlib.h>
88 #include <string.h>
89 #include <sys/socket.h>
90 #include <sys/stat.h>
91 #include <sys/wait.h>
92 #include <syslog.h>
93 #include <unistd.h>
94 #include <wchar.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(string)140 FORTIFY_TEST(string) {
141   char small_buffer[8] = {};
142 
143   {
144     char large_buffer[sizeof(small_buffer) + 1] = {};
145     // expected-error@+1{{will always overflow}}
146     EXPECT_FORTIFY_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer)));
147     // expected-error@+1{{will always overflow}}
148     EXPECT_FORTIFY_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer)));
149     // FIXME(gbiv): look into removing mempcpy's diagnose_if bits once the b/149839606 roll sticks.
150     // expected-error@+2{{will always overflow}}
151     // expected-error@+1{{size bigger than buffer}}
152     EXPECT_FORTIFY_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer)));
153     // expected-error@+1{{will always overflow}}
154     EXPECT_FORTIFY_DEATH(memset(small_buffer, 0, sizeof(large_buffer)));
155     // expected-warning@+1{{arguments got flipped?}}
156     EXPECT_NO_DEATH(memset(small_buffer, sizeof(small_buffer), 0));
157     // expected-error@+1{{size bigger than buffer}}
158     EXPECT_FORTIFY_DEATH(bcopy(large_buffer, small_buffer, sizeof(large_buffer)));
159     // expected-error@+1{{size bigger than buffer}}
160     EXPECT_FORTIFY_DEATH(bzero(small_buffer, sizeof(large_buffer)));
161   }
162 
163   {
164     const char large_string[] = "Hello!!!";
165     static_assert(sizeof(large_string) > sizeof(small_buffer), "");
166 
167     // expected-error@+1{{string bigger than buffer}}
168     EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
169     // expected-error@+1{{string bigger than buffer}}
170     EXPECT_FORTIFY_DEATH(stpcpy(small_buffer, large_string));
171     // expected-error@+1{{size argument is too large}}
172     EXPECT_FORTIFY_DEATH(strncpy(small_buffer, large_string, sizeof(large_string)));
173     // expected-error@+1{{size argument is too large}}
174     EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
175     // expected-error@+1{{string bigger than buffer}}
176     EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string));
177     // expected-error@+1{{size argument is too large}}
178     EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
179     // expected-error@+1{{size bigger than buffer}}
180     EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string)));
181     // expected-error@+1{{size bigger than buffer}}
182     EXPECT_FORTIFY_DEATH(strlcat(small_buffer, large_string, sizeof(large_string)));
183   }
184 
185   {
186     struct {
187       char tiny_buffer[4];
188       char tiny_buffer2[4];
189     } split = {};
190 
191     EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
192     EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
193     EXPECT_NO_DEATH(memmove(split.tiny_buffer, &split, sizeof(split)));
194     EXPECT_NO_DEATH(mempcpy(split.tiny_buffer, &split, sizeof(split)));
195     EXPECT_NO_DEATH(memset(split.tiny_buffer, 0, sizeof(split)));
196 
197     EXPECT_NO_DEATH(bcopy(&split, split.tiny_buffer, sizeof(split)));
198     EXPECT_NO_DEATH(bzero(split.tiny_buffer, sizeof(split)));
199 
200     const char small_string[] = "Hi!!";
201     static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
202 
203 #if _FORTIFY_SOURCE > 1
204     // expected-error@+2{{string bigger than buffer}}
205 #endif
206     EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
207 
208 #if _FORTIFY_SOURCE > 1
209     // expected-error@+2{{string bigger than buffer}}
210 #endif
211     EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
212 
213 #if _FORTIFY_SOURCE > 1
214     // expected-error@+2{{size argument is too large}}
215 #endif
216     EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(small_string)));
217 
218 #if _FORTIFY_SOURCE > 1
219     // expected-error@+2{{size argument is too large}}
220 #endif
221     EXPECT_FORTIFY_DEATH_STRUCT(stpncpy(split.tiny_buffer, small_string, sizeof(small_string)));
222 
223 #if _FORTIFY_SOURCE > 1
224     // expected-error@+2{{string bigger than buffer}}
225 #endif
226     EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
227 
228 #if _FORTIFY_SOURCE > 1
229     // expected-error@+2{{size argument is too large}}
230 #endif
231     EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string)));
232 
233 #if _FORTIFY_SOURCE > 1
234     // expected-error@+2{{size bigger than buffer}}
235 #endif
236     EXPECT_FORTIFY_DEATH_STRUCT(strlcat(split.tiny_buffer, small_string, sizeof(small_string)));
237 
238 #if _FORTIFY_SOURCE > 1
239     // expected-error@+2{{size bigger than buffer}}
240 #endif
241     EXPECT_FORTIFY_DEATH_STRUCT(strlcpy(split.tiny_buffer, small_string, sizeof(small_string)));
242   }
243 }
244 
FORTIFY_TEST(fcntl)245 FORTIFY_TEST(fcntl) {
246   const char target[] = "/dev/null";
247   int dirfd = 0;
248 
249   // These all emit hard errors without diagnose_if, so running them is a bit
250   // more involved.
251 #ifdef COMPILATION_TESTS
252   // expected-error@+1{{too many arguments}}
253   open("/", 0, 0, 0);
254   // expected-error@+1{{too many arguments}}
255   open64("/", 0, 0, 0);
256   // expected-error@+1{{too many arguments}}
257   openat(0, "/", 0, 0, 0);
258   // expected-error@+1{{too many arguments}}
259   openat64(0, "/", 0, 0, 0);
260 #endif
261 
262   // expected-error@+1{{missing mode}}
263   EXPECT_FORTIFY_DEATH(open(target, O_CREAT));
264   // expected-error@+1{{missing mode}}
265   EXPECT_FORTIFY_DEATH(open(target, O_TMPFILE));
266   // expected-error@+1{{missing mode}}
267   EXPECT_FORTIFY_DEATH(open64(target, O_CREAT));
268   // expected-error@+1{{missing mode}}
269   EXPECT_FORTIFY_DEATH(open64(target, O_TMPFILE));
270   // expected-error@+1{{missing mode}}
271   EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_CREAT));
272   // expected-error@+1{{missing mode}}
273   EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_TMPFILE));
274   // expected-error@+1{{missing mode}}
275   EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_CREAT));
276   // expected-error@+1{{missing mode}}
277   EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_TMPFILE));
278 
279   // expected-warning@+1{{superfluous mode bits}}
280   EXPECT_NO_DEATH(open(target, O_RDONLY, 0777));
281   // expected-warning@+1{{superfluous mode bits}}
282   EXPECT_NO_DEATH(open64(target, O_RDONLY, 0777));
283   // expected-warning@+1{{superfluous mode bits}}
284   EXPECT_NO_DEATH(openat(dirfd, target, O_RDONLY, 0777));
285   // expected-warning@+1{{superfluous mode bits}}
286   EXPECT_NO_DEATH(openat64(dirfd, target, O_RDONLY, 0777));
287 }
288 
289 // Since these emit hard errors, it's sort of hard to run them...
290 #ifdef COMPILATION_TESTS
291 namespace compilation_tests {
292 template <typename T>
declval()293 static T declval() {
294   __builtin_unreachable();
295 }
296 
testFormatStrings()297 static void testFormatStrings() {
298   const auto unsigned_value = declval<unsigned long long>();
299   const auto* unknown_string = declval<const char*>();
300   const auto va = *declval<va_list*>();
301 
302   {
303     auto some_fd = declval<int>();
304     // expected-warning@+1{{format specifies type 'int'}}
305     dprintf(some_fd, "%d", unsigned_value);
306     // expected-warning@+1{{format string is not a string literal}}
307     dprintf(some_fd, unknown_string, unsigned_value);
308     // expected-warning@+1{{format string is not a string literal}}
309     vdprintf(1, unknown_string, va);
310   }
311 
312   {
313     auto* retval = declval<char*>();
314 #if 0
315     // expected-error@+2{{ignoring return value}}
316 #endif
317     // expected-warning@+1{{format specifies type 'int'}}
318     asprintf(&retval, "%d", unsigned_value);
319 #if 0
320     // expected-error@+2{{ignoring return value}}
321 #endif
322     // expected-warning@+1{{format string is not a string literal}}
323     asprintf(&retval, unknown_string, unsigned_value);
324 #if 0
325     // expected-error@+2{{ignoring return value}}
326 #endif
327     // expected-warning@+1{{format string is not a string literal}}
328     vasprintf(&retval, unknown_string, va);
329   }
330 
331   // expected-warning@+1{{format specifies type 'int'}}
332   syslog(0, "%d", unsigned_value);
333   // expected-warning@+1{{format string is not a string literal}}
334   syslog(0, unknown_string, unsigned_value);
335   // expected-warning@+1{{format string is not a string literal}}
336   vsyslog(0, unknown_string, va);
337 
338   {
339     auto* file = declval<FILE*>();
340     // expected-warning@+1{{format specifies type 'int'}}
341     fprintf(file, "%d", unsigned_value);
342     // expected-warning@+1{{format string is not a string literal}}
343     fprintf(file, unknown_string, unsigned_value);
344     // expected-warning@+1{{format string is not a string literal}}
345     vfprintf(file, unknown_string, va);
346   }
347 
348   // expected-warning@+1{{format specifies type 'int'}}
349   printf("%d", unsigned_value);
350   // expected-warning@+1{{format string is not a string literal}}
351   printf(unknown_string, unsigned_value);
352   // expected-warning@+1{{format string is not a string literal}}
353   vprintf(unknown_string, va);
354 
355   {
356     char buf[128];
357     // expected-warning@+1{{format specifies type 'int'}}
358     sprintf(buf, "%d", unsigned_value);
359     // expected-warning@+1{{format string is not a string literal}}
360     sprintf(buf, unknown_string, unsigned_value);
361     // expected-warning@+1{{format string is not a string literal}}
362     sprintf(buf, unknown_string, va);
363 
364     // expected-warning@+1{{format specifies type 'int'}}
365     snprintf(buf, sizeof(buf), "%d", unsigned_value);
366     // expected-warning@+1{{format string is not a string literal}}
367     snprintf(buf, sizeof(buf), unknown_string, unsigned_value);
368     // expected-warning@+1{{format string is not a string literal}}
369     vsnprintf(buf, sizeof(buf), unknown_string, va);
370   }
371 
372   // FIXME: below are general format string cases where clang should probably try to warn.
373   {
374     char buf[4];
375     sprintf(buf, "%s", "1234");
376     sprintf(buf, "1%s4", "23");
377     sprintf(buf, "%d", 1234);
378 
379     // Similar thoughts for strncpy, etc.
380   }
381 }
382 
testStdlib()383 static void testStdlib() {
384   char path_buffer[PATH_MAX - 1];
385   // expected-warning@+2{{ignoring return value of function}}
386   // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
387   realpath("/", path_buffer);
388   // expected-warning@+1{{ignoring return value of function}}
389   realpath("/", nullptr);
390 
391   // expected-warning@+2{{ignoring return value of function}}
392   // expected-error@+1{{flipped arguments?}}
393   realpath(nullptr, path_buffer);
394 
395   // expected-warning@+2{{ignoring return value of function}}
396   // expected-error@+1{{flipped arguments?}}
397   realpath(nullptr, nullptr);
398 }
399 }  // namespace compilation_tests
400 #endif
401 
FORTIFY_TEST(poll)402 FORTIFY_TEST(poll) {
403   int pipe_fds[2];
404   if (pipe(pipe_fds)) err(1, "pipe failed");
405 
406   // after this, pipe_fds[0] should always report RDHUP
407   if (close(pipe_fds[1])) err(1, "close failed");
408 
409   struct pollfd poll_fd = { pipe_fds[0], POLLRDHUP, 0 };
410   {
411     struct pollfd few_fds[] = { poll_fd, poll_fd };
412     // expected-error@+1{{fd_count is larger than the given buffer}}
413     EXPECT_FORTIFY_DEATH(poll(few_fds, 3, 0));
414     // expected-error@+1{{fd_count is larger than the given buffer}}
415     EXPECT_FORTIFY_DEATH(ppoll(few_fds, 3, 0, 0));
416     // expected-error@+1{{fd_count is larger than the given buffer}}
417     EXPECT_FORTIFY_DEATH(ppoll64(few_fds, 3, 0, nullptr));
418   }
419 
420   {
421     struct {
422       struct pollfd few[2];
423       struct pollfd extra[1];
424     } fds = { { poll_fd, poll_fd }, { poll_fd } };
425     static_assert(sizeof(fds) >= sizeof(struct pollfd) * 3, "");
426 
427 #if _FORTIFY_SOURCE > 1
428     // expected-error@+2{{fd_count is larger than the given buffer}}
429 #endif
430     EXPECT_FORTIFY_DEATH_STRUCT(poll(fds.few, 3, 0));
431 
432     struct timespec timeout = {};
433 #if _FORTIFY_SOURCE > 1
434     // expected-error@+2{{fd_count is larger than the given buffer}}
435 #endif
436     EXPECT_FORTIFY_DEATH_STRUCT(ppoll(fds.few, 3, &timeout, 0));
437 
438 #if _FORTIFY_SOURCE > 1
439     // expected-error@+2{{fd_count is larger than the given buffer}}
440 #endif
441     EXPECT_FORTIFY_DEATH_STRUCT(ppoll64(fds.few, 3, 0, nullptr));
442   }
443 }
444 
FORTIFY_TEST(socket)445 FORTIFY_TEST(socket) {
446   {
447     char small_buffer[8];
448     // expected-error@+1{{size bigger than buffer}}
449     EXPECT_FORTIFY_DEATH(recv(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
450     // expected-error@+1{{size bigger than buffer}}
451     EXPECT_FORTIFY_DEATH(recvfrom(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
452 
453     // expected-error@+1{{size bigger than buffer}}
454     EXPECT_FORTIFY_DEATH(send(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
455     // expected-error@+1{{size bigger than buffer}}
456     EXPECT_FORTIFY_DEATH(sendto(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
457   }
458 
459   {
460     struct {
461       char tiny_buffer[4];
462       char tiny_buffer2;
463     } split = {};
464 
465     EXPECT_NO_DEATH(recv(kBogusFD, split.tiny_buffer, sizeof(split), 0));
466     EXPECT_NO_DEATH(recvfrom(kBogusFD, split.tiny_buffer, sizeof(split), 0, 0, 0));
467   }
468 }
469 
FORTIFY_TEST(sys_stat)470 FORTIFY_TEST(sys_stat) {
471   // expected-error@+1{{'umask' called with invalid mode}}
472   EXPECT_FORTIFY_DEATH(umask(01777));
473 }
474 
FORTIFY_TEST(stdio)475 FORTIFY_TEST(stdio) {
476   char small_buffer[8] = {};
477   {
478     // expected-error@+1{{size argument is too large}}
479     EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
480 
481     va_list va;
482     // expected-error@+2{{size argument is too large}}
483     // expected-warning@+1{{format string is empty}}
484     EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
485 
486     const char *SOMETIMES_CONST format_string = "aaaaaaaaa";
487 
488     // expected-error@+1{{format string will always overflow}}
489     EXPECT_FORTIFY_DEATH(sprintf(small_buffer, format_string));
490   }
491 
492   // expected-error@+1{{size should not be negative}}
493   EXPECT_FORTIFY_DEATH(fgets(small_buffer, -1, stdin));
494   // expected-error@+1{{size is larger than the destination buffer}}
495   EXPECT_FORTIFY_DEATH(fgets(small_buffer, sizeof(small_buffer) + 1, stdin));
496 
497   // expected-error@+1{{size * count overflows}}
498   EXPECT_NO_DEATH(fread(small_buffer, 2, (size_t)-1, stdin));
499   // expected-error@+1{{size * count is too large for the given buffer}}
500   EXPECT_FORTIFY_DEATH(fread(small_buffer, 1, sizeof(small_buffer) + 1, stdin));
501 
502   // expected-error@+1{{size * count overflows}}
503   EXPECT_NO_DEATH(fwrite(small_buffer, 2, (size_t)-1, stdout));
504   // expected-error@+1{{size * count is too large for the given buffer}}
505   EXPECT_FORTIFY_DEATH(fwrite(small_buffer, 1, sizeof(small_buffer) + 1, stdout));
506 }
507 
FORTIFY_TEST(unistd)508 FORTIFY_TEST(unistd) {
509   char small_buffer[8];
510 
511   // Return value warnings are (sort of) a part of FORTIFY, so we don't ignore them.
512 #if 0
513   // expected-error@+2{{ignoring return value of function}}
514 #endif
515   // expected-error@+1{{bytes overflows the given object}}
516   EXPECT_FORTIFY_DEATH(read(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
517 #if 0
518   // expected-error@+2{{ignoring return value of function}}
519 #endif
520   // expected-error@+1{{bytes overflows the given object}}
521   EXPECT_FORTIFY_DEATH(pread(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
522 #if 0
523   // expected-error@+2{{ignoring return value of function}}
524 #endif
525   // expected-error@+1{{bytes overflows the given object}}
526   EXPECT_FORTIFY_DEATH(pread64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
527 #if 0
528   // expected-error@+2{{ignoring return value of function}}
529 #endif
530   // expected-error@+1{{bytes overflows the given object}}
531   EXPECT_FORTIFY_DEATH(write(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
532 #if 0
533   // expected-error@+2{{ignoring return value of function}}
534 #endif
535   // expected-error@+1{{bytes overflows the given object}}
536   EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
537 #if 0
538   // expected-error@+2{{ignoring return value of function}}
539 #endif
540   // expected-error@+1{{bytes overflows the given object}}
541   EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
542 #if 0
543   // expected-error@+2{{ignoring return value of function}}
544 #endif
545   // expected-error@+1{{bytes overflows the given object}}
546   EXPECT_FORTIFY_DEATH(readlink("/", small_buffer, sizeof(small_buffer) + 1));
547 #if 0
548   // expected-error@+2{{ignoring return value of function}}
549 #endif
550   // expected-error@+1{{bytes overflows the given object}}
551   EXPECT_FORTIFY_DEATH(getcwd(small_buffer, sizeof(small_buffer) + 1));
552 
553   // getcwd allocates and returns a buffer if you pass null to getcwd
554   EXPECT_NO_DEATH(getcwd(nullptr, 0));
555   EXPECT_NO_DEATH(getcwd(nullptr, 4096));
556 
557   struct {
558     char tiny_buffer[4];
559     char tiny_buffer2[4];
560   } split;
561 
562   EXPECT_NO_DEATH(read(kBogusFD, split.tiny_buffer, sizeof(split)));
563   EXPECT_NO_DEATH(pread(kBogusFD, split.tiny_buffer, sizeof(split), 0));
564   EXPECT_NO_DEATH(pread64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
565   EXPECT_NO_DEATH(write(kBogusFD, split.tiny_buffer, sizeof(split)));
566   EXPECT_NO_DEATH(pwrite(kBogusFD, split.tiny_buffer, sizeof(split), 0));
567   EXPECT_NO_DEATH(pwrite64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
568 
569 #if _FORTIFY_SOURCE > 1
570   // expected-error@+2{{bytes overflows the given object}}
571 #endif
572   EXPECT_FORTIFY_DEATH_STRUCT(readlink("/", split.tiny_buffer, sizeof(split)));
573 #if _FORTIFY_SOURCE > 1
574   // expected-error@+2{{bytes overflows the given object}}
575 #endif
576   EXPECT_FORTIFY_DEATH_STRUCT(getcwd(split.tiny_buffer, sizeof(split)));
577 
578   {
579     char* volatile unknown = small_buffer;
580     const size_t count = static_cast<size_t>(SSIZE_MAX) + 1;
581     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
582     EXPECT_FORTIFY_DEATH(read(kBogusFD, unknown, count));
583     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
584     EXPECT_FORTIFY_DEATH(pread(kBogusFD, unknown, count, 0));
585     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
586     EXPECT_FORTIFY_DEATH(pread64(kBogusFD, unknown, count, 0));
587     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
588     EXPECT_FORTIFY_DEATH(write(kBogusFD, unknown, count));
589     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
590     EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, unknown, count, 0));
591     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
592     EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, unknown, count, 0));
593   }
594 }
595 
596 #endif  // defined(__BIONIC__)
597