blob: 1b6b898d5a8c67c55fefcbb366345e15194dc349 [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(...)
George Burgess IV26d25a22019-06-06 17:45:05 -070058
59// SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but
60// blocks them otherwise. This is needed for diagnostics emitted with __enable_if.
61#define SOMETIMES_CONST volatile
62#else
63#define SOMETIMES_CONST const
George Burgess IV9a274102019-06-04 15:39:52 -070064#endif
65
66#include <err.h>
67#include <fcntl.h>
68#include <limits.h>
69#include <poll.h>
70#include <signal.h>
71#include <stdio.h>
72#include <stdlib.h>
73#include <string.h>
74#include <sys/socket.h>
75#include <sys/stat.h>
76#include <sys/wait.h>
77#include <syslog.h>
78#include <unistd.h>
79#include <wchar.h>
80
81#ifndef COMPILATION_TESTS
82#include <gtest/gtest.h>
83#include "BionicDeathTest.h"
84
85#define CONCAT2(x, y) x##y
86#define CONCAT(x, y) CONCAT2(x, y)
87#define FORTIFY_TEST_NAME CONCAT(clang_fortify_test_, _FORTIFY_SOURCE)
88
89namespace {
90struct FORTIFY_TEST_NAME : BionicDeathTest {
91 protected:
92 void SetUp() override {
93 stdin_saved = dup(STDIN_FILENO);
94 if (stdin_saved < 0) err(1, "failed to dup stdin");
95
96 int devnull = open("/dev/null", O_RDONLY);
97 if (devnull < 0) err(1, "failed to open /dev/null");
98
99 if (!dup2(devnull, STDIN_FILENO)) err(1, "failed to overwrite stdin");
100 static_cast<void>(close(devnull));
101
102 BionicDeathTest::SetUp();
103 }
104
105 void TearDown() override {
106 if (stdin_saved == -1) return;
107 if (!dup2(stdin_saved, STDIN_FILENO)) warn("failed to restore stdin");
108
109 static_cast<void>(close(stdin_saved));
110
111 BionicDeathTest::TearDown();
112 }
113
114 private:
115 int stdin_saved = -1;
116};
117} // namespace
118
119template <typename Fn>
120__attribute__((noreturn)) static void ExitAfter(Fn&& f) {
121 f();
122 // No need to tear things down; our parent process should handle that.
123 _exit(0);
124}
125
126// In any case (including failing tests), we always want to die after this.
127#define DIE_WITH(expr, cond, regex) EXPECT_EXIT(ExitAfter([&] { (expr); }), cond, regex)
128
129// EXPECT_NO_DEATH forks so that the test remains alive on a bug, and so that the environment
130// doesn't get modified on no bug. (Environment modification is especially tricky to deal with given
131// the *_STRUCT variants below.)
132#define EXPECT_NO_DEATH(expr) DIE_WITH(expr, testing::ExitedWithCode(0), "")
133#define EXPECT_FORTIFY_DEATH(expr) DIE_WITH(expr, testing::KilledBySignal(SIGABRT), "FORTIFY")
134// Expecting death, but only if we're doing a "strict" struct-checking mode.
135#if _FORTIFY_SOURCE > 1
136#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH
137#else
138#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_NO_DEATH
139#endif
140
141#define FORTIFY_TEST(test_name) TEST(FORTIFY_TEST_NAME, test_name)
142
143#else // defined(COMPILATION_TESTS)
144
145#define EXPECT_NO_DEATH(expr) expr
146#define EXPECT_FORTIFY_DEATH(expr) expr
147#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH
148#define FORTIFY_TEST(test_name) void test_name()
149#endif
150
151const static int kBogusFD = -1;
152
153FORTIFY_TEST(string) {
154 char small_buffer[8] = {};
155
156 {
157 char large_buffer[sizeof(small_buffer) + 1] = {};
158 // expected-error@+1{{size bigger than buffer}}
159 EXPECT_FORTIFY_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer)));
160 // expected-error@+1{{size bigger than buffer}}
161 EXPECT_FORTIFY_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer)));
George Burgess IV849c0b92019-06-10 16:22:09 -0700162 // expected-error@+1{{size bigger than buffer}}
163 EXPECT_FORTIFY_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer)));
George Burgess IV9a274102019-06-04 15:39:52 -0700164 // expected-error@+1{{size bigger than buffer}}
165 EXPECT_FORTIFY_DEATH(memset(small_buffer, 0, sizeof(large_buffer)));
166 // expected-warning@+1{{arguments got flipped?}}
167 EXPECT_NO_DEATH(memset(small_buffer, sizeof(small_buffer), 0));
George Burgess IV261b7f42019-06-10 16:32:07 -0700168 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700169 EXPECT_FORTIFY_DEATH(bcopy(large_buffer, small_buffer, sizeof(large_buffer)));
George Burgess IV261b7f42019-06-10 16:32:07 -0700170 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700171 EXPECT_FORTIFY_DEATH(bzero(small_buffer, sizeof(large_buffer)));
172 }
173
174 {
175 const char large_string[] = "Hello!!!";
176 static_assert(sizeof(large_string) > sizeof(small_buffer), "");
177
178 // expected-error@+1{{string bigger than buffer}}
179 EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
180 // expected-error@+1{{string bigger than buffer}}
181 EXPECT_FORTIFY_DEATH(stpcpy(small_buffer, 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(strncpy(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700184 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700185 EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700186 // expected-error@+1{{string bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700187 EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700188 // expected-error@+1{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700189 EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700190 // expected-error@+1{{size bigger than buffer}}
191 EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string)));
192 // expected-error@+1{{size bigger than buffer}}
193 EXPECT_FORTIFY_DEATH(strlcat(small_buffer, large_string, sizeof(large_string)));
George Burgess IV9a274102019-06-04 15:39:52 -0700194 }
195
196 {
197 struct {
198 char tiny_buffer[4];
199 char tiny_buffer2[4];
200 } split = {};
201
202 EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
203 EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
204 EXPECT_NO_DEATH(memmove(split.tiny_buffer, &split, sizeof(split)));
205 EXPECT_NO_DEATH(mempcpy(split.tiny_buffer, &split, sizeof(split)));
206 EXPECT_NO_DEATH(memset(split.tiny_buffer, 0, sizeof(split)));
207
208 EXPECT_NO_DEATH(bcopy(&split, split.tiny_buffer, sizeof(split)));
209 EXPECT_NO_DEATH(bzero(split.tiny_buffer, sizeof(split)));
210
211 const char small_string[] = "Hi!!";
212 static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
213
214#if _FORTIFY_SOURCE > 1
215 // expected-error@+2{{string bigger than buffer}}
216#endif
217 EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
218
219#if _FORTIFY_SOURCE > 1
220 // expected-error@+2{{string bigger than buffer}}
221#endif
222 EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
223
224#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700225 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700226#endif
227 EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(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(stpncpy(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{{string bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700236#endif
237 EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
238
239#if _FORTIFY_SOURCE > 1
George Burgess IV77f99aa2019-06-06 14:14:52 -0700240 // expected-error@+2{{size bigger than buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700241#endif
242 EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string)));
George Burgess IV77f99aa2019-06-06 14:14:52 -0700243
244#if _FORTIFY_SOURCE > 1
245 // expected-error@+2{{size bigger than buffer}}
246#endif
247 EXPECT_FORTIFY_DEATH_STRUCT(strlcat(split.tiny_buffer, small_string, sizeof(small_string)));
248
249#if _FORTIFY_SOURCE > 1
250 // expected-error@+2{{size bigger than buffer}}
251#endif
252 EXPECT_FORTIFY_DEATH_STRUCT(strlcpy(split.tiny_buffer, small_string, sizeof(small_string)));
George Burgess IV9a274102019-06-04 15:39:52 -0700253 }
254}
255
George Burgess IV2356c932019-06-06 17:18:13 -0700256FORTIFY_TEST(fcntl) {
257 const char target[] = "/dev/null";
258 int dirfd = 0;
259
260 // These all emit hard errors without diagnose_if, so running them is a bit
261 // more involved.
262#ifdef COMPILATION_TESTS
263 // expected-error@+1{{too many arguments}}
264 open("/", 0, 0, 0);
265 // expected-error@+1{{too many arguments}}
266 open64("/", 0, 0, 0);
267 // expected-error@+1{{too many arguments}}
268 openat(0, "/", 0, 0, 0);
269 // expected-error@+1{{too many arguments}}
270 openat64(0, "/", 0, 0, 0);
271#endif
272
273 // expected-error@+1{{missing mode}}
274 EXPECT_FORTIFY_DEATH(open(target, O_CREAT));
275 // expected-error@+1{{missing mode}}
276 EXPECT_FORTIFY_DEATH(open(target, O_TMPFILE));
277 // expected-error@+1{{missing mode}}
278 EXPECT_FORTIFY_DEATH(open64(target, O_CREAT));
279 // expected-error@+1{{missing mode}}
280 EXPECT_FORTIFY_DEATH(open64(target, O_TMPFILE));
281 // expected-error@+1{{missing mode}}
282 EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_CREAT));
283 // expected-error@+1{{missing mode}}
284 EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_TMPFILE));
285 // expected-error@+1{{missing mode}}
286 EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_CREAT));
287 // expected-error@+1{{missing mode}}
288 EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_TMPFILE));
289
290 // expected-warning@+1{{superfluous mode bits}}
291 EXPECT_NO_DEATH(open(target, O_RDONLY, 0777));
292 // expected-warning@+1{{superfluous mode bits}}
293 EXPECT_NO_DEATH(open64(target, O_RDONLY, 0777));
294 // expected-warning@+1{{superfluous mode bits}}
295 EXPECT_NO_DEATH(openat(dirfd, target, O_RDONLY, 0777));
296 // expected-warning@+1{{superfluous mode bits}}
297 EXPECT_NO_DEATH(openat64(dirfd, target, O_RDONLY, 0777));
298}
299
George Burgess IV9a274102019-06-04 15:39:52 -0700300// Since these emit hard errors, it's sort of hard to run them...
301#ifdef COMPILATION_TESTS
302namespace compilation_tests {
303template <typename T>
304static T declval() {
305 __builtin_unreachable();
306}
307
George Burgess IV9a274102019-06-04 15:39:52 -0700308static void testFormatStrings() {
309 const auto unsigned_value = declval<unsigned long long>();
310 const auto* unknown_string = declval<const char*>();
George Burgess IV06bb4ce2019-06-13 15:13:02 -0700311 const auto va = *declval<va_list*>();
George Burgess IV9a274102019-06-04 15:39:52 -0700312
313 {
314 auto some_fd = declval<int>();
315 // expected-warning@+1{{format specifies type 'int'}}
316 dprintf(some_fd, "%d", unsigned_value);
317 // expected-warning@+1{{format string is not a string literal}}
318 dprintf(some_fd, unknown_string, unsigned_value);
319 // expected-warning@+1{{format string is not a string literal}}
320 vdprintf(1, unknown_string, va);
321 }
322
323 {
324 auto* retval = declval<char*>();
325#if 0
326 // expected-error@+2{{ignoring return value}}
327#endif
328 // expected-warning@+1{{format specifies type 'int'}}
329 asprintf(&retval, "%d", unsigned_value);
330#if 0
331 // expected-error@+2{{ignoring return value}}
332#endif
333 // expected-warning@+1{{format string is not a string literal}}
334 asprintf(&retval, unknown_string, 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 vasprintf(&retval, unknown_string, va);
340 }
341
342 // expected-warning@+1{{format specifies type 'int'}}
343 syslog(0, "%d", unsigned_value);
344 // expected-warning@+1{{format string is not a string literal}}
345 syslog(0, unknown_string, unsigned_value);
346 // expected-warning@+1{{format string is not a string literal}}
347 vsyslog(0, unknown_string, va);
348
349 {
350 auto* file = declval<FILE*>();
351 // expected-warning@+1{{format specifies type 'int'}}
352 fprintf(file, "%d", unsigned_value);
353 // expected-warning@+1{{format string is not a string literal}}
354 fprintf(file, unknown_string, unsigned_value);
355 // expected-warning@+1{{format string is not a string literal}}
356 vfprintf(file, unknown_string, va);
357 }
358
359 // expected-warning@+1{{format specifies type 'int'}}
360 printf("%d", unsigned_value);
361 // expected-warning@+1{{format string is not a string literal}}
362 printf(unknown_string, unsigned_value);
363 // expected-warning@+1{{format string is not a string literal}}
364 vprintf(unknown_string, va);
365
366 {
367 char buf[128];
368 // expected-warning@+1{{format specifies type 'int'}}
369 sprintf(buf, "%d", unsigned_value);
370 // expected-warning@+1{{format string is not a string literal}}
371 sprintf(buf, unknown_string, unsigned_value);
372 // expected-warning@+1{{format string is not a string literal}}
373 sprintf(buf, unknown_string, va);
374
375 // expected-warning@+1{{format specifies type 'int'}}
376 snprintf(buf, sizeof(buf), "%d", unsigned_value);
377 // expected-warning@+1{{format string is not a string literal}}
378 snprintf(buf, sizeof(buf), unknown_string, unsigned_value);
379 // expected-warning@+1{{format string is not a string literal}}
380 vsnprintf(buf, sizeof(buf), unknown_string, va);
381 }
382
383 // FIXME: below are general format string cases where clang should probably try to warn.
384 {
385 char buf[4];
386 sprintf(buf, "%s", "1234");
387 sprintf(buf, "1%s4", "23");
388 sprintf(buf, "%d", 1234);
389
390 // Similar thoughts for strncpy, etc.
391 }
392}
393
394static void testStdlib() {
395 char path_buffer[PATH_MAX - 1];
George Burgess IV8c0ec112019-06-06 17:23:32 -0700396 // expected-warning@+2{{ignoring return value of function}}
George Burgess IV9a274102019-06-04 15:39:52 -0700397 // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
398 realpath("/", path_buffer);
George Burgess IV8c0ec112019-06-06 17:23:32 -0700399 // expected-warning@+1{{ignoring return value of function}}
George Burgess IV9a274102019-06-04 15:39:52 -0700400 realpath("/", nullptr);
401
George Burgess IV8c0ec112019-06-06 17:23:32 -0700402 // expected-warning@+2{{ignoring return value of function}}
403 // expected-error@+1{{flipped arguments?}}
George Burgess IV9a274102019-06-04 15:39:52 -0700404 realpath(nullptr, path_buffer);
405
George Burgess IV8c0ec112019-06-06 17:23:32 -0700406 // expected-warning@+2{{ignoring return value of function}}
George Burgess IV9a274102019-06-04 15:39:52 -0700407 // expected-error@+1{{flipped arguments?}}
408 realpath(nullptr, nullptr);
409}
410} // namespace compilation_tests
411#endif
412
413FORTIFY_TEST(poll) {
414 int pipe_fds[2];
415 if (pipe(pipe_fds)) err(1, "pipe failed");
416
417 // after this, pipe_fds[0] should always report RDHUP
418 if (close(pipe_fds[1])) err(1, "close failed");
419
420 struct pollfd poll_fd = { pipe_fds[0], POLLRDHUP, 0 };
421 {
422 struct pollfd few_fds[] = { poll_fd, poll_fd };
423 // expected-error@+1{{fd_count is larger than the given buffer}}
424 EXPECT_FORTIFY_DEATH(poll(few_fds, 3, 0));
425 // expected-error@+1{{fd_count is larger than the given buffer}}
426 EXPECT_FORTIFY_DEATH(ppoll(few_fds, 3, 0, 0));
427 // expected-error@+1{{fd_count is larger than the given buffer}}
428 EXPECT_FORTIFY_DEATH(ppoll64(few_fds, 3, 0, nullptr));
429 }
430
431 {
432 struct {
433 struct pollfd few[2];
434 struct pollfd extra[1];
435 } fds = { { poll_fd, poll_fd }, { poll_fd } };
436 static_assert(sizeof(fds) >= sizeof(struct pollfd) * 3, "");
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(poll(fds.few, 3, 0));
442
443 struct timespec timeout = {};
444#if _FORTIFY_SOURCE > 1
445 // expected-error@+2{{fd_count is larger than the given buffer}}
446#endif
447 EXPECT_FORTIFY_DEATH_STRUCT(ppoll(fds.few, 3, &timeout, 0));
448
449#if _FORTIFY_SOURCE > 1
450 // expected-error@+2{{fd_count is larger than the given buffer}}
451#endif
452 EXPECT_FORTIFY_DEATH_STRUCT(ppoll64(fds.few, 3, 0, nullptr));
453 }
454}
455
456FORTIFY_TEST(socket) {
457 {
458 char small_buffer[8];
459 // expected-error@+1{{size bigger than buffer}}
460 EXPECT_FORTIFY_DEATH(recv(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
461 // expected-error@+1{{size bigger than buffer}}
462 EXPECT_FORTIFY_DEATH(recvfrom(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
463
464 // expected-error@+1{{size bigger than buffer}}
465 EXPECT_FORTIFY_DEATH(send(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
466 // expected-error@+1{{size bigger than buffer}}
467 EXPECT_FORTIFY_DEATH(sendto(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
468 }
469
470 {
471 struct {
472 char tiny_buffer[4];
473 char tiny_buffer2;
474 } split = {};
475
476 EXPECT_NO_DEATH(recv(kBogusFD, split.tiny_buffer, sizeof(split), 0));
477 EXPECT_NO_DEATH(recvfrom(kBogusFD, split.tiny_buffer, sizeof(split), 0, 0, 0));
478 }
479}
480
481FORTIFY_TEST(sys_stat) {
482 // expected-error@+1{{'umask' called with invalid mode}}
483 EXPECT_FORTIFY_DEATH(umask(01777));
484}
485
486FORTIFY_TEST(stdio) {
487 char small_buffer[8] = {};
488 {
George Burgess IV26d25a22019-06-06 17:45:05 -0700489 // expected-error@+1{{size is larger than the destination buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700490 EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
491
492 va_list va;
George Burgess IV26d25a22019-06-06 17:45:05 -0700493 // expected-error@+2{{size is larger than the destination buffer}}
George Burgess IV9a274102019-06-04 15:39:52 -0700494 // expected-warning@+1{{format string is empty}}
495 EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
George Burgess IV26d25a22019-06-06 17:45:05 -0700496
497 const char *SOMETIMES_CONST format_string = "aaaaaaaaa";
498
499 // expected-error@+1{{format string will always overflow}}
500 EXPECT_FORTIFY_DEATH(sprintf(small_buffer, format_string));
George Burgess IV9a274102019-06-04 15:39:52 -0700501 }
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 {
George Burgess IV9a274102019-06-04 15:39:52 -0700590 char* volatile unknown = small_buffer;
591 const size_t count = static_cast<size_t>(SSIZE_MAX) + 1;
592 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
593 EXPECT_FORTIFY_DEATH(read(kBogusFD, unknown, count));
594 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
595 EXPECT_FORTIFY_DEATH(pread(kBogusFD, unknown, count, 0));
596 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
597 EXPECT_FORTIFY_DEATH(pread64(kBogusFD, unknown, count, 0));
598 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
599 EXPECT_FORTIFY_DEATH(write(kBogusFD, unknown, count));
600 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
601 EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, unknown, count, 0));
602 // expected-error@+1{{'count' must be <= SSIZE_MAX}}
603 EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, unknown, count, 0));
George Burgess IV9a274102019-06-04 15:39:52 -0700604 }
605}
606
607#endif // defined(__BIONIC__)