From d4d988532a07a49520f20d00bc431415e86cec50 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Sun, 2 May 2021 01:34:59 -0700 Subject: [PATCH] LibC: Fix bugs in the population of dirent members. While adding new functionality which used the d_reclen member to copy a dirent, I realized that the value being populated was incorrect. sys_ent::total_size() function calculates the size of the sys_ent structure, but dirent is larger than sys_ent. This causes the malloc to be too small and you end up missing the end of the copy, which can miss the null terminator resulting in corrupt dirent names. Since we don't actually use the variable length member nature of dirent on other platforms we can just use the full size of the struct ad the d_reclen value. Also replace the custom strcpy with the standard version. --- Userland/Libraries/LibC/dirent.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibC/dirent.cpp b/Userland/Libraries/LibC/dirent.cpp index 241c7a1113..41f86d91b5 100644 --- a/Userland/Libraries/LibC/dirent.cpp +++ b/Userland/Libraries/LibC/dirent.cpp @@ -68,11 +68,10 @@ static void create_struct_dirent(sys_dirent* sys_ent, struct dirent* str_ent) str_ent->d_ino = sys_ent->ino; str_ent->d_type = sys_ent->file_type; str_ent->d_off = 0; - str_ent->d_reclen = sys_ent->total_size(); - for (size_t i = 0; i < sys_ent->namelen; ++i) - str_ent->d_name[i] = sys_ent->name[i]; - // FIXME: I think this null termination behavior is not supposed to be here. - str_ent->d_name[sys_ent->namelen] = '\0'; + str_ent->d_reclen = sizeof(struct dirent); + + int size = min((sys_ent->namelen + 1) * sizeof(char), sizeof(str_ent->d_name)); + [[maybe_unused]] auto n = strlcpy(str_ent->d_name, sys_ent->name, size); } static int allocate_dirp_buffer(DIR* dirp)