blob: 4c4e51024ef548136db449bb2bd51efcbc4891b7 [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));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700180 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700181 EXPECT_FORTIFY_DEATH(strncpy(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700182 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700183 EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700184 // expected-error@+1{{string bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700185 EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700186 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700187 EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700188 // expected-error@+1{{size bigger than buffer}}
189 EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string)));
190 // expected-error@+1{{size bigger than buffer}}
191 EXPECT_FORTIFY_DEATH(strlcat(small_buffer, large_string, sizeof(large_string)));
George Burgess IV9a274102019-06-04 15:39:52 -0700192 }
193
194 {
195 struct {
196 char tiny_buffer[4];
197 char tiny_buffer2[4];
198 } split = {};
199
200 EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
201 EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
202 EXPECT_NO_DEATH(memmove(split.tiny_buffer, &split, sizeof(split)));
203 EXPECT_NO_DEATH(mempcpy(split.tiny_buffer, &split, sizeof(split)));
204 EXPECT_NO_DEATH(memset(split.tiny_buffer, 0, sizeof(split)));
205
206 EXPECT_NO_DEATH(bcopy(&split, split.tiny_buffer, sizeof(split)));
207 EXPECT_NO_DEATH(bzero(split.tiny_buffer, sizeof(split)));
208
209 const char small_string[] = "Hi!!";
210 static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
211
212#if _FORTIFY_SOURCE > 1
213 // expected-error@+2{{string bigger than buffer}}
214#endif
215 EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
216
217#if _FORTIFY_SOURCE > 1
218 // expected-error@+2{{string bigger than buffer}}
219#endif
220 EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
221
222#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700223 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700224#endif
225 EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(small_string)));
226
227#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700228 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700229#endif
230 EXPECT_FORTIFY_DEATH_STRUCT(stpncpy(split.tiny_buffer, small_string, sizeof(small_string)));
231
232#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700233 // expected-error@+2{{string bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700234#endif
235 EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
236
237#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700238 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700239#endif
240 EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700241
242#if _FORTIFY_SOURCE > 1
243 // expected-error@+2{{size bigger than buffer}}
244#endif
245 EXPECT_FORTIFY_DEATH_STRUCT(strlcat(split.tiny_buffer, small_string, sizeof(small_string)));
246
247#if _FORTIFY_SOURCE > 1
248 // expected-error@+2{{size bigger than buffer}}
249#endif
250 EXPECT_FORTIFY_DEATH_STRUCT(strlcpy(split.tiny_buffer, small_string, sizeof(small_string)));
George Burgess IV9a274102019-06-04 15:39:52 -0700251 }
252}
253
George Burgess IV2356c932019-06-06 17:18:13 -0700254FORTIFY_TEST(fcntl) {
255 const char target[] = "/dev/null";
256 int dirfd = 0;
257
258 // These all emit hard errors without diagnose_if, so running them is a bit
259 // more involved.
260#ifdef COMPILATION_TESTS
261 // expected-error@+1{{too many arguments}}
262 open("/", 0, 0, 0);
263 // expected-error@+1{{too many arguments}}
264 open64("/", 0, 0, 0);
265 // expected-error@+1{{too many arguments}}
266 openat(0, "/", 0, 0, 0);
267 // expected-error@+1{{too many arguments}}
268 openat64(0, "/", 0, 0, 0);
269#endif
270
271 // expected-error@+1{{missing mode}}
272 EXPECT_FORTIFY_DEATH(open(target, O_CREAT));
273 // expected-error@+1{{missing mode}}
274 EXPECT_FORTIFY_DEATH(open(target, O_TMPFILE));
275 // expected-error@+1{{missing mode}}
276 EXPECT_FORTIFY_DEATH(open64(target, O_CREAT));
277 // expected-error@+1{{missing mode}}
278 EXPECT_FORTIFY_DEATH(open64(target, O_TMPFILE));
279 // expected-error@+1{{missing mode}}
280 EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_CREAT));
281 // expected-error@+1{{missing mode}}
282 EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_TMPFILE));
283 // expected-error@+1{{missing mode}}
284 EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_CREAT));
285 // expected-error@+1{{missing mode}}
286 EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_TMPFILE));
287
288 // expected-warning@+1{{superfluous mode bits}}
289 EXPECT_NO_DEATH(open(target, O_RDONLY, 0777));
290 // expected-warning@+1{{superfluous mode bits}}
291 EXPECT_NO_DEATH(open64(target, O_RDONLY, 0777));
292 // expected-warning@+1{{superfluous mode bits}}
293 EXPECT_NO_DEATH(openat(dirfd, target, O_RDONLY, 0777));
294 // expected-warning@+1{{superfluous mode bits}}
295 EXPECT_NO_DEATH(openat64(dirfd, target, O_RDONLY, 0777));
296}
297
George Burgess IV9a274102019-06-04 15:39:52 -0700298// Since these emit hard errors, it's sort of hard to run them...
299#ifdef COMPILATION_TESTS
300namespace compilation_tests {
301template <typename T>
302static T declval() {
303 __builtin_unreachable();
304}
305
George Burgess IV9a274102019-06-04 15:39:52 -0700306static void testFormatStrings() {
307 const auto unsigned_value = declval<unsigned long long>();
308 const auto* unknown_string = declval<const char*>();
George Burgess IV06bb4ce2019-06-13 15:13:02 -0700309 const auto va = *declval<va_list*>();
George Burgess IV9a274102019-06-04 15:39:52 -0700310
311 {
312 auto some_fd = declval<int>();
313 // expected-warning@+1{{format specifies type 'int'}}
314 dprintf(some_fd, "%d", unsigned_value);
315 // expected-warning@+1{{format string is not a string literal}}
316 dprintf(some_fd, unknown_string, unsigned_value);
317 // expected-warning@+1{{format string is not a string literal}}
318 vdprintf(1, unknown_string, va);
319 }
320
321 {
322 auto* retval = declval<char*>();
323#if 0
324 // expected-error@+2{{ignoring return value}}
325#endif
326 // expected-warning@+1{{format specifies type 'int'}}
327 asprintf(&retval, "%d", unsigned_value);
328#if 0
329 // expected-error@+2{{ignoring return value}}
330#endif
331 // expected-warning@+1{{format string is not a string literal}}
332 asprintf(&retval, unknown_string, unsigned_value);
333#if 0
334 // expected-error@+2{{ignoring return value}}
335#endif
336 // expected-warning@+1{{format string is not a string literal}}
337 vasprintf(&retval, unknown_string, va);
338 }
339
340 // expected-warning@+1{{format specifies type 'int'}}
341 syslog(0, "%d", unsigned_value);
342 // expected-warning@+1{{format string is not a string literal}}
343 syslog(0, unknown_string, unsigned_value);
344 // expected-warning@+1{{format string is not a string literal}}
345 vsyslog(0, unknown_string, va);
346
347 {
348 auto* file = declval<FILE*>();
349 // expected-warning@+1{{format specifies type 'int'}}
350 fprintf(file, "%d", unsigned_value);
351 // expected-warning@+1{{format string is not a string literal}}
352 fprintf(file, unknown_string, unsigned_value);
353 // expected-warning@+1{{format string is not a string literal}}
354 vfprintf(file, unknown_string, va);
355 }
356
357 // expected-warning@+1{{format specifies type 'int'}}
358 printf("%d", unsigned_value);
359 // expected-warning@+1{{format string is not a string literal}}
360 printf(unknown_string, unsigned_value);
361 // expected-warning@+1{{format string is not a string literal}}
362 vprintf(unknown_string, va);
363
364 {
365 char buf[128];
366 // expected-warning@+1{{format specifies type 'int'}}
367 sprintf(buf, "%d", unsigned_value);
368 // expected-warning@+1{{format string is not a string literal}}
369 sprintf(buf, unknown_string, unsigned_value);
370 // expected-warning@+1{{format string is not a string literal}}
371 sprintf(buf, unknown_string, va);
372
373 // expected-warning@+1{{format specifies type 'int'}}
374 snprintf(buf, sizeof(buf), "%d", unsigned_value);
375 // expected-warning@+1{{format string is not a string literal}}
376 snprintf(buf, sizeof(buf), unknown_string, unsigned_value);
377 // expected-warning@+1{{format string is not a string literal}}
378 vsnprintf(buf, sizeof(buf), unknown_string, va);
379 }
380
381 // FIXME: below are general format string cases where clang should probably try to warn.
382 {
383 char buf[4];
384 sprintf(buf, "%s", "1234");
385 sprintf(buf, "1%s4", "23");
386 sprintf(buf, "%d", 1234);
387
388 // Similar thoughts for strncpy, etc.
389 }
390}
391
392static void testStdlib() {
393 char path_buffer[PATH_MAX - 1];
394#if 0
395 // expected-error@+2{{ignoring return value of function}}
396#endif
397 // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
398 realpath("/", path_buffer);
399#if 0
400 // expected-error@+1{{ignoring return value of function}}
401#endif
402 realpath("/", nullptr);
403
404 // FIXME: This should complain about flipped arguments, instead of objectsize.
405 // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
406 realpath(nullptr, path_buffer);
407
408 // expected-error@+1{{flipped arguments?}}
409 realpath(nullptr, nullptr);
410}
411} // namespace compilation_tests
412#endif
413
414FORTIFY_TEST(poll) {
415 int pipe_fds[2];
416 if (pipe(pipe_fds)) err(1, "pipe failed");
417
418 // after this, pipe_fds[0] should always report RDHUP
419 if (close(pipe_fds[1])) err(1, "close failed");
420
421 struct pollfd poll_fd = { pipe_fds[0], POLLRDHUP, 0 };
422 {
423 struct pollfd few_fds[] = { poll_fd, poll_fd };
424 // expected-error@+1{{fd_count is larger than the given buffer}}
425 EXPECT_FORTIFY_DEATH(poll(few_fds, 3, 0));
426 // expected-error@+1{{fd_count is larger than the given buffer}}
427 EXPECT_FORTIFY_DEATH(ppoll(few_fds, 3, 0, 0));
428 // expected-error@+1{{fd_count is larger than the given buffer}}
429 EXPECT_FORTIFY_DEATH(ppoll64(few_fds, 3, 0, nullptr));
430 }
431
432 {
433 struct {
434 struct pollfd few[2];
435 struct pollfd extra[1];
436 } fds = { { poll_fd, poll_fd }, { poll_fd } };
437 static_assert(sizeof(fds) >= sizeof(struct pollfd) * 3, "");
438
439#if _FORTIFY_SOURCE > 1
440 // expected-error@+2{{fd_count is larger than the given buffer}}
441#endif
442 EXPECT_FORTIFY_DEATH_STRUCT(poll(fds.few, 3, 0));
443
444 struct timespec timeout = {};
445#if _FORTIFY_SOURCE > 1
446 // expected-error@+2{{fd_count is larger than the given buffer}}
447#endif
448 EXPECT_FORTIFY_DEATH_STRUCT(ppoll(fds.few, 3, &timeout, 0));
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(ppoll64(fds.few, 3, 0, nullptr));
454 }
455}
456
457FORTIFY_TEST(socket) {
458 {
459 char small_buffer[8];
460 // expected-error@+1{{size bigger than buffer}}
461 EXPECT_FORTIFY_DEATH(recv(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
462 // expected-error@+1{{size bigger than buffer}}
463 EXPECT_FORTIFY_DEATH(recvfrom(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
464
465 // expected-error@+1{{size bigger than buffer}}
466 EXPECT_FORTIFY_DEATH(send(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
467 // expected-error@+1{{size bigger than buffer}}
468 EXPECT_FORTIFY_DEATH(sendto(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
469 }
470
471 {
472 struct {
473 char tiny_buffer[4];
474 char tiny_buffer2;
475 } split = {};
476
477 EXPECT_NO_DEATH(recv(kBogusFD, split.tiny_buffer, sizeof(split), 0));
478 EXPECT_NO_DEATH(recvfrom(kBogusFD, split.tiny_buffer, sizeof(split), 0, 0, 0));
479 }
480}
481
482FORTIFY_TEST(sys_stat) {
483 // expected-error@+1{{'umask' called with invalid mode}}
484 EXPECT_FORTIFY_DEATH(umask(01777));
485}
486
487FORTIFY_TEST(stdio) {
488 char small_buffer[8] = {};
489 {
490#if 0
491 // expected-error@+1{{may overflow the destination buffer}}
492#endif
493 EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
494
495 va_list va;
496#if 0
497 // expected-error@+1{{may overflow the destination buffer}}
498#endif
499 // expected-warning@+1{{format string is empty}}
500 EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
501 }
502
503 // expected-error@+1{{size should not be negative}}
504 EXPECT_FORTIFY_DEATH(fgets(small_buffer, -1, stdin));
505 // expected-error@+1{{size is larger than the destination buffer}}
506 EXPECT_FORTIFY_DEATH(fgets(small_buffer, sizeof(small_buffer) + 1, stdin));
507
508 // expected-error@+1{{size * count overflows}}
509 EXPECT_NO_DEATH(fread(small_buffer, 2, (size_t)-1, stdin));
510 // expected-error@+1{{size * count is too large for the given buffer}}
511 EXPECT_FORTIFY_DEATH(fread(small_buffer, 1, sizeof(small_buffer) + 1, stdin));
512
513 // expected-error@+1{{size * count overflows}}
514 EXPECT_NO_DEATH(fwrite(small_buffer, 2, (size_t)-1, stdout));
515 // expected-error@+1{{size * count is too large for the given buffer}}
516 EXPECT_FORTIFY_DEATH(fwrite(small_buffer, 1, sizeof(small_buffer) + 1, stdout));
517}
518
519FORTIFY_TEST(unistd) {
520 char small_buffer[8];
521
522 // Return value warnings are (sort of) a part of FORTIFY, so we don't ignore them.
523#if 0
524 // expected-error@+2{{ignoring return value of function}}
525#endif
526 // expected-error@+1{{bytes overflows the given object}}
527 EXPECT_FORTIFY_DEATH(read(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
528#if 0
529 // expected-error@+2{{ignoring return value of function}}
530#endif
531 // expected-error@+1{{bytes overflows the given object}}
532 EXPECT_FORTIFY_DEATH(pread(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
533#if 0
534 // expected-error@+2{{ignoring return value of function}}
535#endif
536 // expected-error@+1{{bytes overflows the given object}}
537 EXPECT_FORTIFY_DEATH(pread64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
538#if 0
539 // expected-error@+2{{ignoring return value of function}}
540#endif
541 // expected-error@+1{{bytes overflows the given object}}
542 EXPECT_FORTIFY_DEATH(write(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
543#if 0
544 // expected-error@+2{{ignoring return value of function}}
545#endif
546 // expected-error@+1{{bytes overflows the given object}}
547 EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
548#if 0
549 // expected-error@+2{{ignoring return value of function}}
550#endif
551 // expected-error@+1{{bytes overflows the given object}}
552 EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
553#if 0
554 // expected-error@+2{{ignoring return value of function}}
555#endif
556 // expected-error@+1{{bytes overflows the given object}}
557 EXPECT_FORTIFY_DEATH(readlink("/", small_buffer, sizeof(small_buffer) + 1));
558#if 0
559 // expected-error@+2{{ignoring return value of function}}
560#endif
561 // expected-error@+1{{bytes overflows the given object}}
562 EXPECT_FORTIFY_DEATH(getcwd(small_buffer, sizeof(small_buffer) + 1));
563
564 // getcwd allocates and returns a buffer if you pass null to getcwd
565 EXPECT_NO_DEATH(getcwd(nullptr, 0));
566 EXPECT_NO_DEATH(getcwd(nullptr, 4096));
567
568 struct {
569 char tiny_buffer[4];
570 char tiny_buffer2[4];
571 } split;
572
573 EXPECT_NO_DEATH(read(kBogusFD, split.tiny_buffer, sizeof(split)));
574 EXPECT_NO_DEATH(pread(kBogusFD, split.tiny_buffer, sizeof(split), 0));
575 EXPECT_NO_DEATH(pread64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
576 EXPECT_NO_DEATH(write(kBogusFD, split.tiny_buffer, sizeof(split)));
577 EXPECT_NO_DEATH(pwrite(kBogusFD, split.tiny_buffer, sizeof(split), 0));
578 EXPECT_NO_DEATH(pwrite64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
579
580#if _FORTIFY_SOURCE > 1
581 // expected-error@+2{{bytes overflows the given object}}
582#endif
583 EXPECT_FORTIFY_DEATH_STRUCT(readlink("/", split.tiny_buffer, sizeof(split)));
584#if _FORTIFY_SOURCE > 1
585 // expected-error@+2{{bytes overflows the given object}}
586#endif
587 EXPECT_FORTIFY_DEATH_STRUCT(getcwd(split.tiny_buffer, sizeof(split)));
588
589 {
590 // FIXME: These should all die in FORTIFY. Headers are bugged.
591#ifdef COMPILATION_TESTS
592 char* volatile unknown = small_buffer;
593 const size_t count = static_cast<size_t>(SSIZE_MAX) + 1;
594 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
595 EXPECT_FORTIFY_DEATH(read(kBogusFD, unknown, count));
596 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
597 EXPECT_FORTIFY_DEATH(pread(kBogusFD, unknown, count, 0));
598 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
599 EXPECT_FORTIFY_DEATH(pread64(kBogusFD, unknown, count, 0));
600 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
601 EXPECT_FORTIFY_DEATH(write(kBogusFD, unknown, count));
602 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
603 EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, unknown, count, 0));
604 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
605 EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, unknown, count, 0));
606#endif
607 }
608}
609
610#endif // defined(__BIONIC__)