blob: ea5c89d348fdc094aa7fb87a39aa593417461aee [file] [log] [blame]
George Burgess IVb97049c2017-07-24 15:05:05 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28#ifndef _UNISTD_H_
29#error "Never include this file directly; instead, include <unistd.h>"
30#endif
31
32char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
33
34ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
35ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
36
37ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
38ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
39
40ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
41ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
42
43ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
44ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
45 __INTRODUCED_IN(12);
46
47ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
48ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
49ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
50ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
51
52#if defined(__BIONIC_FORTIFY)
53
54#if defined(__USE_FILE_OFFSET64)
55#define __PREAD_PREFIX(x) __pread64_ ## x
56#define __PWRITE_PREFIX(x) __pwrite64_ ## x
57#else
58#define __PREAD_PREFIX(x) __pread_ ## x
59#define __PWRITE_PREFIX(x) __pwrite_ ## x
60#endif
61
62#if defined(__clang__)
George Burgess IV16c17392017-07-31 21:30:47 -070063#define __error_if_overflows_ssizet(what, fn) \
64 __clang_error_if((what) > SSIZE_MAX, "in call to '" #fn "', '" #what "' must be <= SSIZE_MAX")
George Burgess IVb97049c2017-07-24 15:05:05 -070065
George Burgess IV16c17392017-07-31 21:30:47 -070066#define __error_if_overflows_objectsize(what, objsize, fn) \
67 __clang_error_if((objsize) != __BIONIC_FORTIFY_UNKNOWN_SIZE && (what) > (objsize), \
68 "in call to '" #fn "', '" #what "' bytes overflows the given object")
George Burgess IVb97049c2017-07-24 15:05:05 -070069
70#if __ANDROID_API__ >= __ANDROID_API_N__
71__BIONIC_FORTIFY_INLINE
George Burgess IV16c17392017-07-31 21:30:47 -070072char* getcwd(char* const __pass_object_size buf, size_t size)
73 __overloadable
74 __error_if_overflows_objectsize(size, __bos(buf), getcwd) {
George Burgess IVb97049c2017-07-24 15:05:05 -070075 size_t bos = __bos(buf);
76
George Burgess IV16c17392017-07-31 21:30:47 -070077 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
George Burgess IVb97049c2017-07-24 15:05:05 -070078 return __call_bypassing_fortify(getcwd)(buf, size);
79 }
80
81 return __getcwd_chk(buf, size, bos);
82}
83#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
84
85#if __ANDROID_API__ >= __ANDROID_API_M__
George Burgess IVb97049c2017-07-24 15:05:05 -070086__BIONIC_FORTIFY_INLINE
George Burgess IV16c17392017-07-31 21:30:47 -070087ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count, off_t offset)
88 __overloadable
89 __error_if_overflows_ssizet(count, pread)
90 __error_if_overflows_objectsize(count, __bos0(buf), pread) {
George Burgess IVb97049c2017-07-24 15:05:05 -070091 size_t bos = __bos0(buf);
92
93 if (count == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
94 return __PREAD_PREFIX(real)(fd, buf, count, offset);
95 }
96
97 return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
98}
99
George Burgess IVb97049c2017-07-24 15:05:05 -0700100__BIONIC_FORTIFY_INLINE
George Burgess IV16c17392017-07-31 21:30:47 -0700101ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count, off64_t offset)
102 __overloadable
103 __error_if_overflows_ssizet(count, pread64)
104 __error_if_overflows_objectsize(count, __bos0(buf), pread64) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700105 size_t bos = __bos0(buf);
106
107 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
108 return __pread64_real(fd, buf, count, offset);
109 }
110
111 return __pread64_chk(fd, buf, count, offset, bos);
112}
113#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
114
115#if __ANDROID_API__ >= __ANDROID_API_N__
George Burgess IVb97049c2017-07-24 15:05:05 -0700116__BIONIC_FORTIFY_INLINE
George Burgess IV16c17392017-07-31 21:30:47 -0700117ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count, off_t offset)
118 __overloadable
119 __error_if_overflows_ssizet(count, pwrite)
120 __error_if_overflows_objectsize(count, __bos0(buf), pwrite) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700121 size_t bos = __bos0(buf);
122
123 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
124 return __PWRITE_PREFIX(real)(fd, buf, count, offset);
125 }
126
127 return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
128}
129
George Burgess IVb97049c2017-07-24 15:05:05 -0700130__BIONIC_FORTIFY_INLINE
George Burgess IV16c17392017-07-31 21:30:47 -0700131ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf, size_t count, off64_t offset)
132 __overloadable
133 __error_if_overflows_ssizet(count, pwrite64)
134 __error_if_overflows_objectsize(count, __bos0(buf), pwrite64) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700135 size_t bos = __bos0(buf);
136
137 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
138 return __pwrite64_real(fd, buf, count, offset);
139 }
140
141 return __pwrite64_chk(fd, buf, count, offset, bos);
142}
143#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
144
145#if __ANDROID_API__ >= __ANDROID_API_L__
George Burgess IVb97049c2017-07-24 15:05:05 -0700146__BIONIC_FORTIFY_INLINE
147ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
George Burgess IV16c17392017-07-31 21:30:47 -0700148 __overloadable
149 __error_if_overflows_ssizet(count, read)
150 __error_if_overflows_objectsize(count, __bos0(buf), read) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700151 size_t bos = __bos0(buf);
152
153 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
154 return __call_bypassing_fortify(read)(fd, buf, count);
155 }
156
157 return __read_chk(fd, buf, count, bos);
158}
159#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
160
161#if __ANDROID_API__ >= __ANDROID_API_N__
George Burgess IVb97049c2017-07-24 15:05:05 -0700162__BIONIC_FORTIFY_INLINE
163ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
George Burgess IV16c17392017-07-31 21:30:47 -0700164 __overloadable
165 __error_if_overflows_ssizet(count, write)
166 __error_if_overflows_objectsize(count, __bos0(buf), write) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700167 size_t bos = __bos0(buf);
168
169 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
170 return __call_bypassing_fortify(write)(fd, buf, count);
171 }
172
173 return __write_chk(fd, buf, count, bos);
174}
175#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
176
177#if __ANDROID_API__ >= __ANDROID_API_M__
George Burgess IVb97049c2017-07-24 15:05:05 -0700178__BIONIC_FORTIFY_INLINE
George Burgess IV16c17392017-07-31 21:30:47 -0700179ssize_t readlink(const char* path, char* const __pass_object_size buf, size_t size)
180 __overloadable
181 __error_if_overflows_ssizet(size, readlink)
182 __error_if_overflows_objectsize(size, __bos(buf), readlink) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700183 size_t bos = __bos(buf);
184
185 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
186 return __call_bypassing_fortify(readlink)(path, buf, size);
187 }
188
189 return __readlink_chk(path, buf, size, bos);
190}
191
George Burgess IVb97049c2017-07-24 15:05:05 -0700192__BIONIC_FORTIFY_INLINE
George Burgess IV16c17392017-07-31 21:30:47 -0700193ssize_t readlinkat(int dirfd, const char* path, char* const __pass_object_size buf, size_t size)
194 __overloadable
195 __error_if_overflows_ssizet(size, readlinkat)
196 __error_if_overflows_objectsize(size, __bos(buf), readlinkat) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700197 size_t bos = __bos(buf);
198
199 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
200 return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
201 }
202
203 return __readlinkat_chk(dirfd, path, buf, size, bos);
204}
205#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
206
207#undef __enable_if_no_overflow_ssizet
208#undef __error_if_overflows_objectsize
209#undef __error_if_overflows_ssizet
210#else /* defined(__clang__) */
211
212char* __getcwd_real(char*, size_t) __RENAME(getcwd);
213ssize_t __read_real(int, void*, size_t) __RENAME(read);
214ssize_t __write_real(int, const void*, size_t) __RENAME(write);
215ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
216ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
217
218__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
219__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
220__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
221__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
222__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
223__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
224__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
225__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
226__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
227__errordecl(__read_dest_size_error, "read called with size bigger than destination");
228__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
229__errordecl(__write_dest_size_error, "write called with size bigger than destination");
230__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
231__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
232__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
233__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
234__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
235
236#if __ANDROID_API__ >= __ANDROID_API_N__
237__BIONIC_FORTIFY_INLINE
238char* getcwd(char* buf, size_t size) __overloadable {
239 size_t bos = __bos(buf);
240
241 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
242 return __getcwd_real(buf, size);
243 }
244
245 if (__builtin_constant_p(size) && (size > bos)) {
246 __getcwd_dest_size_error();
247 }
248
249 if (__builtin_constant_p(size) && (size <= bos)) {
250 return __getcwd_real(buf, size);
251 }
252
253 return __getcwd_chk(buf, size, bos);
254}
255#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
256
257#if __ANDROID_API__ >= __ANDROID_API_M__
258__BIONIC_FORTIFY_INLINE
259ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
260 size_t bos = __bos0(buf);
261
262 if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
263 __PREAD_PREFIX(count_toobig_error)();
264 }
265
266 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
267 return __PREAD_PREFIX(real)(fd, buf, count, offset);
268 }
269
270 if (__builtin_constant_p(count) && (count > bos)) {
271 __PREAD_PREFIX(dest_size_error)();
272 }
273
274 if (__builtin_constant_p(count) && (count <= bos)) {
275 return __PREAD_PREFIX(real)(fd, buf, count, offset);
276 }
277
278 return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
279}
280
281__BIONIC_FORTIFY_INLINE
282ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
283 size_t bos = __bos0(buf);
284
285 if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
286 __pread64_count_toobig_error();
287 }
288
289 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
290 return __pread64_real(fd, buf, count, offset);
291 }
292
293 if (__builtin_constant_p(count) && (count > bos)) {
294 __pread64_dest_size_error();
295 }
296
297 if (__builtin_constant_p(count) && (count <= bos)) {
298 return __pread64_real(fd, buf, count, offset);
299 }
300
301 return __pread64_chk(fd, buf, count, offset, bos);
302}
303#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
304
305#if __ANDROID_API__ >= __ANDROID_API_N__
306__BIONIC_FORTIFY_INLINE
307ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
308 size_t bos = __bos0(buf);
309
310 if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
311 __PWRITE_PREFIX(count_toobig_error)();
312 }
313
314 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
315 return __PWRITE_PREFIX(real)(fd, buf, count, offset);
316 }
317
318 if (__builtin_constant_p(count) && (count > bos)) {
319 __PWRITE_PREFIX(dest_size_error)();
320 }
321
322 if (__builtin_constant_p(count) && (count <= bos)) {
323 return __PWRITE_PREFIX(real)(fd, buf, count, offset);
324 }
325
326 return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
327}
328
329__BIONIC_FORTIFY_INLINE
330ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
331 size_t bos = __bos0(buf);
332
333 if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
334 __pwrite64_count_toobig_error();
335 }
336
337 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
338 return __pwrite64_real(fd, buf, count, offset);
339 }
340
341 if (__builtin_constant_p(count) && (count > bos)) {
342 __pwrite64_dest_size_error();
343 }
344
345 if (__builtin_constant_p(count) && (count <= bos)) {
346 return __pwrite64_real(fd, buf, count, offset);
347 }
348
349 return __pwrite64_chk(fd, buf, count, offset, bos);
350}
351#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
352
353#if __ANDROID_API__ >= __ANDROID_API_L__
354__BIONIC_FORTIFY_INLINE
355ssize_t read(int fd, void* buf, size_t count) {
356 size_t bos = __bos0(buf);
357
358 if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
359 __read_count_toobig_error();
360 }
361
362 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
363 return __read_real(fd, buf, count);
364 }
365
366 if (__builtin_constant_p(count) && (count > bos)) {
367 __read_dest_size_error();
368 }
369
370 if (__builtin_constant_p(count) && (count <= bos)) {
371 return __read_real(fd, buf, count);
372 }
373
374 return __read_chk(fd, buf, count, bos);
375}
376#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
377
378#if __ANDROID_API__ >= __ANDROID_API_N__
379__BIONIC_FORTIFY_INLINE
380ssize_t write(int fd, const void* buf, size_t count) {
381 size_t bos = __bos0(buf);
382
383 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
384 return __write_real(fd, buf, count);
385 }
386
387 if (__builtin_constant_p(count) && (count > bos)) {
388 __write_dest_size_error();
389 }
390
391 if (__builtin_constant_p(count) && (count <= bos)) {
392 return __write_real(fd, buf, count);
393 }
394
395 return __write_chk(fd, buf, count, bos);
396}
397#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
398
399#if __ANDROID_API__ >= __ANDROID_API_M__
400__BIONIC_FORTIFY_INLINE
401ssize_t readlink(const char* path, char* buf, size_t size) {
402 size_t bos = __bos(buf);
403
404 if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
405 __readlink_size_toobig_error();
406 }
407
408 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
409 return __readlink_real(path, buf, size);
410 }
411
412 if (__builtin_constant_p(size) && (size > bos)) {
413 __readlink_dest_size_error();
414 }
415
416 if (__builtin_constant_p(size) && (size <= bos)) {
417 return __readlink_real(path, buf, size);
418 }
419
420 return __readlink_chk(path, buf, size, bos);
421}
422
423__BIONIC_FORTIFY_INLINE
424ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
425 size_t bos = __bos(buf);
426
427 if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
428 __readlinkat_size_toobig_error();
429 }
430
431 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
432 return __readlinkat_real(dirfd, path, buf, size);
433 }
434
435 if (__builtin_constant_p(size) && (size > bos)) {
436 __readlinkat_dest_size_error();
437 }
438
439 if (__builtin_constant_p(size) && (size <= bos)) {
440 return __readlinkat_real(dirfd, path, buf, size);
441 }
442
443 return __readlinkat_chk(dirfd, path, buf, size, bos);
444}
445#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
446#endif /* defined(__clang__) */
447#undef __PREAD_PREFIX
448#undef __PWRITE_PREFIX
449#endif /* defined(__BIONIC_FORTIFY) */