diff options
author | Balazs Benics <benicsbalazs@gmail.com> | 2023-09-11 14:19:33 +0200 |
---|---|---|
committer | Balazs Benics <benicsbalazs@gmail.com> | 2023-09-11 14:19:33 +0200 |
commit | c3a87ddad62a6cc01acaccc76592bc6730c8ac3c (patch) | |
tree | a57f943bf623b3692aa2eb353ff6681760dbfd3e /clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp | |
parent | 4b9259b9470480cbe140e49858c08fd62f67d7c6 (diff) | |
download | llvm-c3a87ddad62a6cc01acaccc76592bc6730c8ac3c.zip llvm-c3a87ddad62a6cc01acaccc76592bc6730c8ac3c.tar.gz llvm-c3a87ddad62a6cc01acaccc76592bc6730c8ac3c.tar.bz2 |
[analyzer] CStringChecker should check the first byte of the destination of strcpy, strncpy
By not checking if the first byte of the destination of strcpy and
strncpy is writable, we missed some reports in the Juliet benchmark.
(Juliet CWE-124 Buffer Underwrite: strcpy, strncpy)
https://discourse.llvm.org/t/patches-inspired-by-the-juliet-benchmark/73106
Differential Revision: https://reviews.llvm.org/D159108
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 7d3aaac..66ed78e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -2009,6 +2009,11 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, SVal maxLastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal, *maxLastNL, ptrTy); + // Check if the first byte of the destination is writable. + state = CheckLocation(C, state, Dst, DstVal, AccessKind::write); + if (!state) + return; + // Check if the last byte of the destination is writable. state = CheckLocation(C, state, Dst, maxLastElement, AccessKind::write); if (!state) return; @@ -2021,6 +2026,11 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, // ...and we haven't checked the bound, we'll check the actual copy. if (!boundWarning) { + // Check if the first byte of the destination is writable. + state = CheckLocation(C, state, Dst, DstVal, AccessKind::write); + if (!state) + return; + // Check if the last byte of the destination is writable. state = CheckLocation(C, state, Dst, lastElement, AccessKind::write); if (!state) return; |