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* _Nullable __getcwd_chk(char* _Nullable, size_t, size_t) __INTRODUCED_IN(24);
33
34 ssize_t __pread_chk(int, void* _Nonnull, size_t, off_t, size_t) __INTRODUCED_IN(23);
35 ssize_t __pread_real(int, void* _Nonnull, size_t, off_t) __RENAME(pread);
36
37 ssize_t __pread64_chk(int, void* _Nonnull, size_t, off64_t, size_t) __INTRODUCED_IN(23);
38 ssize_t __pread64_real(int, void* _Nonnull, size_t, off64_t) __RENAME(pread64);
39
40 ssize_t __pwrite_chk(int, const void* _Nonnull, size_t, off_t, size_t) __INTRODUCED_IN(24);
41 ssize_t __pwrite_real(int, const void* _Nonnull, size_t, off_t) __RENAME(pwrite);
42
43 ssize_t __pwrite64_chk(int, const void* _Nonnull, size_t, off64_t, size_t) __INTRODUCED_IN(24);
44 ssize_t __pwrite64_real(int, const void* _Nonnull, size_t, off64_t) __RENAME(pwrite64);
45
46 ssize_t __read_chk(int, void* __BIONIC_COMPLICATED_NULLNESS, size_t, size_t);
47 ssize_t __write_chk(int, const void* __BIONIC_COMPLICATED_NULLNESS, size_t, size_t) __INTRODUCED_IN(24);
48 ssize_t __readlink_chk(const char* _Nonnull, char* _Nonnull, size_t, size_t) __INTRODUCED_IN(23);
49 ssize_t __readlinkat_chk(int dirfd, const char* _Nonnull, char* _Nonnull, size_t, size_t) __INTRODUCED_IN(23);
50
51 #if defined(__BIONIC_FORTIFY)
52
53 #if defined(__USE_FILE_OFFSET64)
54 #define __PREAD_PREFIX(x) __pread64_ ## x
55 #define __PWRITE_PREFIX(x) __pwrite64_ ## x
56 #else
57 #define __PREAD_PREFIX(x) __pread_ ## x
58 #define __PWRITE_PREFIX(x) __pwrite_ ## x
59 #endif
60
61 #define __error_if_overflows_ssizet(what, fn) \
62 __clang_error_if((what) > SSIZE_MAX, "in call to '" #fn "', '" #what "' must be <= SSIZE_MAX")
63
64 #define __error_if_overflows_objectsize(what, objsize, fn) \
65 __clang_error_if(__bos_unevaluated_lt((objsize), (what)), \
66 "in call to '" #fn "', '" #what "' bytes overflows the given object")
67
68 #define __bos_trivially_ge_no_overflow(bos_val, index) \
69 ((__bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX) && \
70 __builtin_constant_p(index) && (index) <= SSIZE_MAX))
71
72 __BIONIC_FORTIFY_INLINE
getcwd(char * const _Nullable __pass_object_size buf,size_t size)73 char* _Nullable getcwd(char* const _Nullable __pass_object_size buf, size_t size)
74 __overloadable
75 __error_if_overflows_objectsize(size, __bos(buf), getcwd) {
76 #if __ANDROID_API__ >= 24 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
77 size_t bos = __bos(buf);
78
79 if (!__bos_trivially_ge(bos, size)) {
80 return __getcwd_chk(buf, size, bos);
81 }
82 #endif
83 return __call_bypassing_fortify(getcwd)(buf, size);
84 }
85
86 #if !defined(__USE_FILE_OFFSET64)
87 __BIONIC_FORTIFY_INLINE
pread(int fd,void * const _Nonnull __pass_object_size0 buf,size_t count,off_t offset)88 ssize_t pread(int fd, void* const _Nonnull __pass_object_size0 buf, size_t count, off_t offset)
89 __overloadable
90 __error_if_overflows_ssizet(count, pread)
91 __error_if_overflows_objectsize(count, __bos0(buf), pread) {
92 #if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
93 size_t bos = __bos0(buf);
94
95 if (!__bos_trivially_ge_no_overflow(bos, count)) {
96 return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
97 }
98 #endif
99 return __PREAD_PREFIX(real)(fd, buf, count, offset);
100 }
101 #endif /* !defined(__USE_FILE_OFFSET64) */
102
103 __BIONIC_FORTIFY_INLINE
pread64(int fd,void * const _Nonnull __pass_object_size0 buf,size_t count,off64_t offset)104 ssize_t pread64(int fd, void* const _Nonnull __pass_object_size0 buf, size_t count, off64_t offset)
105 __overloadable
106 __error_if_overflows_ssizet(count, pread64)
107 __error_if_overflows_objectsize(count, __bos0(buf), pread64) {
108 #if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
109 size_t bos = __bos0(buf);
110
111 if (!__bos_trivially_ge_no_overflow(bos, count)) {
112 return __pread64_chk(fd, buf, count, offset, bos);
113 }
114 #endif
115 return __pread64_real(fd, buf, count, offset);
116 }
117
118 #if !defined(__USE_FILE_OFFSET64)
119 __BIONIC_FORTIFY_INLINE
pwrite(int fd,const void * const _Nonnull __pass_object_size0 buf,size_t count,off_t offset)120 ssize_t pwrite(int fd, const void* const _Nonnull __pass_object_size0 buf, size_t count, off_t offset)
121 __overloadable
122 __error_if_overflows_ssizet(count, pwrite)
123 __error_if_overflows_objectsize(count, __bos0(buf), pwrite) {
124 #if __ANDROID_API__ >= 24 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
125 size_t bos = __bos0(buf);
126
127 if (!__bos_trivially_ge_no_overflow(bos, count)) {
128 return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
129 }
130 #endif
131 return __PWRITE_PREFIX(real)(fd, buf, count, offset);
132 }
133 #endif /* !defined(__USE_FILE_OFFSET64) */
134
135 __BIONIC_FORTIFY_INLINE
pwrite64(int fd,const void * const _Nonnull __pass_object_size0 buf,size_t count,off64_t offset)136 ssize_t pwrite64(int fd, const void* const _Nonnull __pass_object_size0 buf, size_t count, off64_t offset)
137 __overloadable
138 __error_if_overflows_ssizet(count, pwrite64)
139 __error_if_overflows_objectsize(count, __bos0(buf), pwrite64) {
140 #if __ANDROID_API__ >= 24 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
141 size_t bos = __bos0(buf);
142
143 if (!__bos_trivially_ge_no_overflow(bos, count)) {
144 return __pwrite64_chk(fd, buf, count, offset, bos);
145 }
146 #endif
147 return __pwrite64_real(fd, buf, count, offset);
148 }
149
150 __BIONIC_FORTIFY_INLINE
read(int fd,void * const __BIONIC_COMPLICATED_NULLNESS __pass_object_size0 buf,size_t count)151 ssize_t read(int fd, void* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size0 buf, size_t count)
152 __overloadable
153 __error_if_overflows_ssizet(count, read)
154 __error_if_overflows_objectsize(count, __bos0(buf), read) {
155 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
156 size_t bos = __bos0(buf);
157
158 if (!__bos_trivially_ge_no_overflow(bos, count)) {
159 return __read_chk(fd, buf, count, bos);
160 }
161 #endif
162 return __call_bypassing_fortify(read)(fd, buf, count);
163 }
164
165 __BIONIC_FORTIFY_INLINE
write(int fd,const void * const __BIONIC_COMPLICATED_NULLNESS __pass_object_size0 buf,size_t count)166 ssize_t write(int fd, const void* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size0 buf, size_t count)
167 __overloadable
168 __error_if_overflows_ssizet(count, write)
169 __error_if_overflows_objectsize(count, __bos0(buf), write) {
170 #if __ANDROID_API__ >= 24 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
171 size_t bos = __bos0(buf);
172
173 if (!__bos_trivially_ge_no_overflow(bos, count)) {
174 return __write_chk(fd, buf, count, bos);
175 }
176 #endif
177 return __call_bypassing_fortify(write)(fd, buf, count);
178 }
179
180 __BIONIC_FORTIFY_INLINE
readlink(const char * _Nonnull path,char * _Nonnull const __pass_object_size buf,size_t size)181 ssize_t readlink(const char* _Nonnull path, char* _Nonnull const __pass_object_size buf, size_t size)
182 __overloadable
183 __error_if_overflows_ssizet(size, readlink)
184 __error_if_overflows_objectsize(size, __bos(buf), readlink) {
185 #if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
186 size_t bos = __bos(buf);
187
188 if (!__bos_trivially_ge_no_overflow(bos, size)) {
189 return __readlink_chk(path, buf, size, bos);
190 }
191 #endif
192 return __call_bypassing_fortify(readlink)(path, buf, size);
193 }
194
195 __BIONIC_FORTIFY_INLINE
readlinkat(int dirfd,const char * _Nonnull path,char * const _Nonnull __pass_object_size buf,size_t size)196 ssize_t readlinkat(int dirfd, const char* _Nonnull path, char* const _Nonnull __pass_object_size buf, size_t size)
197 __overloadable
198 __error_if_overflows_ssizet(size, readlinkat)
199 __error_if_overflows_objectsize(size, __bos(buf), readlinkat) {
200 #if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
201 size_t bos = __bos(buf);
202
203 if (!__bos_trivially_ge_no_overflow(bos, size)) {
204 return __readlinkat_chk(dirfd, path, buf, size, bos);
205 }
206 #endif
207 return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
208 }
209
210 #undef __bos_trivially_ge_no_overflow
211 #undef __enable_if_no_overflow_ssizet
212 #undef __error_if_overflows_objectsize
213 #undef __error_if_overflows_ssizet
214 #undef __PREAD_PREFIX
215 #undef __PWRITE_PREFIX
216 #endif /* defined(__BIONIC_FORTIFY) */
217