• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 /* [Standardize-exceptions] Use unsafe function: Portability
16  * [reason] Use unsafe function to implement security function to maintain platform compatibility.
17  *          And sufficient input validation is performed before calling
18  */
19 
20 #include "securecutil.h"
21 
22 #ifdef SECUREC_NOT_CALL_LIBC_CORE_API
SecUtilMemmove(void * dst,const void * src,size_t count)23 static void SecUtilMemmove(void *dst, const void *src, size_t count)
24 {
25     unsigned char *pDest = (unsigned char *)dst;
26     const unsigned char *pSrc = (const unsigned char *)src;
27     size_t maxCount = count;
28 
29     if (dst <= src || pDest >= (pSrc + maxCount)) {
30         /*
31          * Non-Overlapping Buffers
32          * copy from lower addresses to higher addresses
33          */
34         while (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 
47         while (maxCount--) {
48             *pDest = *pSrc;
49 
50             --pDest;
51             --pSrc;
52         }
53     }
54 }
55 #endif
56 
57 /*******************************************************************************
58  * <FUNCTION DESCRIPTION>
59  *    Copies count bytes of characters from src to dest.
60  *
61  * <INPUT PARAMETERS>
62  *    dest                                 Destination object.
63  *    destMax                           Size of the destination buffer.
64  *    src                                   Source object.
65  *    count                                Number of characters to copy.
66  *
67  * <OUTPUT PARAMETERS>
68  *    dest buffer                       is updated.
69  *
70  * <RETURN VALUE>
71  *    EOK                                 Success
72  *    EINVAL                            dest is  NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
73  *    EINVAL_AND_RESET         dest != NULL and src is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
74  *    ERANGE                           destMax > SECUREC_MEM_MAX_LEN or destMax is 0
75  *    ERANGE_AND_RESET        count > destMax and dest  !=  NULL and src != NULL and destMax != 0
76  *                            and destMax <= SECUREC_MEM_MAX_LEN
77  *
78  *    If an error occurred, dest will  be filled with 0 when dest and destMax valid.
79  *    If some regions of the source area and the destination overlap, memmove_s
80  *    ensures that the original source bytes in the overlapping region are copied
81  *    before being overwritten.
82  *******************************************************************************
83  */
memmove_s(void * dest,size_t destMax,const void * src,size_t count)84 errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count)
85 {
86     if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
87         SECUREC_ERROR_INVALID_RANGE("memmove_s");
88         return ERANGE;
89     }
90     if (dest == NULL || src == NULL) {
91         SECUREC_ERROR_INVALID_PARAMTER("memmove_s");
92         if (dest != NULL) {
93             (void)memset(dest, 0, destMax);
94             return EINVAL_AND_RESET;
95         }
96         return EINVAL;
97     }
98     if (count > destMax) {
99         (void)memset(dest, 0, destMax);
100         SECUREC_ERROR_INVALID_RANGE("memmove_s");
101         return ERANGE_AND_RESET;
102     }
103     if (dest == src) {
104         return EOK;
105     }
106 
107     if (count > 0) {
108 #ifdef SECUREC_NOT_CALL_LIBC_CORE_API
109         SecUtilMemmove(dest, src, count);
110 #else
111         /* use underlying memmove for performance consideration */
112         (void)memmove(dest, src, count);
113 #endif
114     }
115     return EOK;
116 }
117 
118 #if SECUREC_IN_KERNEL
119 EXPORT_SYMBOL(memmove_s);
120 #endif
121 
122