[llvm-branch-commits] [clang] [release/23.x][clang][analyzer] Fix false positive in StdLibraryFunctionsChecker for mmap with MAP_ANON (PR #220333)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 1 11:50:38 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Daniel M. Zimmerman (dmzimmerman)
<details>
<summary>Changes</summary>
Cherry-pick of #<!-- -->219568 (commit af6ae639c296e3ab141b0ee755eb669945411810) to `release/23.x`. This fixes a false positive in the `unix.StdCLibraryFunctions` checker where `mmap` calls using `MAP_ANON` with `VM_MAKE_TAG` on Darwin are incorrectly flagged as having invalid `fd` values. It is a bug fix with no regression risk; it relaxes an `fd` range check from the static analyzer on Darwin and leaves all other platforms unchanged.
---
Full diff: https://github.com/llvm/llvm-project/pull/220333.diff
2 Files Affected:
- (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+21-7)
- (added) clang/test/Analysis/stdlibraryfunction-darwin.c (+31)
``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 4fe3e1f7623f6..d2c6f432f08a9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -41,6 +41,7 @@
//===----------------------------------------------------------------------===//
#include "ErrnoModeling.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -2954,15 +2955,28 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
// void *mmap(void *addr, size_t length, int prot, int flags, int fd,
// off_t offset);
// FIXME: Improve for errno modeling.
- addToFunctionSummaryMap(
- "mmap",
- Signature(
- ArgTypes{VoidPtrTy, SizeTyCanonTy, IntTy, IntTy, IntTy, Off_tTy},
- RetType{VoidPtrTy}),
+ auto MmapSignature = Signature(
+ ArgTypes{VoidPtrTy, SizeTyCanonTy, IntTy, IntTy, IntTy, Off_tTy},
+ RetType{VoidPtrTy});
+ auto MmapSummaryWithLengthConstraint =
Summary(NoEvalCall)
- .ArgConstraint(ArgumentCondition(1, WithinRange, Range(1, SizeMax)))
.ArgConstraint(
- ArgumentCondition(4, WithinRange, Range(-1, IntMax))));
+ ArgumentCondition(1, WithinRange, Range(1, SizeMax)));
+
+ if (ACtx.getTargetInfo().getTriple().isOSDarwin()) {
+ // On Darwin, MAP_ANON + VM_MAKE_TAG(tag) uses argument 4 (len) for
+ // the tag, which looks like a large negative signed integer.
+ // The valid range for fd is not expressible as a simple union of
+ // ranges so we only constrain the length parameter.
+ addToFunctionSummaryMap("mmap", MmapSignature,
+ MmapSummaryWithLengthConstraint);
+ } else {
+ // On other platforms, we also constrain the fd parameter (-1 <= fd).
+ addToFunctionSummaryMap(
+ "mmap", MmapSignature,
+ MmapSummaryWithLengthConstraint.ArgConstraint(
+ ArgumentCondition(4, WithinRange, Range(-1, IntMax))));
+ }
std::optional<QualType> Off64_tTy = lookupTy("off64_t");
// void *mmap64(void *addr, size_t length, int prot, int flags, int fd,
diff --git a/clang/test/Analysis/stdlibraryfunction-darwin.c b/clang/test/Analysis/stdlibraryfunction-darwin.c
new file mode 100644
index 0000000000000..50ed68e6325de
--- /dev/null
+++ b/clang/test/Analysis/stdlibraryfunction-darwin.c
@@ -0,0 +1,31 @@
+// DEFINE: %{analyze} = %clang_analyze_cc1 \
+// DEFINE: -analyzer-checker=core,unix.StdCLibraryFunctions \
+// DEFINE: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
+
+// RUN: %{analyze} -triple arm64-apple-darwin -verify=darwin %s
+// RUN: %{analyze} -triple x86_64-unknown-linux-gnu -verify=linux %s
+
+typedef unsigned long size_t;
+typedef long off_t;
+void *mmap(void *, size_t, int, int, int, off_t);
+
+#define MAP_PRIVATE 0x0002
+#define MAP_ANON 0x1000
+
+// VM_MAKE_TAG on Darwin encodes a Mach VM memory tag in the top 8 bits.
+// For tags >= 128 the result is a large negative signed integer.
+#define VM_MAKE_TAG(tag) ((int)((unsigned)(tag) << 24))
+#define VM_MEMORY_APPLICATION_SPECIFIC_1 240
+
+void test_mmap_vm_make_tag(void) {
+ // darwin-no-warning: no bound restriction on fd parameter on Darwin
+ // linux-warning at +1 {{The 5th argument to 'mmap' is -268435456 but should be >= -1}}
+ void *p = mmap(0, 4096, 0, MAP_ANON | MAP_PRIVATE,
+ VM_MAKE_TAG(VM_MEMORY_APPLICATION_SPECIFIC_1), 0);
+}
+
+void test_mmap_size_constraint(void) {
+ void *p = mmap(0, 0, 0, MAP_ANON | MAP_PRIVATE, -1, 0);
+ // darwin-warning at -1 {{The 2nd argument to 'mmap' is 0 but should be > 0}}
+ // linux-warning at -2 {{The 2nd argument to 'mmap' is 0 but should be > 0}}
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/220333
More information about the llvm-branch-commits
mailing list