Commit Graph

2171 Commits

Author SHA1 Message Date
Vince Bridgers 5fdc4dd777 [analyzer] refactor makeIntValWithPtrWidth, remove getZeroWithPtrWidth (NFC)
This is a NFC refactoring to change makeIntValWithPtrWidth
and remove getZeroWithPtrWidth to use types when forming values to match
pointer widths. Some targets may have different pointer widths depending
upon address space, so this needs to be comprehended.

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D120134
2022-03-23 08:26:37 -05:00
Vince Bridgers 985888411d [analyzer] Refactor makeNull to makeNullWithWidth (NFC)
Usages of makeNull need to be deprecated in favor of makeNullWithWidth
for architectures where the pointer size should not be assumed. This can
occur when pointer sizes can be of different sizes, depending on address
space for example. See https://reviews.llvm.org/D118050 as an example.

This was uncovered initially in a downstream compiler project, and
tested through those systems tests.

steakhal performed systems testing across a large set of open source
projects.

Co-authored-by: steakhal
Resolves: https://github.com/llvm/llvm-project/issues/53664

Reviewed By: NoQ, steakhal

Differential Revision: https://reviews.llvm.org/D119601
2022-03-22 07:35:13 -05:00
phyBrackets 90a6e35478 [analyzer][NFC] Merge similar conditional paths
Reviewed By: aaron.ballman, steakhal

Differential Revision: https://reviews.llvm.org/D121045
2022-03-07 22:05:27 +05:30
Endre Fülöp 4fd6c6e65a [analyzer] Add more propagations to Taint analysis
Add more functions as taint propators to GenericTaintChecker.

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D120369
2022-03-07 13:18:54 +01:00
Shivam 56eaf869be [analyzer] Done some changes to detect Uninitialized read by the char array manipulation functions
Few weeks back I was experimenting with reading the uninitialized values from src , which is actually a bug but the CSA seems to give up at that point . I was curious about that and I pinged @steakhal on the discord and according to him this seems to be a genuine issue and needs to be fix. So I goes with fixing this bug and thanks to @steakhal who help me creating this patch. This feature seems to break some tests but this was the genuine problem and the broken tests also needs to fix in certain manner. I add a test but yeah we need more tests,I'll try to add more tests.Thanks

Reviewed By: steakhal, NoQ

Differential Revision: https://reviews.llvm.org/D120489
2022-03-04 00:21:06 +05:30
Shivam bd1917c88a [analyzer] Done some changes to detect Uninitialized read by the char array manipulation functions
Few weeks back I was experimenting with reading the uninitialized values from src , which is actually a bug but the CSA seems to give up at that point . I was curious about that and I pinged @steakhal on the discord and according to him this seems to be a genuine issue and needs to be fix. So I goes with fixing this bug and thanks to @steakhal who help me creating this patch. This feature seems to break some tests but this was the genuine problem and the broken tests also needs to fix in certain manner. I add a test but yeah we need more tests,I'll try to add more tests.Thanks

Reviewed By: steakhal, NoQ

Differential Revision: https://reviews.llvm.org/D120489
2022-03-03 23:21:26 +05:30
Kristóf Umann d832078904 [analyzer] Improve NoOwnershipChangeVisitor's understanding of deallocators
The problem with leak bug reports is that the most interesting event in the code
is likely the one that did not happen -- lack of ownership change and lack of
deallocation, which is often present within the same function that the analyzer
inlined anyway, but not on the path of execution on which the bug occured. We
struggle to understand that a function was responsible for freeing the memory,
but failed.

D105819 added a new visitor to improve memory leak bug reports. In addition to
inspecting the ExplodedNodes of the bug pat, the visitor tries to guess whether
the function was supposed to free memory, but failed to. Initially (in D108753),
this was done by checking whether a CXXDeleteExpr is present in the function. If
so, we assume that the function was at least party responsible, and prevent the
analyzer from pruning bug report notes in it. This patch improves this heuristic
by recognizing all deallocator functions that MallocChecker itself recognizes,
by reusing MallocChecker::isFreeingCall.

Differential Revision: https://reviews.llvm.org/D118880
2022-03-03 11:27:56 +01:00
Balázs Kéri d8a2afb244 [clang][analyzer] Add modeling of 'errno'.
Add a checker to maintain the system-defined value 'errno'.
The value is supposed to be set in the future by existing or
new checkers that evaluate errno-modifying function calls.

