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

Undefined behavior and heap-buffer-overflow in StringHelpers::GroupStrings(...) #20218

Open
Arpan3323 opened this issue Feb 2, 2025 · 3 comments

Comments

@Arpan3323
Copy link

Describe the bug

Hi, fuzz testing the function below has resulted in two distinct errors:

  1. runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
  2. heap-buffer-overflow
    StringHelpers::GroupStrings(vector<string> stringList,
    vector<vector<string> > &stringGroups,
    vector<string> &groupNames,
    int numLeadingVals,
    string nonRelevantChars)

Error 1 occurs at the line linked below due to negating INT_MIN:

if (-numLeadingVals > len)

Error 2 occurs at the line linked below because of attempting to access the string pointed to by stringPtrs[i] using j:

thisVal += stringPtrs[i][j];

Fuzz test source

#include <fuzzer/FuzzedDataProvider.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
    FuzzedDataProvider provider(data, size);

    int numStrings = provider.ConsumeIntegralInRange<int>(1, 100);
    std::vector<std::string> stringList;
    for (int i = 0; i < numStrings; ++i)
    {
        stringList.push_back(provider.ConsumeRandomLengthString(100));
    }

    std::vector<std::vector<std::string>> stringGroups;
    std::vector<std::string> groupNames;
    int numLeadingVals = provider.ConsumeIntegral<int>();
    std::string nonRelevantChars = provider.ConsumeRandomLengthString(10);

    GroupStrings(stringList, stringGroups, groupNames, numLeadingVals, nonRelevantChars);

    return 0;
}

Potential fix

For error 1: As the error suggests, updating the function StringHelpers::GroupStrings to use unsigned int numLeadingVals instead of int numLeadingVals fixes the bug.

For error 2: Wrapping thisVal += stringPtrs[i][j]; in if (j < sizeof(stringPtrs[i])) fixes the bug.

Adding these two fixes makes the function withstand random inputs supplied by the fuzz test while retaining the original functionality. Please let me know if you have any questions or if you would like to see the crash reports generated by the fuzz test :)

@Arpan3323
Copy link
Author

@JustinPrivitera sorry for nudging you again but whenever you could get a chance, can you please let me know whether the 2 listed bugs are indeed considered as bugs? Please take your time.

@JustinPrivitera
Copy link
Member

Thanks for this report. These look like bugs. However, I don't think StringHelpers::GroupStrings() is used anywhere in the VisIt code base. It might make more sense to just remove the function entirely. Additionally, while it is best to be robust to strange values passed as numLeadingVals, I think it is quite unlikely a developer would pass -2147483648 as the number of leading characters. I appreciate you looking into these kinds of issues; it is very helpful. But we are a small team and can't tackle everything we'd like to tackle; we have to pick our battles. We will discuss and categorize this ticket at a later date as we continue to progress through our unreviewed tickets.

@Arpan3323
Copy link
Author

Thank you for your prompt and thorough investigation. I appreciate the VisIt development team's efforts in maintaining and continuously improving the tool.

I also couldn't confirm whether this function is used anywhere in the code base but since it existed, I thought I should fuzz it anyways. I agree, it might be a good idea to just remove the function entirely.

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

No branches or pull requests

2 participants