blob: 692330278141b5fe00c5a89e917c89530a260084 [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
Yi Kongbf67ea52019-08-03 18:26:05 -070039// FIXME(b/138701943): Silence warnings produced by -Wfortify-source since they're expected.
40// expected-warning@* 0+{{will always overflow}}
41// expected-warning@* 0+{{size argument is too large}}
42// expected-note@* 0+{{has been explicitly marked unavailable here}}
43
George Burgess IV9a274102019-06-04 15:39:52 -070044#ifndef _FORTIFY_SOURCE
45#error "_FORTIFY_SOURCE must be defined"
46#endif
47
48#include <sys/cdefs.h>
49
50// This is a test specifically of bionic's FORTIFY machinery. Other stdlibs need not apply.
51#ifndef __BIONIC__
52// expected-no-diagnostics
53#else
54
55// As alluded to above, we're going to be doing some obviously very broken things in this file.
56// FORTIFY helpfully flags a lot of it at compile-time, but we want it to *actually* crash, too. So
57// let's wipe out any build-time errors.
58#ifndef COMPILATION_TESTS
59#undef __clang_error_if
60#define __clang_error_if(...)
61#undef __clang_warning_if
62#define __clang_warning_if(...)
George Burgess IV26d25a22019-06-06 17:45:05 -070063
64// SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but
65// blocks them otherwise. This is needed for diagnostics emitted with __enable_if.
66#define SOMETIMES_CONST volatile
67#else
68#define SOMETIMES_CONST const
George Burgess IV9a274102019-06-04 15:39:52 -070069#endif
70
71#include <err.h>
72#include <fcntl.h>
73#include <limits.h>
74#include <poll.h>
75#include <signal.h>
76#include <stdio.h>
77#include <stdlib.h>
78#include <string.h>
79#include <sys/socket.h>
80#include <sys/stat.h>
81#include <sys/wait.h>
82#include <syslog.h>
83#include <unistd.h>
84#include <wchar.h>
85
86#ifndef COMPILATION_TESTS
87#include <gtest/gtest.h>
88#include "BionicDeathTest.h"
89
90#define CONCAT2(x, y) x##y
91#define CONCAT(x, y) CONCAT2(x, y)
92#define FORTIFY_TEST_NAME CONCAT(clang_fortify_test_, _FORTIFY_SOURCE)
93
94namespace {
95struct FORTIFY_TEST_NAME : BionicDeathTest {
96 protected:
97 void SetUp() override {
98 stdin_saved = dup(STDIN_FILENO);
99 if (stdin_saved < 0) err(1, "failed to dup stdin");
100
101 int devnull = open("/dev/null", O_RDONLY);
102 if (devnull < 0) err(1, "failed to open /dev/null");
103
104 if (!dup2(devnull, STDIN_FILENO)) err(1, "failed to overwrite stdin");
105 static_cast<void>(close(devnull));
106
107 BionicDeathTest::SetUp();
108 }
109
110 void TearDown() override {
111 if (stdin_saved == -1) return;
112 if (!dup2(stdin_saved, STDIN_FILENO)) warn("failed to restore stdin");
113
114 static_cast<void>(close(stdin_saved));
115
116 BionicDeathTest::TearDown();
117 }
118
119 private:
120 int stdin_saved = -1;
121};
122} // namespace
123
124template <typename Fn>
125__attribute__((noreturn)) static void ExitAfter(Fn&& f) {
126 f();
127 // No need to tear things down; our parent process should handle that.
128 _exit(0);
129}
130
131// In any case (including failing tests), we always want to die after this.
132#define DIE_WITH(expr, cond, regex) EXPECT_EXIT(ExitAfter([&] { (expr); }), cond, regex)
133
134// EXPECT_NO_DEATH forks so that the test remains alive on a bug, and so that the environment
135// doesn't get modified on no bug. (Environment modification is especially tricky to deal with given
136// the *_STRUCT variants below.)
137#define EXPECT_NO_DEATH(expr) DIE_WITH(expr, testing::ExitedWithCode(0), "")
138#define EXPECT_FORTIFY_DEATH(expr) DIE_WITH(expr, testing::KilledBySignal(SIGABRT), "FORTIFY")
139// Expecting death, but only if we're doing a "strict" struct-checking mode.
140#if _FORTIFY_SOURCE > 1
141#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH
142#else
143#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_NO_DEATH
144#endif
145
146#define FORTIFY_TEST(test_name) TEST(FORTIFY_TEST_NAME, test_name)
147
148#else // defined(COMPILATION_TESTS)
149
150#define EXPECT_NO_DEATH(expr) expr
151#define EXPECT_FORTIFY_DEATH(expr) expr
152#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH
153#define FORTIFY_TEST(test_name) void test_name()
154#endif
155
156const static int kBogusFD = -1;
157
158FORTIFY_TEST(string) {
159 char small_buffer[8] = {};
160
161 {
162 char large_buffer[sizeof(small_buffer) + 1] = {};
163 // expected-error@+1{{size bigger than buffer}}
164 EXPECT_FORTIFY_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer)));
165 // expected-error@+1{{size bigger than buffer}}
166 EXPECT_FORTIFY_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer)));
George Burgess IV849c0b92019-06-10 16:22:09 -0700167 // expected-error@+1{{size bigger than buffer}}
168 EXPECT_FORTIFY_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer)));
George Burgess IV9a274102019-06-04 15:39:52 -0700169 // expected-error@+1{{size bigger than buffer}}
170 EXPECT_FORTIFY_DEATH(memset(small_buffer, 0, sizeof(large_buffer)));
171 // expected-warning@+1{{arguments got flipped?}}
172 EXPECT_NO_DEATH(memset(small_buffer, sizeof(small_buffer), 0));
George Burgess IV261b7f42019-06-10 16:32:07 -0700173 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700174 EXPECT_FORTIFY_DEATH(bcopy(large_buffer, small_buffer, sizeof(large_buffer)));
George Burgess IV261b7f42019-06-10 16:32:07 -0700175 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700176 EXPECT_FORTIFY_DEATH(bzero(small_buffer, sizeof(large_buffer)));
177 }
178
179 {
180 const char large_string[] = "Hello!!!";
181 static_assert(sizeof(large_string) > sizeof(small_buffer), "");
182
183 // expected-error@+1{{string bigger than buffer}}
184 EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
185 // expected-error@+1{{string bigger than buffer}}
186 EXPECT_FORTIFY_DEATH(stpcpy(small_buffer, large_string));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700187 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700188 EXPECT_FORTIFY_DEATH(strncpy(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700189 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700190 EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700191 // expected-error@+1{{string bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700192 EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700193 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700194 EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700195 // expected-error@+1{{size bigger than buffer}}
196 EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string)));
197 // expected-error@+1{{size bigger than buffer}}
198 EXPECT_FORTIFY_DEATH(strlcat(small_buffer, large_string, sizeof(large_string)));
George Burgess IV9a274102019-06-04 15:39:52 -0700199 }
200
201 {
202 struct {
203 char tiny_buffer[4];
204 char tiny_buffer2[4];
205 } split = {};
206
207 EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
208 EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
209 EXPECT_NO_DEATH(memmove(split.tiny_buffer, &split, sizeof(split)));
210 EXPECT_NO_DEATH(mempcpy(split.tiny_buffer, &split, sizeof(split)));
211 EXPECT_NO_DEATH(memset(split.tiny_buffer, 0, sizeof(split)));
212
213 EXPECT_NO_DEATH(bcopy(&split, split.tiny_buffer, sizeof(split)));
214 EXPECT_NO_DEATH(bzero(split.tiny_buffer, sizeof(split)));
215
216 const char small_string[] = "Hi!!";
217 static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
218
219#if _FORTIFY_SOURCE > 1
220 // expected-error@+2{{string bigger than buffer}}
221#endif
222 EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
223
224#if _FORTIFY_SOURCE > 1
225 // expected-error@+2{{string bigger than buffer}}
226#endif
227 EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
228
229#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700230 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700231#endif
232 EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(small_string)));
233
234#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700235 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700236#endif
237 EXPECT_FORTIFY_DEATH_STRUCT(stpncpy(split.tiny_buffer, small_string, sizeof(small_string)));
238
239#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700240 // expected-error@+2{{string bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700241#endif
242 EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
243
244#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700245 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700246#endif
247 EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700248
249#if _FORTIFY_SOURCE > 1
250 // expected-error@+2{{size bigger than buffer}}
251#endif
252 EXPECT_FORTIFY_DEATH_STRUCT(strlcat(split.tiny_buffer, small_string, sizeof(small_string)));
253
254#if _FORTIFY_SOURCE > 1
255 // expected-error@+2{{size bigger than buffer}}
256#endif
257 EXPECT_FORTIFY_DEATH_STRUCT(strlcpy(split.tiny_buffer, small_string, sizeof(small_string)));
George Burgess IV9a274102019-06-04 15:39:52 -0700258 }
259}
260
George Burgess IV2356c932019-06-06 17:18:13 -0700261FORTIFY_TEST(fcntl) {
262 const char target[] = "/dev/null";
263 int dirfd = 0;
264
265 // These all emit hard errors without diagnose_if, so running them is a bit
266 // more involved.
267#ifdef COMPILATION_TESTS
268 // expected-error@+1{{too many arguments}}
269 open("/", 0, 0, 0);
270 // expected-error@+1{{too many arguments}}
271 open64("/", 0, 0, 0);
272 // expected-error@+1{{too many arguments}}
273 openat(0, "/", 0, 0, 0);
274 // expected-error@+1{{too many arguments}}
275 openat64(0, "/", 0, 0, 0);
276#endif
277
278 // expected-error@+1{{missing mode}}
279 EXPECT_FORTIFY_DEATH(open(target, O_CREAT));
280 // expected-error@+1{{missing mode}}
281 EXPECT_FORTIFY_DEATH(open(target, O_TMPFILE));
282 // expected-error@+1{{missing mode}}
283 EXPECT_FORTIFY_DEATH(open64(target, O_CREAT));
284 // expected-error@+1{{missing mode}}
285 EXPECT_FORTIFY_DEATH(open64(target, O_TMPFILE));
286 // expected-error@+1{{missing mode}}
287 EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_CREAT));
288 // expected-error@+1{{missing mode}}
289 EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_TMPFILE));
290 // expected-error@+1{{missing mode}}
291 EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_CREAT));
292 // expected-error@+1{{missing mode}}
293 EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_TMPFILE));
294
295 // expected-warning@+1{{superfluous mode bits}}
296 EXPECT_NO_DEATH(open(target, O_RDONLY, 0777));
297 // expected-warning@+1{{superfluous mode bits}}
298 EXPECT_NO_DEATH(open64(target, O_RDONLY, 0777));
299 // expected-warning@+1{{superfluous mode bits}}
300 EXPECT_NO_DEATH(openat(dirfd, target, O_RDONLY, 0777));
301 // expected-warning@+1{{superfluous mode bits}}
302 EXPECT_NO_DEATH(openat64(dirfd, target, O_RDONLY, 0777));
303}
304
George Burgess IV9a274102019-06-04 15:39:52 -0700305// Since these emit hard errors, it's sort of hard to run them...
306#ifdef COMPILATION_TESTS
307namespace compilation_tests {
308template <typename T>
309static T declval() {
310 __builtin_unreachable();
311}
312
George Burgess IV9a274102019-06-04 15:39:52 -0700313static void testFormatStrings() {
314 const auto unsigned_value = declval<unsigned long long>();
315 const auto* unknown_string = declval<const char*>();
George Burgess IV06bb4ce2019-06-13 15:13:02 -0700316 const auto va = *declval<va_list*>();
George Burgess IV9a274102019-06-04 15:39:52 -0700317
318 {
319 auto some_fd = declval<int>();
320 // expected-warning@+1{{format specifies type 'int'}}
321 dprintf(some_fd, "%d", unsigned_value);
322 // expected-warning@+1{{format string is not a string literal}}
323 dprintf(some_fd, unknown_string, unsigned_value);
324 // expected-warning@+1{{format string is not a string literal}}
325 vdprintf(1, unknown_string, va);
326 }
327
328 {
329 auto* retval = declval<char*>();
330#if 0
331 // expected-error@+2{{ignoring return value}}
332#endif
333 // expected-warning@+1{{format specifies type 'int'}}
334 asprintf(&retval, "%d", unsigned_value);
335#if 0
336 // expected-error@+2{{ignoring return value}}
337#endif
338 // expected-warning@+1{{format string is not a string literal}}
339 asprintf(&retval, unknown_string, unsigned_value);
340#if 0
341 // expected-error@+2{{ignoring return value}}
342#endif
343 // expected-warning@+1{{format string is not a string literal}}
344 vasprintf(&retval, unknown_string, va);
345 }
346
347 // expected-warning@+1{{format specifies type 'int'}}
348 syslog(0, "%d", unsigned_value);
349 // expected-warning@+1{{format string is not a string literal}}
350 syslog(0, unknown_string, unsigned_value);
351 // expected-warning@+1{{format string is not a string literal}}
352 vsyslog(0, unknown_string, va);
353
354 {
355 auto* file = declval<FILE*>();
356 // expected-warning@+1{{format specifies type 'int'}}
357 fprintf(file, "%d", unsigned_value);
358 // expected-warning@+1{{format string is not a string literal}}
359 fprintf(file, unknown_string, unsigned_value);
360 // expected-warning@+1{{format string is not a string literal}}
361 vfprintf(file, unknown_string, va);
362 }
363
364 // expected-warning@+1{{format specifies type 'int'}}
365 printf("%d", unsigned_value);
366 // expected-warning@+1{{format string is not a string literal}}
367 printf(unknown_string, unsigned_value);
368 // expected-warning@+1{{format string is not a string literal}}
369 vprintf(unknown_string, va);
370
371 {
372 char buf[128];
373 // expected-warning@+1{{format specifies type 'int'}}
374 sprintf(buf, "%d", unsigned_value);
375 // expected-warning@+1{{format string is not a string literal}}
376 sprintf(buf, unknown_string, unsigned_value);
377 // expected-warning@+1{{format string is not a string literal}}
378 sprintf(buf, unknown_string, va);
379
380 // expected-warning@+1{{format specifies type 'int'}}
381 snprintf(buf, sizeof(buf), "%d", unsigned_value);
382 // expected-warning@+1{{format string is not a string literal}}
383 snprintf(buf, sizeof(buf), unknown_string, unsigned_value);
384 // expected-warning@+1{{format string is not a string literal}}
385 vsnprintf(buf, sizeof(buf), unknown_string, va);
386 }
387
388 // FIXME: below are general format string cases where clang should probably try to warn.
389 {
390 char buf[4];
391 sprintf(buf, "%s", "1234");
392 sprintf(buf, "1%s4", "23");
393 sprintf(buf, "%d", 1234);
394
395 // Similar thoughts for strncpy, etc.
396 }
397}
398
399static void testStdlib() {
400 char path_buffer[PATH_MAX - 1];
George Burgess IV8c0ec112019-06-06 17:23:32 -0700401 // expected-warning@+2{{ignoring return value of function}}
George Burgess IV9a274102019-06-04 15:39:52 -0700402 // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
403 realpath("/", path_buffer);
George Burgess IV8c0ec112019-06-06 17:23:32 -0700404 // expected-warning@+1{{ignoring return value of function}}
George Burgess IV9a274102019-06-04 15:39:52 -0700405 realpath("/", nullptr);
406
George Burgess IV8c0ec112019-06-06 17:23:32 -0700407 // expected-warning@+2{{ignoring return value of function}}
408 // expected-error@+1{{flipped arguments?}}
George Burgess IV9a274102019-06-04 15:39:52 -0700409 realpath(nullptr, path_buffer);
410
George Burgess IV8c0ec112019-06-06 17:23:32 -0700411 // expected-warning@+2{{ignoring return value of function}}
George Burgess IV9a274102019-06-04 15:39:52 -0700412 // expected-error@+1{{flipped arguments?}}
413 realpath(nullptr, nullptr);
414}
415} // namespace compilation_tests
416#endif
417
418FORTIFY_TEST(poll) {
419 int pipe_fds[2];
420 if (pipe(pipe_fds)) err(1, "pipe failed");
421
422 // after this, pipe_fds[0] should always report RDHUP
423 if (close(pipe_fds[1])) err(1, "close failed");
424
425 struct pollfd poll_fd = { pipe_fds[0], POLLRDHUP, 0 };
426 {
427 struct pollfd few_fds[] = { poll_fd, poll_fd };
428 // expected-error@+1{{fd_count is larger than the given buffer}}
429 EXPECT_FORTIFY_DEATH(poll(few_fds, 3, 0));
430 // expected-error@+1{{fd_count is larger than the given buffer}}
431 EXPECT_FORTIFY_DEATH(ppoll(few_fds, 3, 0, 0));
432 // expected-error@+1{{fd_count is larger than the given buffer}}
433 EXPECT_FORTIFY_DEATH(ppoll64(few_fds, 3, 0, nullptr));
434 }
435
436 {
437 struct {
438 struct pollfd few[2];
439 struct pollfd extra[1];
440 } fds = { { poll_fd, poll_fd }, { poll_fd } };
441 static_assert(sizeof(fds) >= sizeof(struct pollfd) * 3, "");
442
443#if _FORTIFY_SOURCE > 1
444 // expected-error@+2{{fd_count is larger than the given buffer}}
445#endif
446 EXPECT_FORTIFY_DEATH_STRUCT(poll(fds.few, 3, 0));
447
448 struct timespec timeout = {};
449#if _FORTIFY_SOURCE > 1
450 // expected-error@+2{{fd_count is larger than the given buffer}}
451#endif
452 EXPECT_FORTIFY_DEATH_STRUCT(ppoll(fds.few, 3, &timeout, 0));
453
454#if _FORTIFY_SOURCE > 1
455 // expected-error@+2{{fd_count is larger than the given buffer}}
456#endif
457 EXPECT_FORTIFY_DEATH_STRUCT(ppoll64(fds.few, 3, 0, nullptr));
458 }
459}
460
461FORTIFY_TEST(socket) {
462 {
463 char small_buffer[8];
464 // expected-error@+1{{size bigger than buffer}}
465 EXPECT_FORTIFY_DEATH(recv(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
466 // expected-error@+1{{size bigger than buffer}}
467 EXPECT_FORTIFY_DEATH(recvfrom(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
468
469 // expected-error@+1{{size bigger than buffer}}
470 EXPECT_FORTIFY_DEATH(send(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
471 // expected-error@+1{{size bigger than buffer}}
472 EXPECT_FORTIFY_DEATH(sendto(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
473 }
474
475 {
476 struct {
477 char tiny_buffer[4];
478 char tiny_buffer2;
479 } split = {};
480
481 EXPECT_NO_DEATH(recv(kBogusFD, split.tiny_buffer, sizeof(split), 0));
482 EXPECT_NO_DEATH(recvfrom(kBogusFD, split.tiny_buffer, sizeof(split), 0, 0, 0));
483 }
484}
485
486FORTIFY_TEST(sys_stat) {
487 // expected-error@+1{{'umask' called with invalid mode}}
488 EXPECT_FORTIFY_DEATH(umask(01777));
489}
490
491FORTIFY_TEST(stdio) {
492 char small_buffer[8] = {};
493 {
George Burgess IV26d25a22019-06-06 17:45:05 -0700494 // expected-error@+1{{size is larger than the destination buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700495 EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
496
497 va_list va;
George Burgess IV26d25a22019-06-06 17:45:05 -0700498 // expected-error@+2{{size is larger than the destination buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700499 // expected-warning@+1{{format string is empty}}
500 EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
George Burgess IV26d25a22019-06-06 17:45:05 -0700501
502 const char *SOMETIMES_CONST format_string = "aaaaaaaaa";
503
504 // expected-error@+1{{format string will always overflow}}
505 EXPECT_FORTIFY_DEATH(sprintf(small_buffer, format_string));
George Burgess IV9a274102019-06-04 15:39:52 -0700506 }
507
508 // expected-error@+1{{size should not be negative}}
509 EXPECT_FORTIFY_DEATH(fgets(small_buffer, -1, stdin));
510 // expected-error@+1{{size is larger than the destination buffer}}
511 EXPECT_FORTIFY_DEATH(fgets(small_buffer, sizeof(small_buffer) + 1, stdin));
512
513 // expected-error@+1{{size * count overflows}}
514 EXPECT_NO_DEATH(fread(small_buffer, 2, (size_t)-1, stdin));
515 // expected-error@+1{{size * count is too large for the given buffer}}
516 EXPECT_FORTIFY_DEATH(fread(small_buffer, 1, sizeof(small_buffer) + 1, stdin));
517
518 // expected-error@+1{{size * count overflows}}
519 EXPECT_NO_DEATH(fwrite(small_buffer, 2, (size_t)-1, stdout));
520 // expected-error@+1{{size * count is too large for the given buffer}}
521 EXPECT_FORTIFY_DEATH(fwrite(small_buffer, 1, sizeof(small_buffer) + 1, stdout));
522}
523
524FORTIFY_TEST(unistd) {
525 char small_buffer[8];
526
527 // Return value warnings are (sort of) a part of FORTIFY, so we don't ignore them.
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(read(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
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(pread(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(pread64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
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(write(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
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(pwrite(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(pwrite64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
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(readlink("/", small_buffer, sizeof(small_buffer) + 1));
563#if 0
564 // expected-error@+2{{ignoring return value of function}}
565#endif
566 // expected-error@+1{{bytes overflows the given object}}
567 EXPECT_FORTIFY_DEATH(getcwd(small_buffer, sizeof(small_buffer) + 1));
568
569 // getcwd allocates and returns a buffer if you pass null to getcwd
570 EXPECT_NO_DEATH(getcwd(nullptr, 0));
571 EXPECT_NO_DEATH(getcwd(nullptr, 4096));
572
573 struct {
574 char tiny_buffer[4];
575 char tiny_buffer2[4];
576 } split;
577
578 EXPECT_NO_DEATH(read(kBogusFD, split.tiny_buffer, sizeof(split)));
579 EXPECT_NO_DEATH(pread(kBogusFD, split.tiny_buffer, sizeof(split), 0));
580 EXPECT_NO_DEATH(pread64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
581 EXPECT_NO_DEATH(write(kBogusFD, split.tiny_buffer, sizeof(split)));
582 EXPECT_NO_DEATH(pwrite(kBogusFD, split.tiny_buffer, sizeof(split), 0));
583 EXPECT_NO_DEATH(pwrite64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
584
585#if _FORTIFY_SOURCE > 1
586 // expected-error@+2{{bytes overflows the given object}}
587#endif
588 EXPECT_FORTIFY_DEATH_STRUCT(readlink("/", split.tiny_buffer, sizeof(split)));
589#if _FORTIFY_SOURCE > 1
590 // expected-error@+2{{bytes overflows the given object}}
591#endif
592 EXPECT_FORTIFY_DEATH_STRUCT(getcwd(split.tiny_buffer, sizeof(split)));
593
594 {
George Burgess IV9a274102019-06-04 15:39:52 -0700595 char* volatile unknown = small_buffer;
596 const size_t count = static_cast<size_t>(SSIZE_MAX) + 1;
597 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
598 EXPECT_FORTIFY_DEATH(read(kBogusFD, unknown, count));
599 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
600 EXPECT_FORTIFY_DEATH(pread(kBogusFD, unknown, count, 0));
601 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
602 EXPECT_FORTIFY_DEATH(pread64(kBogusFD, unknown, count, 0));
603 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
604 EXPECT_FORTIFY_DEATH(write(kBogusFD, unknown, count));
605 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
606 EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, unknown, count, 0));
607 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
608 EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, unknown, count, 0));
George Burgess IV9a274102019-06-04 15:39:52 -0700609 }
610}
611
612#endif // defined(__BIONIC__)