Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix potential double free issue in FileInfoUtils_FillFileInfoWithNewestFilesInDir #628

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

Nox-MSFT
Copy link
Contributor

Fix an issue in the FileInfoUtils_FillFileInfoWithNewestFilesInDir() function where, if an error occurs after the FileInfo structure has been partially populated, the cleanup code incorrectly handles the fileName fields. Specifically, the cleanup code frees the fileName fields but does not properly reset these fields in the input array.

…function where, if an error occurs after the FileInfo structure has been partially populated, the cleanup code incorrectly handles the fileNames fields. Specifically, the cleanup code frees the fileNames fields but does not properly reset these fields in the input array.
@Nox-MSFT Nox-MSFT requested a review from a team May 29, 2024 20:37
@Nox-MSFT Nox-MSFT changed the title SECURITY FIX : Fix potential Remote Code Execution vulnerability in FileInfoUtils_FillFileInfoWithNewestFilesInDir Fix potential double free issue in FileInfoUtils_FillFileInfoWithNewestFilesInDir May 29, 2024
@@ -168,13 +168,11 @@ bool FileInfoUtils_FillFileInfoWithNewestFilesInDir(FileInfo* logFiles, size_t l

if (!succeeded)
{
// Free all the file names, if allocated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be better to use a temporary FileInfo array and not write out to logFiles side-effect until we know that all of it succeeded in the temporary array. That way, at the end, it can unconditionally always free the temporary array.

@@ -168,13 +168,11 @@ bool FileInfoUtils_FillFileInfoWithNewestFilesInDir(FileInfo* logFiles, size_t l

if (!succeeded)
{
// Free all the file names, if allocated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L146: should we be doing a stat() before checking type? I imagine that stat touches the file, while the S_ just are checking attribute bits.

@@ -168,13 +168,11 @@ bool FileInfoUtils_FillFileInfoWithNewestFilesInDir(FileInfo* logFiles, size_t l

if (!succeeded)
{
// Free all the file names, if allocated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit/future: FileInfoUtils_InsertFileInfoIntoArray sorts each time it's called. Probably better to add to current position in array and then sort at end.

@@ -168,13 +168,11 @@ bool FileInfoUtils_FillFileInfoWithNewestFilesInDir(FileInfo* logFiles, size_t l

if (!succeeded)
{
// Free all the file names, if allocated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L158: there's MAX_FILES_TO_SCAN and there's logFileSize. What happens MAX_FILES_TO_SCAN is greater (or much greater!) than logFileSize?


memset(&logFileEntry, 0, sizeof(FileInfo));
free(logFiles[i].fileName);
memset(&logFiles[i], 0, sizeof(FileInfo));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to memset on each iteration. After this loop, just call memset like done on L107.

@@ -168,13 +168,11 @@ bool FileInfoUtils_FillFileInfoWithNewestFilesInDir(FileInfo* logFiles, size_t l

if (!succeeded)
{
// Free all the file names, if allocated.
for (int i = 0; i < logFileSize; ++i)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: technically speaking, a caller shouldn't do anything with out parameters on failure.

int *p
if (!foo(&p)) {
  // shouldn't reference p!!!
}

So L219's "done" really shouldn't do anything if the call on L219 failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants