1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 19:57:44 +00:00

LibC: Fix invalid 1-byte read I introduced in dirent.

When attempting to fix the dirent code I also changed
this to use strlcpy instead of the custom string copy
loop that was there before. Looking over strlcpy it
looked like it should work when using a non null terminated
string, I obviously misinterpreted the implementation
as it will read till it finds a null terminator.

Manually null terminate the string to address this.

Gunnar found this after he fixed UserspaceEmulator.
I reproduced it locally using his branch, and also
found the memory leak I had in the unit test for the
scandir that I added, so lets fix that as well.

Reported-by: Gunnar Beutner <gbeutner@serenityos.org>
This commit is contained in:
Brian Gianforcaro 2021-05-03 00:15:11 -07:00 committed by Andreas Kling
parent 3a5f9b2f7e
commit 0726d39cb1
2 changed files with 7 additions and 3 deletions

View file

@ -72,8 +72,13 @@ static void create_struct_dirent(sys_dirent* sys_ent, struct dirent* str_ent)
str_ent->d_off = 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);
VERIFY(sizeof(str_ent->d_name) > sys_ent->namelen);
// Note: We can't use any normal string function as sys_ent->name is
// not null terminated. All string copy functions will attempt to read
// the non-existent null terminator past the end of the source string.
memcpy(str_ent->d_name, sys_ent->name, sys_ent->namelen);
str_ent->d_name[sys_ent->namelen] = '\0';
}
static int allocate_dirp_buffer(DIR* dirp)

View file

@ -19,7 +19,6 @@ TEST_CASE(scandir_basic_scenario)
for (auto i = 0; i < entries; i++) {
if (strcmp(namelist[i]->d_name, "passwd") == 0) {
found_passwd = true;
break;
}
free(namelist[i]);
}