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 _STRING_H
17 #error "Never include this file directly; instead, include <string.h>"
18 #endif
19
20 #include "fortify.h"
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 void *__memchr_diagnose(const void* s, int c, size_t n, size_t actual_size);
27 void *__memrchr_chk(const void*, int, size_t, size_t);
28 size_t __strlcpy_diagnose(char*, const char*, size_t, size_t);
29 size_t __strlcat_diagnose(char*, const char*, size_t, size_t);
30 char *__strchr_diagnose(const char* p, int ch, size_t s_len);
31 char *__strrchr_diagnose(const char *p, int ch, size_t s_len);
32 size_t __strlen_chk(const char* s, size_t s_len);
33
34 #ifdef __FORTIFY_COMPILATION
35 __DIAGNOSE_FORTIFY_INLINE
strcpy(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * src)36 char *strcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src)
37 __DIAGNOSE_OVERLOAD
38 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)),
39 "'strcpy' " CALLED_WITH_STRING_BIGGER_BUFFER)
40 {
41 #ifdef __FORTIFY_RUNTIME
42 return __builtin___strcpy_chk(dest, src, __DIAGNOSE_BOS(dest));
43 #else
44 return __builtin_strcpy(dest, src);
45 #endif
46 }
47
48 __DIAGNOSE_FORTIFY_INLINE
stpcpy(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * src)49 char *stpcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src)
50 __DIAGNOSE_OVERLOAD
51 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)),
52 "'stpcpy' " CALLED_WITH_STRING_BIGGER_BUFFER)
53 {
54 #ifdef __FORTIFY_RUNTIME
55 return __builtin___stpcpy_chk(dest, src, __DIAGNOSE_BOS(dest));
56 #else
57 return __builtin_stpcpy(dest, src);
58 #endif
59 }
60
61 __DIAGNOSE_FORTIFY_INLINE
memmove(void * const dest __DIAGNOSE_PASS_OBJECT_SIZE0,const void * src,size_t len)62 void *memmove(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE0, const void *src, size_t len)
63 __DIAGNOSE_OVERLOAD
64 {
65 #ifdef __FORTIFY_RUNTIME
66 return __builtin___memmove_chk(dest, src, len, __DIAGNOSE_BOS(dest));
67 #else
68 return __builtin_memmove(dest, src, len);
69 #endif
70 }
71
72 __DIAGNOSE_FORTIFY_INLINE
mempcpy(void * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const void * src,size_t copy_amount)73 void *mempcpy(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const void *src, size_t copy_amount)
74 __DIAGNOSE_OVERLOAD
75 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS0(dest), copy_amount),
76 "'mempcpy' " CALLED_WITH_STRING_BIGGER_BUFFER)
77 {
78 #ifdef __FORTIFY_RUNTIME
79 return __builtin___mempcpy_chk(dest, src, copy_amount, __DIAGNOSE_BOS0(dest));
80 #else
81 return __builtin_mempcpy(dest, src, copy_amount);
82 #endif
83 }
84
85 __DIAGNOSE_FORTIFY_INLINE
strcat(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * src)86 char *strcat(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src)
87 __DIAGNOSE_OVERLOAD
88 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)),
89 "'strcat' " CALLED_WITH_STRING_BIGGER_BUFFER)
90 {
91 #ifdef __FORTIFY_RUNTIME
92 return __builtin___strcat_chk(dest, src, __DIAGNOSE_BOS(dest));
93 #else
94 return __builtin_strcat(dest, src);
95 #endif
96 }
97
98 #ifdef __FORTIFY_RUNTIME
99 __DIAGNOSE_FORTIFY_INLINE
strncat(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * src,size_t n)100 char *strncat(char* const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char* src, size_t n)
101 __DIAGNOSE_OVERLOAD
102 {
103 return __builtin___strncat_chk(dest, src, n, __DIAGNOSE_BOS(dest));
104 }
105 #endif
106
107 #ifdef __FORTIFY_RUNTIME
108 __DIAGNOSE_FORTIFY_INLINE
stpncpy(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * const src __DIAGNOSE_PASS_OBJECT_SIZE,size_t n)109 char *stpncpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE,
110 const char *const src __DIAGNOSE_PASS_OBJECT_SIZE, size_t n)
111 __DIAGNOSE_OVERLOAD
112 {
113 size_t bos_dest = __DIAGNOSE_BOS(dest);
114 return __builtin___stpncpy_chk(dest, src, n, bos_dest);
115 }
116 #endif
117
118 #ifdef __FORTIFY_RUNTIME
119 __DIAGNOSE_FORTIFY_INLINE
strncpy(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * const src __DIAGNOSE_PASS_OBJECT_SIZE,size_t n)120 char *strncpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE,
121 const char *const src __DIAGNOSE_PASS_OBJECT_SIZE, size_t n)
122 __DIAGNOSE_OVERLOAD
123 {
124 size_t bos_dest = __DIAGNOSE_BOS(dest);
125 return __builtin___strncpy_chk(dest, src, n, bos_dest);
126 }
127 #endif
128
129 #ifdef __FORTIFY_RUNTIME
130 __DIAGNOSE_FORTIFY_INLINE
memcpy(void * const dest __DIAGNOSE_PASS_OBJECT_SIZE0,const void * src,size_t copy_amount)131 void *memcpy(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE0, const void *src, size_t copy_amount)
132 __DIAGNOSE_OVERLOAD
133 {
134 return __builtin___memcpy_chk(dest, src, copy_amount, __DIAGNOSE_BOS0(dest));
135 }
136 #endif
137
138 #if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
139 __DIAGNOSE_FORTIFY_INLINE
strlcpy(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * src,size_t size)140 size_t strlcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src, size_t size)
141 __DIAGNOSE_OVERLOAD
142 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS(dest), size),
143 "'strlcpy' called with size bigger than buffer")
144 {
145 #ifdef __FORTIFY_RUNTIME
146 return __strlcpy_diagnose(dest, src, size, __DIAGNOSE_BOS(dest));
147 #else
148 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strlcpy)(dest, src, size);
149 #endif
150 }
151
152 __DIAGNOSE_FORTIFY_INLINE
strlcat(char * const dest __DIAGNOSE_PASS_OBJECT_SIZE,const char * src,size_t size)153 size_t strlcat(char* const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char* src, size_t size)
154 __DIAGNOSE_OVERLOAD
155 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS(dest), size),
156 "'strlcat' called with size bigger than buffer")
157 {
158 #ifdef __FORTIFY_RUNTIME
159 return __strlcat_diagnose(dest, src, size, __DIAGNOSE_BOS(dest));
160 #else
161 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strlcat)(dest, src, size);
162 #endif
163 }
164 #endif // defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
165
166 __DIAGNOSE_FORTIFY_INLINE
memset(void * const s __DIAGNOSE_PASS_OBJECT_SIZE0,int c,size_t n)167 void *memset(void *const s __DIAGNOSE_PASS_OBJECT_SIZE0, int c, size_t n)
168 __DIAGNOSE_OVERLOAD
169 __DIAGNOSE_WARNING_IF(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?")
170 {
171 #ifdef __FORTIFY_RUNTIME
172 return __builtin___memset_chk(s, c, n, __DIAGNOSE_BOS0(s));
173 #else
174 return __builtin_memset(s, c, n);
175 #endif
176 }
177
178 #ifdef __FORTIFY_RUNTIME
179 __DIAGNOSE_FORTIFY_INLINE
memchr(const void * const s __DIAGNOSE_PASS_OBJECT_SIZE,int c,size_t n)180 void *memchr(const void *const s __DIAGNOSE_PASS_OBJECT_SIZE, int c, size_t n)
181 __DIAGNOSE_OVERLOAD
182 {
183 size_t bos = __DIAGNOSE_BOS(s);
184 if (__DIAGNOSE_BOS_TRIVIALLY_GE(bos, n)) {
185 return __builtin_memchr(s, c, n);
186 }
187 return __memchr_diagnose(s, c, n, bos);
188 }
189 #endif // memchr __FORTIFY_RUNTIME
190
191 extern void* __memrchr_real(const void*, int, size_t) __DIAGNOSE_RENAME(memrchr);
192
193 #ifdef __FORTIFY_RUNTIME
194 __DIAGNOSE_FORTIFY_INLINE
memrchr(const void * const __DIAGNOSE_PASS_OBJECT_SIZE s,int c,size_t n)195 void *memrchr(const void *const __DIAGNOSE_PASS_OBJECT_SIZE s, int c, size_t n)
196 __DIAGNOSE_OVERLOAD
197 {
198 size_t bos = __DIAGNOSE_BOS(s);
199 if (__DIAGNOSE_BOS_TRIVIALLY_GE(bos, n)) {
200 return __memrchr_real(s, c, n);
201 }
202 return __memrchr_chk(s, c, n, bos);
203 }
204 #endif
205
206 __DIAGNOSE_FORTIFY_INLINE
strchr(const char * const s __DIAGNOSE_PASS_OBJECT_SIZE,int c)207 char* strchr(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE, int c)
208 __DIAGNOSE_OVERLOAD
209 {
210 #ifdef __FORTIFY_RUNTIME
211 size_t bos = __DIAGNOSE_BOS(s);
212
213 if (bos != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE) {
214 return __strchr_diagnose(s, c, bos);
215 }
216 #endif
217 return __builtin_strchr(s, c);
218 }
219
220 __DIAGNOSE_FORTIFY_INLINE
strrchr(const char * const s __DIAGNOSE_PASS_OBJECT_SIZE,int c)221 char* strrchr(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE, int c)
222 __DIAGNOSE_OVERLOAD
223 {
224 #ifdef __FORTIFY_RUNTIME
225 size_t bos = __DIAGNOSE_BOS(s);
226
227 if (bos != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE) {
228 return __strrchr_diagnose(s, c, bos);
229 }
230 #endif
231 return __builtin_strrchr(s, c);
232 }
233
234 #ifdef __FORTIFY_RUNTIME
235 __DIAGNOSE_FORTIFY_INLINE
strlen(const char * const s __DIAGNOSE_PASS_OBJECT_SIZE0)236 size_t strlen(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE0)
237 __DIAGNOSE_OVERLOAD
238 {
239 return __strlen_chk(s, __DIAGNOSE_BOS0(s));
240 }
241 #endif
242
243 #endif // __FORTIFY_COMPILATION
244 #ifdef __cplusplus
245 }
246 #endif