[clang] [analyzer] [MallocChecker] Less aggressive analysis of functions (PR #116383)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 15 05:30:23 PST 2024
https://github.com/likeamahoney created https://github.com/llvm/llvm-project/pull/116383
It seems to me that the `unix.Malloc` checker is too aggressive when it comes to analyzing function arguments.
For example it warns on such code (there is no directly usage of freed memory - but just pointer copying):
```cpp
#include "stdlib.h"
static void test_empty(int* p) {
return;
}
void test() {
int *p = (int*)malloc(sizeof(int));
free(p);
test_empty(p); // use after free warning causing
}
```
it leads to fp like that:
```cpp
#include "stdlib.h"
static void test_realloc(int* p) {
p = (int*)malloc(sizeof(int));
free(p);
return;
}
void test() {
int *p = (int*)malloc(sizeof(int));
free(p);
test_realloc(p); // use after free warning causing
}
```
I believe that when a function is from standard library and not external (it has a definition in the compilation unit) then checker can continue to analyze the function body further until an actual freed memory use is encountered but not warn on the call arguments in the case where there is simply copying of a pointer, and not its dereferencing.
>From 92354e08433b3b683c59634d8f8e4d4d7dd3fd44 Mon Sep 17 00:00:00 2001
From: Yan Churkin <yan at ispras.ru>
Date: Fri, 15 Nov 2024 15:44:17 +0300
Subject: [PATCH] [analyzer] [MallocChecker] Less aggressive analysis of
functions with the body
---
.../StaticAnalyzer/Checkers/MallocChecker.cpp | 7 ++++
clang/test/Analysis/malloc-interprocedural.c | 38 ++++++++++++++++++-
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 4166cf14391e2d..80a24abc0d8fa7 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -3156,12 +3156,16 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
return;
}
+ bool hasDef = false;
+
// We will check for double free in the post visit.
if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
const FunctionDecl *FD = FC->getDecl();
if (!FD)
return;
+ hasDef = FD->getDefinition() != nullptr;
+
if (ChecksEnabled[CK_MallocChecker] && isFreeingCall(Call))
return;
}
@@ -3173,6 +3177,9 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
return;
}
+ if (ChecksEnabled[CK_MallocChecker] && !Call.isInSystemHeader() && hasDef)
+ return;
+
// Check arguments for being used after free.
for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
SVal ArgSVal = Call.getArgSVal(I);
diff --git a/clang/test/Analysis/malloc-interprocedural.c b/clang/test/Analysis/malloc-interprocedural.c
index 5e5232af7b46e8..b6979554a116d6 100644
--- a/clang/test/Analysis/malloc-interprocedural.c
+++ b/clang/test/Analysis/malloc-interprocedural.c
@@ -26,7 +26,7 @@ static void *my_malloc2(int elevel, size_t size) {
}
static void my_free1(void *p) {
- free(p);
+ free(p); // expected-warning {{Attempt to free released memory}}
}
static void test1(void) {
@@ -65,7 +65,7 @@ int test4(void) {
void test6(void) {
int *data = (int *)my_malloc2(1, 4);
my_free1((int*)data);
- my_free1((int*)data); // expected-warning{{Use of memory after it is freed}}
+ my_free1((int*)data);
}
// TODO: We should warn here.
@@ -98,3 +98,37 @@ int uafAndCallsFooWithEmptyReturn(void) {
fooWithEmptyReturn(12);
return *x; // expected-warning {{Use of memory after it is freed}}
}
+
+static void test_empty(int *p) { return; }
+
+void test7() {
+ int *p = malloc(sizeof(int));
+ free(p);
+
+ test_empty(p); // no-warning
+}
+
+static void test_realloc(int *p) {
+ p = (int *)malloc(12);
+ free(p);
+ return;
+}
+
+void test8() {
+ int *p = malloc(sizeof(int));
+ free(p);
+
+ test_realloc(p); // no-warning
+}
+
+static void test_interproc_ptr_use(int *p) {
+ *p = 1; // expected-warning {{Use of memory after it is freed}}
+ return;
+}
+
+void test9() {
+ int *p = malloc(sizeof(int));
+ free(p);
+
+ test_interproc_ptr_use(p);
+}
More information about the cfe-commits
mailing list