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