• 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 _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