feat(lib): implement memcpy_s in lib
To support memcpy_s for better security purpose
to avoid overflowing the dest while copy from src.
Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Change-Id: I63c3ea6a3e99c10d69be6bce04843c14b0a28a4d
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index 9894483..7ddeed9 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -5,6 +5,7 @@
*/
/*
* Portions copyright (c) 2018-2020, ARM Limited and Contributors.
+ * Portions copyright (c) 2023, Intel Corporation. All rights reserved.
* All rights reserved.
*/
@@ -14,6 +15,7 @@
#include <stddef.h>
void *memcpy(void *dst, const void *src, size_t len);
+int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize);
void *memmove(void *dst, const void *src, size_t len);
int memcmp(const void *s1, const void *s2, size_t len);
int strcmp(const char *s1, const char *s2);
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index b75d09c..5eb8b52 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -11,6 +11,7 @@
memchr.c \
memcmp.c \
memcpy.c \
+ memcpy_s.c \
memmove.c \
memrchr.c \
memset.c \
diff --git a/lib/libc/memcpy_s.c b/lib/libc/memcpy_s.c
new file mode 100644
index 0000000..01e88b0
--- /dev/null
+++ b/lib/libc/memcpy_s.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize)
+{
+ unsigned int *s = (unsigned int *)src;
+ unsigned int *d = (unsigned int *)dst;
+
+ /*
+ * Check source and destination size is NULL
+ */
+ if ((dst == NULL) || (src == NULL)) {
+ return -ENOMEM;
+ }
+
+ /*
+ * Check source and destination size validity
+ */
+ if ((dsize == 0) || (ssize == 0)) {
+ return -ERANGE;
+ }
+
+ /*
+ * Check both source and destination size range
+ */
+ if ((ssize > dsize) || (dsize > ssize)) {
+ return -EINVAL;
+ }
+
+ /*
+ * Check both source and destination address overlapping
+ * When (s > d < s + ssize)
+ * Or (d > s < d + dsize)
+ */
+
+ if (d > s) {
+ if ((d) < (s + ssize)) {
+ return -EOPNOTSUPP;
+ }
+ }
+
+ if (s > d) {
+ if ((s) < (d + dsize)) {
+ return -EOPNOTSUPP;
+ }
+ }
+
+ /*
+ * Start copy process when there is no error
+ */
+ while (ssize--) {
+ d[ssize] = s[ssize];
+ }
+
+ return 0;
+}