• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
23 extern "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 
39 char* __getcwd_chk(char*, size_t, size_t) ;
40 
41 ssize_t __pread_chk(int, void*, size_t, off_t, size_t);
42 ssize_t __pread_real(int, void*, size_t, off_t) __DIAGNOSE_RENAME(pread);
43 
44 ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t);
45 ssize_t __pwrite_real(int, const void*, size_t, off_t) __DIAGNOSE_RENAME(pwrite);
46 
47 ssize_t __read_chk(int, void*, size_t, size_t);
48 ssize_t __write_chk(int, const void*, size_t, size_t);
49 
50 ssize_t __readlink_chk(const char*, char*, size_t, size_t);
51 ssize_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
getcwd(char * const __DIAGNOSE_PASS_OBJECT_SIZE buf,size_t size)57 char* 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
pread(int fd,void * const __DIAGNOSE_PASS_OBJECT_SIZE0 buf,size_t count,off_t offset)72 ssize_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
pwrite(int fd,const void * const __DIAGNOSE_PASS_OBJECT_SIZE0 buf,size_t count,off_t offset)88 ssize_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
read(int fd,void * const __DIAGNOSE_PASS_OBJECT_SIZE0 buf,size_t count)104 ssize_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
write(int fd,const void * const __DIAGNOSE_PASS_OBJECT_SIZE0 buf,size_t count)120 ssize_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
readlink(const char * path,char * const __DIAGNOSE_PASS_OBJECT_SIZE buf,size_t size)136 ssize_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
readlinkat(int dirfd,const char * path,char * const __DIAGNOSE_PASS_OBJECT_SIZE buf,size_t size)152 ssize_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