• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: memmove_s function
12  * Author: lishunda
13  * Create: 2014-02-25
14  */
15 
16 #include "securecutil.h"
17 
18 #ifdef SECUREC_NOT_CALL_LIBC_CORE_API
19 /*
20  * Implementing memory data movement
21  */
SecUtilMemmove(void * dst,const void * src,size_t count)22 SECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count)
23 {
24     unsigned char *pDest = (unsigned char *)dst;
25     const unsigned char *pSrc = (const unsigned char *)src;
26     size_t maxCount = count;
27 
28     if (dst <= src || pDest >= (pSrc + maxCount)) {
29         /*
30          * Non-Overlapping Buffers
31          * Copy from lower addresses to higher addresses
32          */
33         while (maxCount > 0) {
34             --maxCount;
35             *pDest = *pSrc;
36             ++pDest;
37             ++pSrc;
38         }
39     } else {
40         /*
41          * Overlapping Buffers
42          * Copy from higher addresses to lower addresses
43          */
44         pDest = pDest + maxCount - 1;
45         pSrc = pSrc + maxCount - 1;
46         while (maxCount > 0) {
47             --maxCount;
48             *pDest = *pSrc;
49             --pDest;
50             --pSrc;
51         }
52     }
53 }
54 #endif
55 
56 /*
57  * <FUNCTION DESCRIPTION>
58  *    The memmove_s function copies count bytes of characters from src to dest.
59  *    This function can be assigned correctly when memory overlaps.
60  * <INPUT PARAMETERS>
61  *    dest                    Destination object.
62  *    destMax                 Size of the destination buffer.
63  *    src                     Source object.
64  *    count                   Number of characters to copy.
65  *
66  * <OUTPUT PARAMETERS>
67  *    dest buffer             is uptdated.
68  *
69  * <RETURN VALUE>
70  *    EOK                     Success
71  *    EINVAL                  dest is  NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
72  *    EINVAL_AND_RESET        dest != NULL and src is NULLL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
73  *    ERANGE                  destMax > SECUREC_MEM_MAX_LEN or destMax is 0
74  *    ERANGE_AND_RESET        count > destMax and dest  !=  NULL and src != NULL and destMax != 0
75  *                            and destMax <= SECUREC_MEM_MAX_LEN
76  *
77  *    If an error occured, dest will  be filled with 0 when dest and destMax valid.
78  *    If some regions of the source area and the destination overlap, memmove_s
79  *    ensures that the original source bytes in the overlapping region are copied
80  *    before being overwritten.
81  */
memmove_s(void * dest,size_t destMax,const void * src,size_t count)82 errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count)
83 {
84     if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
85         SECUREC_ERROR_INVALID_RANGE("memmove_s");
86         return ERANGE;
87     }
88     if (dest == NULL || src == NULL) {
89         SECUREC_ERROR_INVALID_PARAMTER("memmove_s");
90         if (dest != NULL) {
91             (void)memset(dest, 0, destMax);
92             return EINVAL_AND_RESET;
93         }
94         return EINVAL;
95     }
96     if (count > destMax) {
97         (void)memset(dest, 0, destMax);
98         SECUREC_ERROR_INVALID_RANGE("memmove_s");
99         return ERANGE_AND_RESET;
100     }
101     if (dest == src) {
102         return EOK;
103     }
104 
105     if (count > 0) {
106 #ifdef SECUREC_NOT_CALL_LIBC_CORE_API
107         SecUtilMemmove(dest, src, count);
108 #else
109         /* Use underlying memmove for performance consideration */
110         (void)memmove(dest, src, count);
111 #endif
112     }
113     return EOK;
114 }
115 
116 #if SECUREC_IN_KERNEL
117 EXPORT_SYMBOL(memmove_s);
118 #endif
119 
120