1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved.
3 * Licensed under Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 * Description: memcpy_s function
12 * Author: lishunda
13 * Create: 2014-02-25
14 */
15 /*
16 * [Standardize-exceptions] Use unsafe function: Portability
17 * [reason] Use unsafe function to implement security function to maintain platform compatibility.
18 * And sufficient input validation is performed before calling
19 */
20
21 #include "securecutil.h"
22
23 #ifndef SECUREC_MEMCOPY_WITH_PERFORMANCE
24 #define SECUREC_MEMCOPY_WITH_PERFORMANCE 0
25 #endif
26
27 #if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMCOPY_WITH_PERFORMANCE
28 #ifndef SECUREC_MEMCOPY_THRESHOLD_SIZE
29 #define SECUREC_MEMCOPY_THRESHOLD_SIZE 64UL
30 #endif
31
32 #define SECUREC_SMALL_MEM_COPY(dest, src, count) do { \
33 if (SECUREC_ADDR_ALIGNED_8(dest) && SECUREC_ADDR_ALIGNED_8(src)) { \
34 /* Use struct assignment */ \
35 switch (count) { \
36 case 1: \
37 *(unsigned char *)(dest) = *(const unsigned char *)(src); \
38 break; \
39 case 2: \
40 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 2); \
41 break; \
42 case 3: \
43 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 3); \
44 break; \
45 case 4: \
46 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 4); \
47 break; \
48 case 5: \
49 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 5); \
50 break; \
51 case 6: \
52 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 6); \
53 break; \
54 case 7: \
55 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 7); \
56 break; \
57 case 8: \
58 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 8); \
59 break; \
60 case 9: \
61 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 9); \
62 break; \
63 case 10: \
64 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 10); \
65 break; \
66 case 11: \
67 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 11); \
68 break; \
69 case 12: \
70 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 12); \
71 break; \
72 case 13: \
73 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 13); \
74 break; \
75 case 14: \
76 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 14); \
77 break; \
78 case 15: \
79 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 15); \
80 break; \
81 case 16: \
82 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 16); \
83 break; \
84 case 17: \
85 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 17); \
86 break; \
87 case 18: \
88 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 18); \
89 break; \
90 case 19: \
91 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 19); \
92 break; \
93 case 20: \
94 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 20); \
95 break; \
96 case 21: \
97 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 21); \
98 break; \
99 case 22: \
100 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 22); \
101 break; \
102 case 23: \
103 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 23); \
104 break; \
105 case 24: \
106 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 24); \
107 break; \
108 case 25: \
109 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 25); \
110 break; \
111 case 26: \
112 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 26); \
113 break; \
114 case 27: \
115 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 27); \
116 break; \
117 case 28: \
118 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 28); \
119 break; \
120 case 29: \
121 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 29); \
122 break; \
123 case 30: \
124 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 30); \
125 break; \
126 case 31: \
127 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 31); \
128 break; \
129 case 32: \
130 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 32); \
131 break; \
132 case 33: \
133 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 33); \
134 break; \
135 case 34: \
136 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 34); \
137 break; \
138 case 35: \
139 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 35); \
140 break; \
141 case 36: \
142 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 36); \
143 break; \
144 case 37: \
145 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 37); \
146 break; \
147 case 38: \
148 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 38); \
149 break; \
150 case 39: \
151 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 39); \
152 break; \
153 case 40: \
154 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 40); \
155 break; \
156 case 41: \
157 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 41); \
158 break; \
159 case 42: \
160 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 42); \
161 break; \
162 case 43: \
163 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 43); \
164 break; \
165 case 44: \
166 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 44); \
167 break; \
168 case 45: \
169 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 45); \
170 break; \
171 case 46: \
172 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 46); \
173 break; \
174 case 47: \
175 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 47); \
176 break; \
177 case 48: \
178 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 48); \
179 break; \
180 case 49: \
181 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 49); \
182 break; \
183 case 50: \
184 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 50); \
185 break; \
186 case 51: \
187 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 51); \
188 break; \
189 case 52: \
190 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 52); \
191 break; \
192 case 53: \
193 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 53); \
194 break; \
195 case 54: \
196 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 54); \
197 break; \
198 case 55: \
199 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 55); \
200 break; \
201 case 56: \
202 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 56); \
203 break; \
204 case 57: \
205 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 57); \
206 break; \
207 case 58: \
208 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 58); \
209 break; \
210 case 59: \
211 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 59); \
212 break; \
213 case 60: \
214 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 60); \
215 break; \
216 case 61: \
217 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 61); \
218 break; \
219 case 62: \
220 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 62); \
221 break; \
222 case 63: \
223 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 63); \
224 break; \
225 case 64: \
226 SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 64); \
227 break; \
228 default: \
229 /* Do nothing */ \
230 break; \
231 } /* END switch */ \
232 } else { \
233 unsigned char *tmpDest_ = (unsigned char *)(dest); \
234 const unsigned char *tmpSrc_ = (const unsigned char *)(src); \
235 switch (count) { \
236 case 64: \
237 *(tmpDest_++) = *(tmpSrc_++); \
238 /* fall-through */ /* FALLTHRU */ \
239 case 63: \
240 *(tmpDest_++) = *(tmpSrc_++); \
241 /* fall-through */ /* FALLTHRU */ \
242 case 62: \
243 *(tmpDest_++) = *(tmpSrc_++); \
244 /* fall-through */ /* FALLTHRU */ \
245 case 61: \
246 *(tmpDest_++) = *(tmpSrc_++); \
247 /* fall-through */ /* FALLTHRU */ \
248 case 60: \
249 *(tmpDest_++) = *(tmpSrc_++); \
250 /* fall-through */ /* FALLTHRU */ \
251 case 59: \
252 *(tmpDest_++) = *(tmpSrc_++); \
253 /* fall-through */ /* FALLTHRU */ \
254 case 58: \
255 *(tmpDest_++) = *(tmpSrc_++); \
256 /* fall-through */ /* FALLTHRU */ \
257 case 57: \
258 *(tmpDest_++) = *(tmpSrc_++); \
259 /* fall-through */ /* FALLTHRU */ \
260 case 56: \
261 *(tmpDest_++) = *(tmpSrc_++); \
262 /* fall-through */ /* FALLTHRU */ \
263 case 55: \
264 *(tmpDest_++) = *(tmpSrc_++); \
265 /* fall-through */ /* FALLTHRU */ \
266 case 54: \
267 *(tmpDest_++) = *(tmpSrc_++); \
268 /* fall-through */ /* FALLTHRU */ \
269 case 53: \
270 *(tmpDest_++) = *(tmpSrc_++); \
271 /* fall-through */ /* FALLTHRU */ \
272 case 52: \
273 *(tmpDest_++) = *(tmpSrc_++); \
274 /* fall-through */ /* FALLTHRU */ \
275 case 51: \
276 *(tmpDest_++) = *(tmpSrc_++); \
277 /* fall-through */ /* FALLTHRU */ \
278 case 50: \
279 *(tmpDest_++) = *(tmpSrc_++); \
280 /* fall-through */ /* FALLTHRU */ \
281 case 49: \
282 *(tmpDest_++) = *(tmpSrc_++); \
283 /* fall-through */ /* FALLTHRU */ \
284 case 48: \
285 *(tmpDest_++) = *(tmpSrc_++); \
286 /* fall-through */ /* FALLTHRU */ \
287 case 47: \
288 *(tmpDest_++) = *(tmpSrc_++); \
289 /* fall-through */ /* FALLTHRU */ \
290 case 46: \
291 *(tmpDest_++) = *(tmpSrc_++); \
292 /* fall-through */ /* FALLTHRU */ \
293 case 45: \
294 *(tmpDest_++) = *(tmpSrc_++); \
295 /* fall-through */ /* FALLTHRU */ \
296 case 44: \
297 *(tmpDest_++) = *(tmpSrc_++); \
298 /* fall-through */ /* FALLTHRU */ \
299 case 43: \
300 *(tmpDest_++) = *(tmpSrc_++); \
301 /* fall-through */ /* FALLTHRU */ \
302 case 42: \
303 *(tmpDest_++) = *(tmpSrc_++); \
304 /* fall-through */ /* FALLTHRU */ \
305 case 41: \
306 *(tmpDest_++) = *(tmpSrc_++); \
307 /* fall-through */ /* FALLTHRU */ \
308 case 40: \
309 *(tmpDest_++) = *(tmpSrc_++); \
310 /* fall-through */ /* FALLTHRU */ \
311 case 39: \
312 *(tmpDest_++) = *(tmpSrc_++); \
313 /* fall-through */ /* FALLTHRU */ \
314 case 38: \
315 *(tmpDest_++) = *(tmpSrc_++); \
316 /* fall-through */ /* FALLTHRU */ \
317 case 37: \
318 *(tmpDest_++) = *(tmpSrc_++); \
319 /* fall-through */ /* FALLTHRU */ \
320 case 36: \
321 *(tmpDest_++) = *(tmpSrc_++); \
322 /* fall-through */ /* FALLTHRU */ \
323 case 35: \
324 *(tmpDest_++) = *(tmpSrc_++); \
325 /* fall-through */ /* FALLTHRU */ \
326 case 34: \
327 *(tmpDest_++) = *(tmpSrc_++); \
328 /* fall-through */ /* FALLTHRU */ \
329 case 33: \
330 *(tmpDest_++) = *(tmpSrc_++); \
331 /* fall-through */ /* FALLTHRU */ \
332 case 32: \
333 *(tmpDest_++) = *(tmpSrc_++); \
334 /* fall-through */ /* FALLTHRU */ \
335 case 31: \
336 *(tmpDest_++) = *(tmpSrc_++); \
337 /* fall-through */ /* FALLTHRU */ \
338 case 30: \
339 *(tmpDest_++) = *(tmpSrc_++); \
340 /* fall-through */ /* FALLTHRU */ \
341 case 29: \
342 *(tmpDest_++) = *(tmpSrc_++); \
343 /* fall-through */ /* FALLTHRU */ \
344 case 28: \
345 *(tmpDest_++) = *(tmpSrc_++); \
346 /* fall-through */ /* FALLTHRU */ \
347 case 27: \
348 *(tmpDest_++) = *(tmpSrc_++); \
349 /* fall-through */ /* FALLTHRU */ \
350 case 26: \
351 *(tmpDest_++) = *(tmpSrc_++); \
352 /* fall-through */ /* FALLTHRU */ \
353 case 25: \
354 *(tmpDest_++) = *(tmpSrc_++); \
355 /* fall-through */ /* FALLTHRU */ \
356 case 24: \
357 *(tmpDest_++) = *(tmpSrc_++); \
358 /* fall-through */ /* FALLTHRU */ \
359 case 23: \
360 *(tmpDest_++) = *(tmpSrc_++); \
361 /* fall-through */ /* FALLTHRU */ \
362 case 22: \
363 *(tmpDest_++) = *(tmpSrc_++); \
364 /* fall-through */ /* FALLTHRU */ \
365 case 21: \
366 *(tmpDest_++) = *(tmpSrc_++); \
367 /* fall-through */ /* FALLTHRU */ \
368 case 20: \
369 *(tmpDest_++) = *(tmpSrc_++); \
370 /* fall-through */ /* FALLTHRU */ \
371 case 19: \
372 *(tmpDest_++) = *(tmpSrc_++); \
373 /* fall-through */ /* FALLTHRU */ \
374 case 18: \
375 *(tmpDest_++) = *(tmpSrc_++); \
376 /* fall-through */ /* FALLTHRU */ \
377 case 17: \
378 *(tmpDest_++) = *(tmpSrc_++); \
379 /* fall-through */ /* FALLTHRU */ \
380 case 16: \
381 *(tmpDest_++) = *(tmpSrc_++); \
382 /* fall-through */ /* FALLTHRU */ \
383 case 15: \
384 *(tmpDest_++) = *(tmpSrc_++); \
385 /* fall-through */ /* FALLTHRU */ \
386 case 14: \
387 *(tmpDest_++) = *(tmpSrc_++); \
388 /* fall-through */ /* FALLTHRU */ \
389 case 13: \
390 *(tmpDest_++) = *(tmpSrc_++); \
391 /* fall-through */ /* FALLTHRU */ \
392 case 12: \
393 *(tmpDest_++) = *(tmpSrc_++); \
394 /* fall-through */ /* FALLTHRU */ \
395 case 11: \
396 *(tmpDest_++) = *(tmpSrc_++); \
397 /* fall-through */ /* FALLTHRU */ \
398 case 10: \
399 *(tmpDest_++) = *(tmpSrc_++); \
400 /* fall-through */ /* FALLTHRU */ \
401 case 9: \
402 *(tmpDest_++) = *(tmpSrc_++); \
403 /* fall-through */ /* FALLTHRU */ \
404 case 8: \
405 *(tmpDest_++) = *(tmpSrc_++); \
406 /* fall-through */ /* FALLTHRU */ \
407 case 7: \
408 *(tmpDest_++) = *(tmpSrc_++); \
409 /* fall-through */ /* FALLTHRU */ \
410 case 6: \
411 *(tmpDest_++) = *(tmpSrc_++); \
412 /* fall-through */ /* FALLTHRU */ \
413 case 5: \
414 *(tmpDest_++) = *(tmpSrc_++); \
415 /* fall-through */ /* FALLTHRU */ \
416 case 4: \
417 *(tmpDest_++) = *(tmpSrc_++); \
418 /* fall-through */ /* FALLTHRU */ \
419 case 3: \
420 *(tmpDest_++) = *(tmpSrc_++); \
421 /* fall-through */ /* FALLTHRU */ \
422 case 2: \
423 *(tmpDest_++) = *(tmpSrc_++); \
424 /* fall-through */ /* FALLTHRU */ \
425 case 1: \
426 *(tmpDest_++) = *(tmpSrc_++); \
427 /* fall-through */ /* FALLTHRU */ \
428 default: \
429 /* Do nothing */ \
430 break; \
431 } \
432 } \
433 } SECUREC_WHILE_ZERO
434
435 /*
436 * Performance optimization
437 */
438 #define SECUREC_MEMCPY_OPT(dest, src, count) do { \
439 if ((count) > SECUREC_MEMCOPY_THRESHOLD_SIZE) { \
440 SECUREC_MEMCPY_WARP_OPT((dest), (src), (count)); \
441 } else { \
442 SECUREC_SMALL_MEM_COPY((dest), (src), (count)); \
443 } \
444 } SECUREC_WHILE_ZERO
445 #endif
446
447 /*
448 * Handling errors
449 */
SecMemcpyError(void * dest,size_t destMax,const void * src,size_t count)450 SECUREC_INLINE errno_t SecMemcpyError(void *dest, size_t destMax, const void *src, size_t count)
451 {
452 if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
453 SECUREC_ERROR_INVALID_RANGE("memcpy_s");
454 return ERANGE;
455 }
456 if (dest == NULL || src == NULL) {
457 SECUREC_ERROR_INVALID_PARAMTER("memcpy_s");
458 if (dest != NULL) {
459 (void)memset(dest, 0, destMax);
460 return EINVAL_AND_RESET;
461 }
462 return EINVAL;
463 }
464 if (count > destMax) {
465 (void)memset(dest, 0, destMax);
466 SECUREC_ERROR_INVALID_RANGE("memcpy_s");
467 return ERANGE_AND_RESET;
468 }
469 if (SECUREC_MEMORY_IS_OVERLAP(dest, src, count)) {
470 (void)memset(dest, 0, destMax);
471 SECUREC_ERROR_BUFFER_OVERLAP("memcpy_s");
472 return EOVERLAP_AND_RESET;
473 }
474 /* Count is 0 or dest equal src also ret EOK */
475 return EOK;
476 }
477
478 #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
479 /*
480 * The fread API in windows will call memcpy_s and pass 0xffffffff to destMax.
481 * To avoid the failure of fread, we don't check desMax limit.
482 */
483 #define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \
484 (dest) != NULL && (src) != NULL && \
485 (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
486 #else
487 #define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \
488 (dest) != NULL && (src) != NULL && (destMax) <= SECUREC_MEM_MAX_LEN && \
489 (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
490 #endif
491
492 /*
493 * <FUNCTION DESCRIPTION>
494 * The memcpy_s function copies n characters from the object pointed to by src into the object pointed to by dest
495 *
496 * <INPUT PARAMETERS>
497 * dest Destination buffer.
498 * destMax Size of the destination buffer.
499 * src Buffer to copy from.
500 * count Number of characters to copy
501 *
502 * <OUTPUT PARAMETERS>
503 * dest buffer is updated.
504 *
505 * <RETURN VALUE>
506 * EOK Success
507 * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
508 * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
509 * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0
510 * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
511 * and dest != NULL and src != NULL
512 * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
513 * count <= destMax destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL
514 * and src != NULL and dest != src
515 *
516 * if an error occured, dest will be filled with 0.
517 * If the source and destination overlap, the behavior of memcpy_s is undefined.
518 * Use memmove_s to handle overlapping regions.
519 */
memcpy_s(void * dest,size_t destMax,const void * src,size_t count)520 errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count)
521 {
522 if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
523 #if SECUREC_MEMCOPY_WITH_PERFORMANCE
524 SECUREC_MEMCPY_OPT(dest, src, count);
525 #else
526 SECUREC_MEMCPY_WARP_OPT(dest, src, count);
527 #endif
528 return EOK;
529 }
530 /* Meet some runtime violation, return error code */
531 return SecMemcpyError(dest, destMax, src, count);
532 }
533
534 #if SECUREC_IN_KERNEL
535 EXPORT_SYMBOL(memcpy_s);
536 #endif
537
538 #if SECUREC_WITH_PERFORMANCE_ADDONS
539 /*
540 * Performance optimization
541 */
memcpy_sOptAsm(void * dest,size_t destMax,const void * src,size_t count)542 errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count)
543 {
544 if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
545 SECUREC_MEMCPY_OPT(dest, src, count);
546 return EOK;
547 }
548 /* Meet some runtime violation, return error code */
549 return SecMemcpyError(dest, destMax, src, count);
550 }
551
552 /* Trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" */
memcpy_sOptTc(void * dest,size_t destMax,const void * src,size_t count)553 errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count)
554 {
555 if (SECUREC_LIKELY(count <= destMax && dest != NULL && src != NULL && \
556 count > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) {
557 SECUREC_MEMCPY_OPT(dest, src, count);
558 return EOK;
559 }
560 /* Meet some runtime violation, return error code */
561 return SecMemcpyError(dest, destMax, src, count);
562 }
563 #endif
564
565