Skip to content

Commit

Permalink
lib: utils: implement internal safe_strcpy function
Browse files Browse the repository at this point in the history
The strlcpy() function has only recently become available in glibc.
While this function prevents destination buffer overflow, it seems
that it cannot guarantee read access only within the source buffer.
this is for instance the case if the source string is not terminated by
a'\0' character.
Implement a safe_strcpy to ensure that no access is done out of the
source and destination buffer ranges.

Signed-off-by: Arnaud Pouliquen <[email protected]>
  • Loading branch information
arnopo committed Oct 18, 2024
1 parent a69881f commit 9aa3ee5
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ collect (PROJECT_LIB_SOURCES version.c)
add_subdirectory (virtio)
add_subdirectory (rpmsg)
add_subdirectory (remoteproc)
add_subdirectory (utils)
if (WITH_VIRTIO_MMIO_DRV)
add_subdirectory (virtio_mmio)
endif (WITH_VIRTIO_MMIO_DRV)
Expand All @@ -23,6 +24,7 @@ set (OPENAMP_LIB open_amp)

configure_file(version.h.in ${PROJECT_BINARY_DIR}/include/generated/openamp/version_def.h)
collect (PROJECT_INC_DIRS " ${PROJECT_BINARY_DIR}/include/generated/openamp")
collect (PROJECT_INC_DIRS " ${PROJECT_BINARY_DIR}/include/internal")

if (NOT CMAKE_INSTALL_LIBDIR)
set (CMAKE_INSTALL_LIBDIR "lib")
Expand Down
35 changes: 35 additions & 0 deletions lib/include/internal/utilities.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2024, STMicroelectronics
*
*/

#include <string.h>

/**
* @internal
*
* @brief Copies a string to a destination buffer with size limitation and returns the length of
* the destination string.
*
* This function copies up to `s_size - 1` characters from the source string `src`
* to the destination buffer `dst`, ensuring that the destination buffer is
* null-terminated. The function returns the length of the `dst` string.
* If the length of `src` string is greater than or equal to `d_size`, the destination
* buffer will be truncated.
*
* @param dst Destination buffer where the string will be copied.
* @param d_size Size of the destination buffer.
* @param src Source string to be copied.
* @param s_size Size of the source buffer.
* @return The length of the string contained in the `dst` buffer.
*
* @note If the size of the destination buffer is 0, the function does not copy any characters and
* the destination buffer is not null-terminated.
* @note The function ensures that the destination buffer is always null-terminated if `size` is
* greater than 0.
* @note The function ensures that no data is read past the end of the 'src' buffer.
*/
size_t safe_strcpy(char *dst, size_t d_size, const char *src, size_t s_size);

1 change: 1 addition & 0 deletions lib/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
collect (PROJECT_LIB_SOURCES utilities.c)
35 changes: 35 additions & 0 deletions lib/utils/utilities.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2024, STMicroelectronics
*
*/

#include <internal/utilities.h>
#include <metal/io.h>
#include <metal/utilities.h>

size_t safe_strcpy(char *dst, size_t d_size, const char *src, size_t s_size)
{
size_t size = metal_min(s_size, d_size);
size_t nleft = size + 1;
char *d = dst;

if (!d_size)
return 0;

/* Copy as many bytes as will fit. */
while (--nleft != 0) {
*dst = *src++;
if (*dst++ == '\0')
break;
}

/* Fill last characters with '\0' */
if (size < d_size)
memset(dst, '\0', d_size - size + nleft);
else
d[d_size - 1] = '\0';

return size - nleft;
}

0 comments on commit 9aa3ee5

Please sign in to comment.