Reviewed By: NoQ, steakhal

Differential Revision: https://reviews.llvm.org/D120310
2022-03-01 08:20:33 +01:00
Dawid Jurczak b3e2dac27c [NFC] Don't pass temporary LangOptions to Lexer
Since https://reviews.llvm.org/D120334 we shouldn't pass temporary LangOptions to Lexer.
This change fixes stack-use-after-scope UB in LocalizationChecker found by sanitizer-x86_64-linux-fast buildbot
and resolve similar issue in HeaderIncludes.
2022-02-28 20:43:28 +01:00
Endre Fülöp 34a7387986 [analyzer] Add more sources to Taint analysis
Add more functions as taint sources to GenericTaintChecker.

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D120236
2022-02-28 11:33:02 +01:00
Aaron Ballman f9e8e92cf5 Revert "[clang][analyzer] Add modeling of 'errno'."
This reverts commit 29b512ba32.

This broke several build bots:

https://lab.llvm.org/buildbot/#/builders/86/builds/30183
https://lab.llvm.org/buildbot/#/builders/216/builds/488
2022-02-25 07:21:01 -05:00
Balázs Kéri 29b512ba32 [clang][analyzer] Add modeling of 'errno'.
Add a checker to maintain the system-defined value 'errno'.
The value is supposed to be set in the future by existing or
new checkers that evaluate errno-modifying function calls.

Reviewed By: NoQ, steakhal

Differential Revision: https://reviews.llvm.org/D120310
2022-02-25 12:42:55 +01:00
Fangrui Song ecff9b65b5 [analyzer] Just use default capture after 7fd60ee6e0 2022-02-24 10:06:11 -08:00
Fangrui Song 7fd60ee6e0 [analyzer] Fix -Wunused-lambda-capture in -DLLVM_ENABLE_ASSERTIONS=off builds 2022-02-24 00:13:13 -08:00
Balazs Benics 7036413dc2 Revert "Revert "[analyzer] Fix taint rule of fgets and setproctitle_init""
This reverts commit 2acead35c1.

Let's try `REQUIRES: asserts`.
2022-02-23 12:55:31 +01:00
Balazs Benics a848a5cf2f Revert "Revert "[analyzer] Fix taint propagation by remembering to the location context""
This reverts commit d16c5f4192.

Let's try `REQUIRES: asserts`.
2022-02-23 12:53:07 +01:00
Balazs Benics fa0a80e017 Revert "Revert "[analyzer] Add failing test case demonstrating buggy taint propagation""
This reverts commit b8ae323cca.

Let's try `REQUIRES: asserts`.
2022-02-23 10:48:06 +01:00
Artem Dergachev e0e174845b [analyzer] Fix a crash in NoStateChangeVisitor with body-farmed stack frames.
LocationContext::getDecl() isn't useful for obtaining the "farmed" body because
the (synthetic) body statement isn't actually attached to the (natural-grown)
declaration in the AST.

Differential Revision: https://reviews.llvm.org/D119509
2022-02-17 10:13:34 -08:00
Balazs Benics b8ae323cca Revert "[analyzer] Add failing test case demonstrating buggy taint propagation"
This reverts commit 744745ae19.

I'm reverting this since this patch caused a build breakage.

https://lab.llvm.org/buildbot/#/builders/91/builds/3818
2022-02-14 18:45:46 +01:00
Balazs Benics d16c5f4192 Revert "[analyzer] Fix taint propagation by remembering to the location context"
This reverts commit b099e1e562.

I'm reverting this since the head of the patch stack caused a build
breakage.

https://lab.llvm.org/buildbot/#/builders/91/builds/3818
2022-02-14 18:45:46 +01:00
Balazs Benics 2acead35c1 Revert "[analyzer] Fix taint rule of fgets and setproctitle_init"
This reverts commit bf5963bf19.

I'm reverting this since the head of the patch stack caused a build
breakage.

https://lab.llvm.org/buildbot/#/builders/91/builds/3818
2022-02-14 18:45:46 +01:00
Balazs Benics bf5963bf19 [analyzer] Fix taint rule of fgets and setproctitle_init
There was a typo in the rule.
`{{0}, ReturnValueIndex}` meant that the discrete index is `0` and the
variadic index is `-1`.
What we wanted instead is that both `0` and `-1` are in the discrete index
list.

