[clang] 2e30f8d - [analyzer] Fix StreamChecker crash in fread modeling (#108393)

via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 12 08:06:56 PDT 2024


Author: Balazs Benics
Date: 2024-09-12T17:06:52+02:00
New Revision: 2e30f8d114e1406b35dc63868a92f4279330251b

URL: https://github.com/llvm/llvm-project/commit/2e30f8d114e1406b35dc63868a92f4279330251b
DIFF: https://github.com/llvm/llvm-project/commit/2e30f8d114e1406b35dc63868a92f4279330251b.diff

LOG: [analyzer] Fix StreamChecker crash in fread modeling (#108393)

In #93408
https://github.com/llvm/llvm-project/commit/69bc159142c6e4ed168e32a6168392d396f891de
I refined how invalidation is done for `fread`. It can crash, if the
"size" or "count" parameters of "fread" is a perfectly constrained
negative value. In such cases, when it will try to allocate a
SmallVector with a negative size, which will cause a crash.

To mitigate this issue, let's just guard against negative values.

CPP-3247

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
    clang/test/Analysis/fread.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 22061373c4b393..8bb7880a3cc283 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -1129,7 +1129,7 @@ tryToInvalidateFReadBufferByElements(ProgramStateRef State, CheckerContext &C,
   if (!ElemTy.isNull() && CountVal && Size && StartIndexVal) {
     int64_t NumBytesRead = Size.value() * CountVal.value();
     int64_t ElemSizeInChars = Ctx.getTypeSizeInChars(ElemTy).getQuantity();
-    if (ElemSizeInChars == 0)
+    if (ElemSizeInChars == 0 || NumBytesRead < 0)
       return nullptr;
 
     bool IncompleteLastElement = (NumBytesRead % ElemSizeInChars) != 0;

diff  --git a/clang/test/Analysis/fread.c b/clang/test/Analysis/fread.c
index 3f286421fd7a13..5dc6c0c744093a 100644
--- a/clang/test/Analysis/fread.c
+++ b/clang/test/Analysis/fread.c
@@ -443,3 +443,33 @@ void test_unaligned_start_read(void) {
     fclose(fp);
   }
 }
+
+void no_crash_if_count_is_negative(long l, long r, unsigned char *buffer) {
+  FILE *fp = fopen("path", "r");
+  if (fp) {
+    if (l * r == -1) {
+      fread(buffer, 1, l * r, fp); // no-crash
+    }
+    fclose(fp);
+  }
+}
+
+void no_crash_if_size_is_negative(long l, long r, unsigned char *buffer) {
+  FILE *fp = fopen("path", "r");
+  if (fp) {
+    if (l * r == -1) {
+      fread(buffer, l * r, 1, fp); // no-crash
+    }
+    fclose(fp);
+  }
+}
+
+void no_crash_if_size_and_count_are_negative(long l, long r, unsigned char *buffer) {
+  FILE *fp = fopen("path", "r");
+  if (fp) {
+    if (l * r == -1) {
+      fread(buffer, l * r, l * r, fp); // no-crash
+    }
+    fclose(fp);
+  }
+}


        


More information about the cfe-commits mailing list