blob: ac9853c7fab2c100f0c6f3d47a349ac6ba209219 [file] [log] [blame]
Dan Albert2fbb1b62014-10-08 11:21:32 -07001/*
2 * Copyright (C) 2014 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
George Burgess IVc7bd90f2017-08-23 17:32:48 -070017/*
George Burgess IVdb48e0c2019-05-02 16:23:31 -070018 * Silence all notes about enable_if-related 'candidates'; they're nice to know
19 * about for users, but this test doesn't care.
George Burgess IVc7bd90f2017-08-23 17:32:48 -070020 */
George Burgess IVdb48e0c2019-05-02 16:23:31 -070021// expected-note@* 0+{{candidate function}}
22
23/* Similarly, ignore all "from 'diagnose_if'"s. */
24// expected-note@* 0+{{from 'diagnose_if'}}
25
George Burgess IVc7bd90f2017-08-23 17:32:48 -070026
Dan Albert2fbb1b62014-10-08 11:21:32 -070027#undef _FORTIFY_SOURCE
28#define _FORTIFY_SOURCE 2
Yabin Cui20f22682015-03-03 20:27:58 -080029#include <fcntl.h>
30#include <netinet/in.h>
31#include <poll.h>
32#include <stdarg.h>
Dan Albert2fbb1b62014-10-08 11:21:32 -070033#include <stdio.h>
Daniel Micayafdd1542015-07-20 21:37:29 -040034#include <stdlib.h>
Yabin Cui20f22682015-03-03 20:27:58 -080035#include <string.h>
36#include <sys/socket.h>
37#include <sys/stat.h>
38#include <time.h>
39#include <unistd.h>
Dan Albert2fbb1b62014-10-08 11:21:32 -070040
George Burgess IVdb48e0c2019-05-02 16:23:31 -070041#if !defined(__BIONIC__)
42# error "This only works with Bionic."
43#endif
44
Dan Albert2fbb1b62014-10-08 11:21:32 -070045void test_sprintf() {
46 char buf[4];
47
48 // NOLINTNEXTLINE(whitespace/line_length)
George Burgess IVdb48e0c2019-05-02 16:23:31 -070049 // expected-error@+1{{call to unavailable function 'sprintf': format string will always overflow destination buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -080050 sprintf(buf, "foobar"); // NOLINT(runtime/printf)
Dan Albert2fbb1b62014-10-08 11:21:32 -070051
Elliott Hughes0d1a8a52018-07-24 19:36:51 +000052 // TODO: clang should emit a warning, but doesn't
Yabin Cui20f22682015-03-03 20:27:58 -080053 sprintf(buf, "%s", "foobar"); // NOLINT(runtime/printf)
Dan Albert2fbb1b62014-10-08 11:21:32 -070054}
55
56void test_snprintf() {
57 char buf[4];
58
59 // NOLINTNEXTLINE(whitespace/line_length)
George Burgess IVdb48e0c2019-05-02 16:23:31 -070060 // expected-error@+1{{call to unavailable function 'snprintf': format string will always overflow destination buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -080061 snprintf(buf, 5, "foobar"); // NOLINT(runtime/printf)
Dan Albert2fbb1b62014-10-08 11:21:32 -070062
Elliott Hughes0d1a8a52018-07-24 19:36:51 +000063 // TODO: clang should emit a warning, but doesn't
Yabin Cui20f22682015-03-03 20:27:58 -080064 snprintf(buf, 5, "%s", "foobar"); // NOLINT(runtime/printf)
Dan Albert2fbb1b62014-10-08 11:21:32 -070065
Elliott Hughes0d1a8a52018-07-24 19:36:51 +000066 // TODO: clang should emit a warning, but doesn't
Yabin Cui20f22682015-03-03 20:27:58 -080067 snprintf(buf, 5, " %s ", "foobar"); // NOLINT(runtime/printf)
Dan Albert2fbb1b62014-10-08 11:21:32 -070068
Elliott Hughes0d1a8a52018-07-24 19:36:51 +000069 // TODO: clang should emit a warning, but doesn't
Yabin Cui20f22682015-03-03 20:27:58 -080070 snprintf(buf, 5, "%d", 100000); // NOLINT(runtime/printf)
71}
72
73void test_memcpy() {
74 char buf[4];
75
George Burgess IVdb48e0c2019-05-02 16:23:31 -070076 // expected-error@+1{{'memcpy' called with size bigger than buffer}}
George Burgess IV7cc779f2017-02-09 00:00:31 -080077 memcpy(buf, "foobar", sizeof("foobar") + 100);
Yabin Cui20f22682015-03-03 20:27:58 -080078}
79
80void test_memmove() {
81 char buf[4];
82
George Burgess IVdb48e0c2019-05-02 16:23:31 -070083 // expected-error@+1{{'memmove' called with size bigger than buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -080084 memmove(buf, "foobar", sizeof("foobar"));
85}
86
87void test_memset() {
88 char buf[4];
89
George Burgess IVdb48e0c2019-05-02 16:23:31 -070090 // expected-error@+1{{'memset' called with size bigger than buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -080091 memset(buf, 0, 6);
92}
93
94void test_strcpy() {
95 char buf[4];
96
George Burgess IVdb48e0c2019-05-02 16:23:31 -070097 // expected-error@+1{{'strcpy' called with string bigger than buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -080098 strcpy(buf, "foobar"); // NOLINT(runtime/printf)
George Burgess IVb6300462017-07-31 21:29:42 -070099
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700100 // expected-error@+1{{'strcpy' called with string bigger than buffer}}
George Burgess IVb6300462017-07-31 21:29:42 -0700101 strcpy(buf, "quux");
Yabin Cui20f22682015-03-03 20:27:58 -0800102}
103
104void test_stpcpy() {
105 char buf[4];
106
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700107 // expected-error@+1{{'stpcpy' called with string bigger than buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -0800108 stpcpy(buf, "foobar");
George Burgess IVb6300462017-07-31 21:29:42 -0700109
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700110 // expected-error@+1{{'stpcpy' called with string bigger than buffer}}
George Burgess IVb6300462017-07-31 21:29:42 -0700111 stpcpy(buf, "quux");
Yabin Cui20f22682015-03-03 20:27:58 -0800112}
113
114void test_strncpy() {
115 char buf[4];
116
Elliott Hughes0d1a8a52018-07-24 19:36:51 +0000117 // TODO: clang should emit a warning, but doesn't
Yabin Cui20f22682015-03-03 20:27:58 -0800118 strncpy(buf, "foobar", sizeof("foobar"));
119}
120
121void test_strcat() {
122 char buf[4] = "";
123
Elliott Hughes0d1a8a52018-07-24 19:36:51 +0000124 // TODO: clang should emit a warning, but doesn't
Yabin Cui20f22682015-03-03 20:27:58 -0800125 strcat(buf, "foobar"); // NOLINT(runtime/printf)
126}
127
128void test_strncat() {
129 char buf[4] = "";
130
Elliott Hughes0d1a8a52018-07-24 19:36:51 +0000131 // TODO: clang should emit a warning, but doesn't
Yabin Cui20f22682015-03-03 20:27:58 -0800132 strncat(buf, "foobar", sizeof("foobar"));
133}
134
135void test_vsprintf(const char* fmt, ...) {
136 va_list va;
137 char buf[4];
138 va_start(va, fmt);
139
Yabin Cui20f22682015-03-03 20:27:58 -0800140 // clang should emit a warning, but doesn't
141 vsprintf(buf, "foobar", va);
142 va_end(va);
143}
144
145void test_vsnprintf(const char* fmt, ...) {
146 va_list va;
147 char buf[4];
148 va_start(va, fmt);
149
Yabin Cui20f22682015-03-03 20:27:58 -0800150 // clang should emit a warning, but doesn't
151 vsnprintf(buf, 5, "foobar", va); // NOLINT(runtime/printf)
152
153 va_end(va);
154}
155
156void test_fgets() {
157 char buf[4];
158
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700159 // expected-error@+1{{in call to 'fgets', size should not be negative}}
Yabin Cui20f22682015-03-03 20:27:58 -0800160 fgets(buf, -1, stdin);
161
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700162 // expected-error@+1{{in call to 'fgets', size is larger than the destination buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -0800163 fgets(buf, 6, stdin);
164}
165
166void test_recvfrom() {
167 char buf[4];
168 sockaddr_in addr;
169
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700170 // expected-error@+1{{'recvfrom' called with size bigger than buffer}}
Yi Kong32bc0fc2018-08-02 17:31:13 -0700171 recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), nullptr);
Yabin Cui20f22682015-03-03 20:27:58 -0800172}
173
George Burgess IV54f5d832017-07-31 21:21:10 -0700174void test_recv() {
175 char buf[4] = {0};
176
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700177 // expected-error@+1{{'recv' called with size bigger than buffer}}
George Burgess IV54f5d832017-07-31 21:21:10 -0700178 recv(0, buf, 6, 0);
179}
180
Yabin Cui20f22682015-03-03 20:27:58 -0800181void test_umask() {
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700182 // expected-error@+1{{'umask' called with invalid mode}}
Yabin Cui20f22682015-03-03 20:27:58 -0800183 umask(01777);
184}
185
186void test_read() {
187 char buf[4];
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700188 // expected-error@+1{{in call to 'read', 'count' bytes overflows the given object}}
Yabin Cui20f22682015-03-03 20:27:58 -0800189 read(0, buf, 6);
190}
191
192void test_open() {
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700193 // expected-error@+1{{'open' called with O_CREAT or O_TMPFILE, but missing mode}}
Yabin Cui20f22682015-03-03 20:27:58 -0800194 open("/dev/null", O_CREAT);
195
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700196 // expected-error@+1{{'open' called with O_CREAT or O_TMPFILE, but missing mode}}
Elliott Hughesb115aef2017-08-04 09:34:19 -0700197 open("/dev/null", O_TMPFILE);
198
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700199 // expected-error@+1{{call to unavailable function 'open': too many arguments}}
Yabin Cui20f22682015-03-03 20:27:58 -0800200 open("/dev/null", O_CREAT, 0, 0);
George Burgess IV4e37d532017-08-03 17:11:35 -0700201
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700202 // expected-error@+1{{call to unavailable function 'open': too many arguments}}
Elliott Hughesb115aef2017-08-04 09:34:19 -0700203 open("/dev/null", O_TMPFILE, 0, 0);
204
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700205 // expected-warning@+1{{'open' has superfluous mode bits; missing O_CREAT?}}
George Burgess IV4e37d532017-08-03 17:11:35 -0700206 open("/dev/null", O_RDONLY, 0644);
207
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700208 // expected-warning@+1{{'open' has superfluous mode bits; missing O_CREAT?}}
George Burgess IV4e37d532017-08-03 17:11:35 -0700209 open("/dev/null", O_DIRECTORY, 0644);
Yabin Cui20f22682015-03-03 20:27:58 -0800210}
211
212void test_poll() {
213 pollfd fds[1];
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700214 // expected-error@+1{{in call to 'poll', fd_count is larger than the given buffer}}
Yabin Cui20f22682015-03-03 20:27:58 -0800215 poll(fds, 2, 0);
216}
217
218void test_ppoll() {
219 pollfd fds[1];
220 timespec timeout;
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700221 // expected-error@+1{{in call to 'ppoll', fd_count is larger than the given buffer}}
Elliott Hughesb83bf142018-03-22 11:01:25 -0700222 ppoll(fds, 2, &timeout, nullptr);
223}
224
225void test_ppoll64() {
226 pollfd fds[1];
227 timespec timeout;
228 // NOLINTNEXTLINE(whitespace/line_length)
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700229 // expected-error@+1{{in call to 'ppoll64', fd_count is larger than the given buffer}}
Elliott Hughesb83bf142018-03-22 11:01:25 -0700230 ppoll64(fds, 2, &timeout, nullptr);
Dan Albert2fbb1b62014-10-08 11:21:32 -0700231}
Daniel Micayfed26592015-07-18 13:55:51 -0400232
233void test_fread_overflow() {
234 char buf[4];
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700235 // expected-error@+1{{in call to 'fread', size * count overflows}}
Daniel Micayfed26592015-07-18 13:55:51 -0400236 fread(buf, 2, (size_t)-1, stdin);
237}
238
239void test_fread_too_big() {
240 char buf[4];
241 // NOLINTNEXTLINE(whitespace/line_length)
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700242 // expected-error@+1{{in call to 'fread', size * count is too large for the given buffer}}
Daniel Micayfed26592015-07-18 13:55:51 -0400243 fread(buf, 1, 5, stdin);
244}
245
246void test_fwrite_overflow() {
Daniel Micayafdd1542015-07-20 21:37:29 -0400247 char buf[4] = {0};
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700248 // expected-error@+1{{in call to 'fwrite', size * count overflows}}
Daniel Micayfed26592015-07-18 13:55:51 -0400249 fwrite(buf, 2, (size_t)-1, stdout);
250}
251
252void test_fwrite_too_big() {
253 char buf[4] = {0};
254 // NOLINTNEXTLINE(whitespace/line_length)
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700255 // expected-error@+1{{in call to 'fwrite', size * count is too large for the given buffer}}
Daniel Micayfed26592015-07-18 13:55:51 -0400256 fwrite(buf, 1, 5, stdout);
257}
Daniel Micay9101b002015-05-20 15:31:26 -0400258
259void test_getcwd() {
260 char buf[4];
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700261 // expected-error@+1{{in call to 'getcwd', 'size' bytes overflows the given object}}
Daniel Micay9101b002015-05-20 15:31:26 -0400262 getcwd(buf, 5);
263}
Daniel Micayafdd1542015-07-20 21:37:29 -0400264
265void test_pwrite64_size() {
266 char buf[4] = {0};
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700267 // expected-error@+1{{in call to 'pwrite64', 'count' bytes overflows the given object}}
Daniel Micayafdd1542015-07-20 21:37:29 -0400268 pwrite64(STDOUT_FILENO, buf, 5, 0);
269}
270
George Burgess IV7cc779f2017-02-09 00:00:31 -0800271void test_pwrite64_too_big_malloc() {
Daniel Micayafdd1542015-07-20 21:37:29 -0400272 void *buf = calloc(atoi("5"), 1);
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700273 // expected-error@+1{{in call to 'pwrite64', 'count' must be <= SSIZE_MAX}}
George Burgess IV7cc779f2017-02-09 00:00:31 -0800274 pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0);
275}
276
277void test_pwrite64_too_big() {
278 char buf[4] = {0};
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700279 // expected-error@+1{{in call to 'pwrite64', 'count' must be <= SSIZE_MAX}}
Daniel Micayafdd1542015-07-20 21:37:29 -0400280 pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0);
281}
282
283void test_write_size() {
284 char buf[4] = {0};
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700285 // expected-error@+1{{in call to 'write', 'count' bytes overflows the given object}}
Daniel Micayafdd1542015-07-20 21:37:29 -0400286 write(STDOUT_FILENO, buf, 5);
287}
George Burgess IV7cc779f2017-02-09 00:00:31 -0800288
289void test_memset_args_flipped() {
290 char from[4] = {0};
291 // NOLINTNEXTLINE(whitespace/line_length)
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700292 // expected-warning@+1{{'memset' will set 0 bytes; maybe the arguments got flipped?}}
George Burgess IV7cc779f2017-02-09 00:00:31 -0800293 memset(from, sizeof(from), 0);
294}
Daniel Micay95b59c52017-02-13 17:27:59 -0800295
296void test_sendto() {
297 char buf[4] = {0};
298 sockaddr_in addr;
299
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700300 // expected-error@+1{{'sendto' called with size bigger than buffer}}
Daniel Micay95b59c52017-02-13 17:27:59 -0800301 sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in));
302}
303
304void test_send() {
305 char buf[4] = {0};
306
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700307 // expected-error@+1{{'send' called with size bigger than buffer}}
Daniel Micay95b59c52017-02-13 17:27:59 -0800308 send(0, buf, 6, 0);
309}
George Burgess IV54f5d832017-07-31 21:21:10 -0700310
311void test_realpath() {
312 char buf[4] = {0};
313 // NOLINTNEXTLINE(whitespace/line_length)
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700314 // expected-error@+1{{'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
George Burgess IV54f5d832017-07-31 21:21:10 -0700315 realpath(".", buf);
316
317 // This is fine.
Yi Kong32bc0fc2018-08-02 17:31:13 -0700318 realpath(".", nullptr);
George Burgess IV54f5d832017-07-31 21:21:10 -0700319
George Burgess IV95bd4882017-08-14 14:48:55 -0700320 char bigbuf[PATH_MAX];
George Burgess IVdb48e0c2019-05-02 16:23:31 -0700321 // expected-error@+1{{'realpath': NULL path is never correct; flipped arguments?}}
Yi Kong32bc0fc2018-08-02 17:31:13 -0700322 realpath(nullptr, bigbuf);
George Burgess IV54f5d832017-07-31 21:21:10 -0700323}