1 /*
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
32 char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
33
34 ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
35 ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
36
37 ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
38 ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
39
40 ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
41 ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
42
43 ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
44 ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
45 __INTRODUCED_IN(12);
46
47 ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
48 ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
49 ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
50 ssize_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__)
63 #define __error_if_overflows_ssizet(what, fn) \
64 __clang_error_if((what) > SSIZE_MAX, "in call to '" #fn "', '" #what "' must be <= SSIZE_MAX")
65
66 #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")
69
70 #if __ANDROID_API__ >= __ANDROID_API_N__
71 __BIONIC_FORTIFY_INLINE
getcwd(char * const __pass_object_size buf,size_t size)72 char* getcwd(char* const __pass_object_size buf, size_t size)
73 __overloadable
74 __error_if_overflows_objectsize(size, __bos(buf), getcwd) {
75 size_t bos = __bos(buf);
76
77 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
78 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__
86 __BIONIC_FORTIFY_INLINE
pread(int fd,void * const __pass_object_size0 buf,size_t count,off_t offset)87 ssize_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) {
91 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
100 __BIONIC_FORTIFY_INLINE
pread64(int fd,void * const __pass_object_size0 buf,size_t count,off64_t offset)101 ssize_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) {
105 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__
116 __BIONIC_FORTIFY_INLINE
pwrite(int fd,const void * const __pass_object_size0 buf,size_t count,off_t offset)117 ssize_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) {
121 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
130 __BIONIC_FORTIFY_INLINE
pwrite64(int fd,const void * const __pass_object_size0 buf,size_t count,off64_t offset)131 ssize_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) {
135 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__
146 __BIONIC_FORTIFY_INLINE
read(int fd,void * const __pass_object_size0 buf,size_t count)147 ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
148 __overloadable
149 __error_if_overflows_ssizet(count, read)
150 __error_if_overflows_objectsize(count, __bos0(buf), read) {
151 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__
162 __BIONIC_FORTIFY_INLINE
write(int fd,const void * const __pass_object_size0 buf,size_t count)163 ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
164 __overloadable
165 __error_if_overflows_ssizet(count, write)
166 __error_if_overflows_objectsize(count, __bos0(buf), write) {
167 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__
178 __BIONIC_FORTIFY_INLINE
readlink(const char * path,char * const __pass_object_size buf,size_t size)179 ssize_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) {
183 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
192 __BIONIC_FORTIFY_INLINE
readlinkat(int dirfd,const char * path,char * const __pass_object_size buf,size_t size)193 ssize_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) {
197 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
212 char* __getcwd_real(char*, size_t) __RENAME(getcwd);
213 ssize_t __read_real(int, void*, size_t) __RENAME(read);
214 ssize_t __write_real(int, const void*, size_t) __RENAME(write);
215 ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
216 ssize_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
getcwd(char * buf,size_t size)238 char* 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
pread(int fd,void * buf,size_t count,off_t offset)259 ssize_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
pread64(int fd,void * buf,size_t count,off64_t offset)282 ssize_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
pwrite(int fd,const void * buf,size_t count,off_t offset)307 ssize_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
pwrite64(int fd,const void * buf,size_t count,off64_t offset)330 ssize_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
read(int fd,void * buf,size_t count)355 ssize_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
write(int fd,const void * buf,size_t count)380 ssize_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
readlink(const char * path,char * buf,size_t size)401 ssize_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
readlinkat(int dirfd,const char * path,char * buf,size_t size)424 ssize_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) */
450