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