Instead of this, we wanted to express that both `0` and the
`ReturnValueIndex` is in the discrete arg list.

The manual inspection revealed that `setproctitle_init` also suffered a
probably incomplete propagation rule.

Reviewed By: Szelethus, gamesh411

Differential Revision: https://reviews.llvm.org/D119129
2022-02-14 16:55:55 +01:00
Balazs Benics b099e1e562 [analyzer] Fix taint propagation by remembering to the location context
Fixes the issue D118987 by mapping the propagation to the callsite's
LocationContext.
This way we can keep track of the in-flight propagations.

Note that empty propagation sets won't be inserted.

Reviewed By: NoQ, Szelethus

Differential Revision: https://reviews.llvm.org/D119128
2022-02-14 16:55:55 +01:00
Balazs Benics 744745ae19 [analyzer] Add failing test case demonstrating buggy taint propagation
Recently we uncovered a serious bug in the `GenericTaintChecker`.
It was already flawed before D116025, but that was the patch that turned
this silent bug into a crash.

It happens if the `GenericTaintChecker` has a rule for a function, which
also has a definition.

  char *fgets(char *s, int n, FILE *fp) {
    nested_call();   // no parameters!
    return (char *)0;
  }

  // Within some function:
  fgets(..., tainted_fd);

When the engine inlines the definition and finds a function call within
that, the `PostCall` event for the call will get triggered sooner than the
`PostCall` for the original function.
This mismatch violates the assumption of the `GenericTaintChecker` which
wants to propagate taint information from the `PreCall` event to the
`PostCall` event, where it can actually bind taint to the return value
**of the same call**.

Let's get back to the example and go through step-by-step.
The `GenericTaintChecker` will see the `PreCall<fgets(..., tainted_fd)>`
event, so it would 'remember' that it needs to taint the return value
and the buffer, from the `PostCall` handler, where it has access to the
return value symbol.
However, the engine will inline fgets and the `nested_call()` gets
evaluated subsequently, which produces an unimportant
`PreCall<nested_call()>`, then a `PostCall<nested_call()>` event, which is
observed by the `GenericTaintChecker`, which will unconditionally mark
tainted the 'remembered' arg indexes, trying to access a non-existing
argument, resulting in a crash.
If it doesn't crash, it will behave completely unintuitively, by marking
completely unrelated memory regions tainted, which is even worse.

