Home | History | Annotate | Download | only in fortify
      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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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