From eb088894dc9fb08eb3da82b86ebdabe82ae45940 Mon Sep 17 00:00:00 2001 From: Jit Loon Lim Date: Mon, 17 Mar 2025 16:25:53 +0800 Subject: [PATCH] feat(lib): implement strnlen secure and strcpy secure function Implement safer version of 'strnlen' function to handle NULL terminated strings with additional bound checking and secure version of string copy function to support better security and avoid destination buffer overflow. Change-Id: I93916f003b192c1c6da6a4f78a627c8885db11d9 Signed-off-by: Jit Loon Lim Signed-off-by: Girisha Dengi --- include/lib/libc/string.h | 2 ++ lib/libc/libc_common.mk | 2 ++ lib/libc/strcpy_secure.c | 40 +++++++++++++++++++++++++++++++++++++++ lib/libc/strnlen_secure.c | 22 +++++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 lib/libc/strcpy_secure.c create mode 100644 lib/libc/strnlen_secure.c diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h index 812940418..bba98167b 100644 --- a/include/lib/libc/string.h +++ b/include/lib/libc/string.h @@ -30,5 +30,7 @@ char *strrchr(const char *p, int ch); size_t strlcpy(char * dst, const char * src, size_t dsize); size_t strlcat(char * dst, const char * src, size_t dsize); char *strtok_r(char *s, const char *delim, char **last); +size_t strnlen_secure(const char *str, size_t maxlen); +int strcpy_secure(char *restrict dest, size_t dest_size, const char *restrict src); #endif /* STRING_H */ diff --git a/lib/libc/libc_common.mk b/lib/libc/libc_common.mk index 5f44bd517..3b8321606 100644 --- a/lib/libc/libc_common.mk +++ b/lib/libc/libc_common.mk @@ -21,9 +21,11 @@ LIBC_SRCS := $(addprefix lib/libc/, \ snprintf.c \ strchr.c \ strcmp.c \ + strcpy_secure.c \ strlcat.c \ strlcpy.c \ strlen.c \ + strnlen_secure.c \ strncmp.c \ strnlen.c \ strrchr.c \ diff --git a/lib/libc/strcpy_secure.c b/lib/libc/strcpy_secure.c new file mode 100644 index 000000000..6f8de2982 --- /dev/null +++ b/lib/libc/strcpy_secure.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024-2025, Altera Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +int strcpy_secure(char *restrict dest, size_t dest_size, const char *restrict src) +{ + /* Check for null pointers */ + if ((dest == NULL) || (src == NULL)) { + return -EINVAL; + } + + /* Check the destination size valid range */ + if (dest_size == 0) { + return -ERANGE; + } + + /* Calculate the length of the source string */ + size_t src_len = strnlen_secure(src, dest_size); + + /* Check if the source string fits in the destination buffer */ + if (src_len >= dest_size) { + /* Set destination to an empty string */ + dest[0] = '\0'; + return -ERANGE; + } + + /* Copy the source string to the destination */ + for (dest[src_len] = '\0'; src_len > 0; src_len--) { + dest[src_len - 1] = src[src_len - 1]; + } + + return 0; +} diff --git a/lib/libc/strnlen_secure.c b/lib/libc/strnlen_secure.c new file mode 100644 index 000000000..36b35712f --- /dev/null +++ b/lib/libc/strnlen_secure.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024-2025, Altera Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +size_t strnlen_secure(const char *str, size_t maxlen) +{ + size_t len = 0; + + if (str == NULL) { + return 0; + } + + while ((len < maxlen) && (str[len] != '\0')) { + len++; + } + + return len; +}