The resulting assertion is something like this:
  Expr.h: const Expr *CallExpr::getArg(unsigned int) const: Assertion
          `Arg < getNumArgs() && "Arg access out of range!"' failed.

The gist of the backtrace:
  CallExpr::getArg(unsigned int) const
  SimpleFunctionCall::getArgExpr(unsigned int)
  CallEvent::getArgSVal(unsigned int) const
  GenericTaintChecker::checkPostCall(const CallEvent &, CheckerContext&) const

Prior to D116025, there was a check for the argument count before it
applied taint, however, it still suffered from the same underlying
issue/bug regarding propagation.

This path does not intend to fix the bug, rather start a discussion on
how to fix this.

---

Let me elaborate on how I see this problem.

This pre-call, post-call juggling is just a workaround.
The engine should by itself propagate taint where necessary right where
it invalidates regions.
For the tracked values, which potentially escape, we need to erase the
information we know about them; and this is exactly what is done by
invalidation.
However, in the case of taint, we basically want to approximate from the
opposite side of the spectrum.
We want to preserve taint in most cases, rather than cleansing them.

Now, we basically sanitize all escaping tainted regions implicitly,
since invalidation binds a fresh conjured symbol for the given region,
and that has not been associated with taint.

IMO this is a bad default behavior, we should be more aggressive about
preserving taint if not further spreading taint to the reachable
regions.

We have a couple of options for dealing with it (let's call it //tainting
policy//):
  1) Taint only the parameters which were tainted prior to the call.
  2) Taint the return value of the call, since it likely depends on the
     tainted input - if any arguments were tainted.
  3) Taint all escaped regions - (maybe transitively using the cluster
     algorithm) - if any arguments were tainted.
  4) Not taint anything - this is what we do right now :D

The `ExprEngine` should not deal with taint on its own. It should be done
by a checker, such as the `GenericTaintChecker`.
However, the `Pre`-`PostCall` checker callbacks are not designed for this.
`RegionChanges` would be a much better fit for modeling taint propagation.
What we would need in the `RegionChanges` callback is the `State` prior
invalidation, the `State` after the invalidation, and a `CheckerContext` in
which the checker can create transitions, where it would place `NoteTags`
for the modeled taint propagations and report errors if a taint sink
rule gets violated.
In this callback, we could query from the prior State, if the given
value was tainted; then act and taint if necessary according to the
checker's tainting policy.

By using RegionChanges for this, we would 'fix' the mentioned
propagation bug 'by-design'.

Reviewed By: Szelethus

Differential Revision: https://reviews.llvm.org/D118987
2022-02-14 16:55:55 +01:00
phyBrackets 6745b6a0f1 [analyzer][NFCi] Use the correct BugType in CStringChecker.
There is different bug types for different types of bugs  but the **emitAdditionOverflowbug** seems to use bugtype **BT_NotCSting** but actually it have to use **BT_AdditionOverflow** .

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D119462
2022-02-14 20:54:59 +05:30
Rashmi Mudduluru faabdfcf7f [analyzer] Add support for __attribute__((returns_nonnull)).
Differential Revision: https://reviews.llvm.org/D118657
2022-02-02 11:46:52 -08:00
Tres Popp 262cc74e0b Fix pair construction with an implicit constructor inside. 2022-01-18 18:01:52 +01:00
Endre Fülöp 17f74240e6 [analyzer][NFC] Refactor GenericTaintChecker to use CallDescriptionMap
GenericTaintChecker now uses CallDescriptionMap to describe the possible
operation in code which trigger the introduction (sources), the removal
(filters), the passing along (propagations) and detection (sinks) of
tainted values.

Reviewed By: steakhal, NoQ

Differential Revision: https://reviews.llvm.org/D116025
2022-01-18 16:04:04 +01:00
Kazu Hirata 17d4bd3d78 [clang] Fix bugprone argument comments (NFC)
Identified with bugprone-argument-comment.
2022-01-09 00:19:49 -08:00
Kazu Hirata 40446663c7 [clang] Use true/false instead of 1/0 (NFC)
Identified with modernize-use-bool-literals.
2022-01-09 00:19:47 -08:00
Kazu Hirata d1b127b5b7 [clang] Remove unused forward declarations (NFC) 2022-01-08 11:56:40 -08:00
Qiu Chaofan c2cc70e4f5 [NFC] Fix endif comments to match with include guard 2022-01-07 15:52:59 +08:00
Kazu Hirata 6c335b1a45 [clang] Remove unused "using" (NFC)
Identified by misc-unused-using-decls.
2021-12-27 20:48:21 -08:00
Kazu Hirata 0542d15211 Remove redundant string initialization (NFC)
Identified with readability-redundant-string-init.
2021-12-26 09:39:26 -08:00
Kazu Hirata 34558b039b [StaticAnalyzer] Remove redundant declaration isStdSmartPtr (NFC)
An identical declaration is present just a couple of lines above the
line being removed in this patch.

Identified with readability-redundant-declaration.
2021-12-25 00:35:41 -08:00
Sami Tolvanen ec2e26eaf6 [Clang] Add __builtin_function_start
Control-Flow Integrity (CFI) replaces references to address-taken
functions with pointers to the CFI jump table. This is a problem
for low-level code, such as operating system kernels, which may
need the address of an actual function body without the jump table
indirection.

This change adds the __builtin_function_start() builtin, which
accepts an argument that can be constant-evaluated to a function,
and returns the address of the function body.

Link: https://github.com/ClangBuiltLinux/linux/issues/1353

Depends on D108478

Reviewed By: pcc, rjmccall

Differential Revision: https://reviews.llvm.org/D108479
2021-12-20 12:55:33 -08:00
Gabor Marton bd9e23943a [analyzer] Expand conversion check to check more expressions for overflow and underflow
This expands checking for more expressions. This will check underflow
and loss of precision when using call expressions like:

  void foo(unsigned);
  int i = -1;
  foo(i);

This also includes other expressions as well, so it can catch negative
indices to std::vector since it uses unsigned integers for [] and .at()
function.

Patch by: @pfultz2

Differential Revision: https://reviews.llvm.org/D46081
2021-12-15 11:41:34 +01:00
Logan Smith 715c72b4fb [NFC][analyzer] Return underlying strings directly instead of OS.str()
This avoids an unnecessary copy required by 'return OS.str()', allowing
instead for NRVO or implicit move. The .str() call (which flushes the
stream) is no longer required since 65b13610a5,
which made raw_string_ostream unbuffered by default.

Differential Revision: https://reviews.llvm.org/D115374
2021-12-09 16:05:46 -08:00
Zarko Todorovski d8e5a0c42b [clang][NFC] Inclusive terms: replace some uses of sanity in clang
Rewording of comments to avoid using `sanity test, sanity check`.

Reviewed By: aaron.ballman, Quuxplusone

Differential Revision: https://reviews.llvm.org/D114025
2021-11-19 14:58:35 -05:00
Balazs Benics e6ef134f3c [analyzer][NFC] Use enum for CallDescription flags
Yeah, let's prefer a slightly stronger type representing this.

Reviewed By: martong, xazax.hun

Differential Revision: https://reviews.llvm.org/D113595
2021-11-19 18:32:13 +01:00
Balazs Benics 9ad0a90baa [analyzer][NFC] Demonstrate the use of CallDescriptionSet
Reviewed By: martong, xazax.hun

Differential Revision: https://reviews.llvm.org/D113592
2021-11-19 18:32:13 +01:00
Balazs Benics f18da190b0 [analyzer][NFC] Switch to using CallDescription::matches() instead of isCalled()
This patch replaces each use of the previous API with the new one.
In variadic cases, it will use the ADL `matchesAny(Call, CDs...)`
variadic function.
Also simplifies some code involving such operations.

Reviewed By: martong, xazax.hun

Differential Revision: https://reviews.llvm.org/D113591
2021-11-19 18:32:13 +01:00
Balazs Benics 0b9d3a6e53 [analyzer][NFC] Separate CallDescription from CallEvent
`CallDescriptions` deserve its own translation unit.
This patch simply moves the corresponding parts.
Also includes the `CallDescription.h` where it's necessary.

Reviewed By: martong, xazax.hun, Szelethus

Differential Revision: https://reviews.llvm.org/D113587
2021-11-15 19:10:46 +01:00
Kazu Hirata d0ac215dd5 [clang] Use isa instead of dyn_cast (NFC) 2021-11-14 09:32:40 -08:00
Kazu Hirata 4db2e4cebe Use {DenseSet,SetVector,SmallPtrSet}::contains (NFC) 2021-10-30 19:00:19 -07:00
Zarko Todorovski 8659b241ae [clang][NFC] Inclusive terms: Replace uses of whitelist in clang/lib/StaticAnalyzer
Replace variable and functions names, as well as comments that contain whitelist with
more inclusive terms.

Reviewed By: aaron.ballman, martong

Differential Revision: https://reviews.llvm.org/D112642
2021-10-29 16:51:36 -04:00
Balazs Benics 49285f43e5 [analyzer] sprintf is a taint propagator not a source
Due to a typo, `sprintf()` was recognized as a taint source instead of a
taint propagator. It was because an empty taint source list - which is
the first parameter of the `TaintPropagationRule` - encoded the
unconditional taint sources.
This typo effectively turned the `sprintf()` into an unconditional taint
source.

This patch fixes that typo and demonstrated the correct behavior with
tests.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D112558
2021-10-28 11:03:02 +02:00
Balazs Benics c18407217e [analyzer] Fix StringChecker for Unknown params
It seems like protobuf crashed the `std::string` checker.
Somehow it acquired `UnknownVal` as the sole `std::string` constructor
parameter, causing a crash in the `castAs<Loc>()`.

This patch addresses this.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D112551
2021-10-26 18:15:00 +02:00
Balazs Benics e1fdec875f [analyzer] Add std::string checker
This patch adds a checker checking `std::string` operations.
At first, it only checks the `std::string` single `const char *`
constructor for nullness.
If It might be `null`, it will constrain it to non-null and place a note
tag there.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D111247
2021-10-25 11:15:40 +02:00
Kazu Hirata d8e4170b0a Ensure newlines at the end of files (NFC) 2021-10-23 08:45:29 -07:00