1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef _UNISTD_H 17#error "Never include this file directly; instead, include <unistd.h>" 18#endif 19 20#include "fortify.h" 21 22#ifdef __cplusplus 23extern "C" { 24#endif 25 26#if defined(__FORTIFY_COMPILATION) 27 28#define __DIAGNOSE_ERROR_IF_OVERFLOWS_SSIZET(what, fn) \ 29 __DIAGNOSE_ERROR_IF((what) > FORTIFY_SSIZE_MAX, "in call to '" #fn "', '" #what "' must be <= FORTIFY_SSIZE_MAX") 30 31#define __DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(what, objsize, fn) \ 32 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT((objsize), (what)), \ 33 "in call to '" #fn "', '" #what "' bytes overflows the given object") 34 35#define __DIAGNOSE_BOS_TRIVIALLY_GE_NO_OVERFLOW(bos_val, index) \ 36 ((__DIAGNOSE_BOS_DYNAMIC_CHECK_IMPL_AND((bos_val), >=, (index), (bos_val) <= (FORTIFY_SSIZE_MAX)) && \ 37 __builtin_constant_p(index) && (index) <= (FORTIFY_SSIZE_MAX))) 38 39char* __getcwd_chk(char*, size_t, size_t) ; 40 41ssize_t __pread_chk(int, void*, size_t, off_t, size_t); 42ssize_t __pread_real(int, void*, size_t, off_t) __DIAGNOSE_RENAME(pread); 43 44ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t); 45ssize_t __pwrite_real(int, const void*, size_t, off_t) __DIAGNOSE_RENAME(pwrite); 46 47ssize_t __read_chk(int, void*, size_t, size_t); 48ssize_t __write_chk(int, const void*, size_t, size_t); 49 50ssize_t __readlink_chk(const char*, char*, size_t, size_t); 51ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t); 52 53#define __DIAGNOSE_PREAD_PREFIX(x) __pread_ ## x 54#define __DIAGNOSE_PWRITE_PREFIX(x) __pwrite_ ## x 55 56__DIAGNOSE_FORTIFY_INLINE 57char* getcwd(char* const __DIAGNOSE_PASS_OBJECT_SIZE buf, size_t size) 58__DIAGNOSE_OVERLOAD 59__DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(size, __DIAGNOSE_BOS(buf), getcwd) 60{ 61#ifdef __FORTIFY_RUNTIME 62 size_t bos = __DIAGNOSE_BOS(buf); 63 64 if (!__DIAGNOSE_BOS_TRIVIALLY_GE(bos, size)) { 65 return __getcwd_chk(buf, size, bos); 66 } 67#endif 68 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(getcwd)(buf, size); 69} 70 71__DIAGNOSE_FORTIFY_INLINE 72ssize_t pread(int fd, void* const __DIAGNOSE_PASS_OBJECT_SIZE0 buf, size_t count, off_t offset) 73__DIAGNOSE_OVERLOAD 74__DIAGNOSE_ERROR_IF_OVERFLOWS_SSIZET(count, pread) 75__DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(count, __DIAGNOSE_BOS0(buf), pread) 76{ 77#ifdef __FORTIFY_RUNTIME 78 size_t bos = __DIAGNOSE_BOS0(buf); 79 80 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_NO_OVERFLOW(bos, count)) { 81 return __DIAGNOSE_PREAD_PREFIX(chk)(fd, buf, count, offset, bos); 82 } 83#endif 84 return __DIAGNOSE_PREAD_PREFIX(real)(fd, buf, count, offset); 85} 86 87__DIAGNOSE_FORTIFY_INLINE 88ssize_t pwrite(int fd, const void* const __DIAGNOSE_PASS_OBJECT_SIZE0 buf, size_t count, off_t offset) 89__DIAGNOSE_OVERLOAD 90__DIAGNOSE_ERROR_IF_OVERFLOWS_SSIZET(count, pwrite) 91__DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(count, __DIAGNOSE_BOS0(buf), pwrite) 92{ 93#ifdef __FORTIFY_RUNTIME 94 size_t bos = __DIAGNOSE_BOS0(buf); 95 96 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_NO_OVERFLOW(bos, count)) { 97 return __DIAGNOSE_PWRITE_PREFIX(chk)(fd, buf, count, offset, bos); 98 } 99#endif 100 return __DIAGNOSE_PWRITE_PREFIX(real)(fd, buf, count, offset); 101} 102 103__DIAGNOSE_FORTIFY_INLINE 104ssize_t read(int fd, void* const __DIAGNOSE_PASS_OBJECT_SIZE0 buf, size_t count) 105__DIAGNOSE_OVERLOAD 106__DIAGNOSE_ERROR_IF_OVERFLOWS_SSIZET(count, read) 107__DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(count, __DIAGNOSE_BOS0(buf), read) 108{ 109#ifdef __FORTIFY_RUNTIME 110 size_t bos = __DIAGNOSE_BOS0(buf); 111 112 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_NO_OVERFLOW(bos, count)) { 113 return __read_chk(fd, buf, count, bos); 114 } 115#endif 116 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(read)(fd, buf, count); 117} 118 119__DIAGNOSE_FORTIFY_INLINE 120ssize_t write(int fd, const void* const __DIAGNOSE_PASS_OBJECT_SIZE0 buf, size_t count) 121__DIAGNOSE_OVERLOAD 122__DIAGNOSE_ERROR_IF_OVERFLOWS_SSIZET(count, write) 123__DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(count, __DIAGNOSE_BOS0(buf), write) 124{ 125#ifdef __FORTIFY_RUNTIME 126 size_t bos = __DIAGNOSE_BOS0(buf); 127 128 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_NO_OVERFLOW(bos, count)) { 129 return __write_chk(fd, buf, count, bos); 130 } 131#endif 132 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(write)(fd, buf, count); 133} 134 135__DIAGNOSE_FORTIFY_INLINE 136ssize_t readlink(const char* path, char* const __DIAGNOSE_PASS_OBJECT_SIZE buf, size_t size) 137__DIAGNOSE_OVERLOAD 138__DIAGNOSE_ERROR_IF_OVERFLOWS_SSIZET(size, readlink) 139__DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(size, __DIAGNOSE_BOS(buf), readlink) 140{ 141#ifdef __FORTIFY_RUNTIME 142 size_t bos = __DIAGNOSE_BOS(buf); 143 144 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_NO_OVERFLOW(bos, size)) { 145 return __readlink_chk(path, buf, size, bos); 146 } 147#endif 148 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(readlink)(path, buf, size); 149} 150 151__DIAGNOSE_FORTIFY_INLINE 152ssize_t readlinkat(int dirfd, const char* path, char* const __DIAGNOSE_PASS_OBJECT_SIZE buf, size_t size) 153__DIAGNOSE_OVERLOAD 154__DIAGNOSE_ERROR_IF_OVERFLOWS_SSIZET(size, readlinkat) 155__DIAGNOSE_ERROR_IF_OVERFLOWS_OBJECTSIZE(size, __DIAGNOSE_BOS(buf), readlinkat) 156{ 157#ifdef __FORTIFY_RUNTIME 158 size_t bos = __DIAGNOSE_BOS(buf); 159 160 if (!__DIAGNOSE_BOS_TRIVIALLY_GE_NO_OVERFLOW(bos, size)) { 161 return __readlinkat_chk(dirfd, path, buf, size, bos); 162 } 163#endif 164 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(readlinkat)(dirfd, path, buf, size); 165} 166 167#endif // defined(__FORTIFY_COMPILATION) 168 169#ifdef __cplusplus 170} 171#endif