Compare commits

...

177 Commits

Author SHA1 Message Date
Nick Rolfe
71ef2931a5 Ruby: update crate versions 2022-01-13 11:43:31 +00:00
Stephan Brandauer
40ad88ba53 Merge pull request #7474 from kaeluka/db-reads-as-taint-sources
JS: DB reads as taint sources
2022-01-13 12:06:48 +01:00
Michael Nebel
8583a4ffea Merge pull request #7583 from michaelnebel/csharp/fix-broken-test
C#: Narrow string interpolation expressions to a specific single file in testcase.
2022-01-13 11:37:52 +01:00
Erik Krogh Kristensen
89bab6ae12 Merge pull request #7097 from erik-krogh/railsReDoS
JS/PY/RB: support a limited number of ranges for ReDoS analysis
2022-01-13 11:04:36 +01:00
Stephan Brandauer
93507a2d71 combine two implementations for database-accesses as remote flow sources 2022-01-13 10:53:58 +01:00
Michael Nebel
aacb03a74b C#: Narrow string interpolation expressions to a specific single file in testcase. 2022-01-13 10:25:33 +01:00
Stephan Brandauer
63aaf24063 base implementation of Sequelize model on models-as-data 2022-01-13 09:41:25 +01:00
Anders Schack-Mulligen
da69886777 Merge pull request #7580 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-13 09:26:00 +01:00
github-actions[bot]
625836a3be Add changed framework coverage reports 2022-01-13 00:11:30 +00:00
Henry Mercer
1c3c9216f5 Merge pull request #7576 from github/henrymercer/js-bump-atm-versions
JS: Bump ATM pack versions to 0.0.4
2022-01-12 16:53:10 +00:00
Stephan Brandauer
09a28c428c base implementation of Spanner model on models-as-data 2022-01-12 17:07:16 +01:00
Henry Mercer
9abc3411a4 JS: Bump ATM pack versions to 0.0.4 2022-01-12 15:19:13 +00:00
Robert Marsh
5031d6c4a3 Merge pull request #7566 from MathiasVP/smaller-join-in-reachesRefParameter
C++: Smaller join in `reachesRefParameter`
2022-01-12 10:04:35 -05:00
Henry Mercer
3ef69763a7 Merge pull request #7567 from github/henrymercer/atm-body-tokens-perf-opt
ATM: Optimize body tokens by pushing in size restriction
2022-01-12 12:45:27 +00:00
Tamás Vajk
9065a7f320 Merge pull request #7573 from tamasvajk/fix/java-field-decl-tostr
Java: Fix toString on field declarations with single field
2022-01-12 13:03:16 +01:00
Tony Torralba
8a80e02861 Merge pull request #7574 from pwntester/improve_strings_qll
Add models for AbstractStringBuilder.substring,subsequence,getChars
2022-01-12 12:01:28 +01:00
Tony Torralba
c2105e506b Added test cases 2022-01-12 11:06:58 +01:00
Alvaro Muñoz Sanchez
715d372572 Add models for AbstractStringBuilder.substring,subsequence,getChars 2022-01-12 10:54:27 +01:00
Anders Schack-Mulligen
c6a9b2b6ff Merge pull request #7572 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-12 09:39:14 +01:00
Tamas Vajk
b9e0310aa2 Java: Fix toString on field declarations with single field 2022-01-12 09:22:16 +01:00
Michael Nebel
f17c110f51 Merge pull request #7562 from michaelnebel/csharp/record-seal-tostring
C#: Record types are allowed to seal ToString (test only).
2022-01-12 08:08:32 +01:00
github-actions[bot]
c79e8ab440 Add changed framework coverage reports 2022-01-12 00:10:48 +00:00
Andrew Eisenberg
da4f1d86aa Merge pull request #7355 from github/aeisenberg/remove-upgrades
Move upgrades into standard library packs
2022-01-11 14:09:10 -08:00
Andrew Eisenberg
07228672df Merge branch 'main' into aeisenberg/remove-upgrades 2022-01-11 11:25:27 -08:00
Mathias Vorreiter Pedersen
c45127fdd6 Merge pull request #7541 from github/rdmarsh2/dataflow-ipa-params
C++: Use an IPA type rather than negative indexes for argument/parameter matching in data flow
2022-01-11 16:52:13 +00:00
Tony Torralba
7b0d9ea525 Merge pull request #7054 from atorralba/atorralba/promote-log-injection
Java: Promote Log Injection from experimental
2022-01-11 17:26:18 +01:00
Henry Mercer
3f70476c87 ATM: Optimize body tokens by pushing in size limit
Pushing the restriction to 256 tokens into the `bodyTokens` predicate
means we avoid this predicate blowing up due to very large functions.

This results in a runtime improvement from 1800s+ to 294s as measured
on a problematic repo on my machine (I didn't wait for the query to
finish running).
2022-01-11 16:16:54 +00:00
Tony Torralba
1030ff7063 Update java/ql/src/Security/CWE/CWE-117/LogInjection.ql 2022-01-11 16:25:32 +01:00
Tony Torralba
4aacba8594 Merge pull request #6468 from atorralba/atorralba/promote-cleartext-sharedprefs
Java: Promote Cleartext storage of sensitive information using SharedPreferences from experimental
2022-01-11 16:23:53 +01:00
Tony Torralba
394c4a9ee0 Remove unused code 2022-01-11 14:50:48 +01:00
Mathias Vorreiter Pedersen
b3a7090068 C++: Fix join in reachesRefParameter by joining with 'getEnd' instead
of 'getANode'.

Before:

Tuple counts for FlowVar::FlowVar::reachesRefParameter_dispred#ff/2@956ac39i after 229ms:
  24806   ~1%     {2} r1 = JOIN FlowVar::FlowVar_internal::parameterIsNonConstReference#f WITH Parameter::Parameter::getFunction_dispred#ff ON FIRST 1 OUTPUT Lhs.0 'p', Rhs.1
  56985   ~3%     {3} r2 = JOIN r1 WITH num#FlowVar::FlowVar_internal::TBlockVar#fff_12#join_rhs ON FIRST 1 OUTPUT Rhs.1 'this', Lhs.0 'p', Lhs.1
  2384489 ~4%     {4} r3 = JOIN r2 WITH FlowVar::FlowVar_internal::getAReachedBlockVarSBB#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.2, Lhs.1 'p', Lhs.0 'this'
  49457   ~0%     {2} r4 = JOIN r3 WITH SubBasicBlocks::SubBasicBlock::getANode_dispred#fb ON FIRST 2 OUTPUT Lhs.3 'this', Lhs.2 'p'
                  return r4

After:

Tuple counts for FlowVar::FlowVar::reachesRefParameter_dispred#ff/2@46f8bfn7 after 32ms:
  24806 ~1%     {2} r1 = JOIN FlowVar::FlowVar_internal::parameterIsNonConstReference#f WITH Parameter::Parameter::getFunction_dispred#ff ON FIRST 1 OUTPUT Lhs.0 'p', Rhs.1
  56985 ~1%     {3} r2 = JOIN r1 WITH num#FlowVar::FlowVar_internal::TBlockVar#fff_12#join_rhs ON FIRST 1 OUTPUT Lhs.1, Lhs.0 'p', Rhs.1 'this'
  56985 ~1%     {3} r3 = JOIN r2 WITH SubBasicBlocks::SubBasicBlock::getEnd_dispred#fb_10#join_rhs ON FIRST 1 OUTPUT Lhs.2 'this', Rhs.1, Lhs.1 'p'
  49457 ~0%     {2} r4 = JOIN r3 WITH FlowVar::FlowVar_internal::getAReachedBlockVarSBB#ff ON FIRST 2 OUTPUT Lhs.0 'this', Lhs.2 'p'
                return r4
2022-01-11 13:48:20 +00:00
Michael Nebel
77763d7ee5 Merge pull request #7559 from michaelnebel/csharp/const-interpolatedstring
C#: Constant string interpolation (test only).
2022-01-11 14:01:55 +01:00
Michael Nebel
56bc3db46a C#: Add test case for sealed ToString modifier on a record type. 2022-01-11 13:58:43 +01:00
Michael Nebel
ae5d3a1ccb C#: Add example of sealing ToString on a record type. 2022-01-11 13:57:29 +01:00
Tony Torralba
50caf7d8dc Move change note to new location and remove import
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2022-01-11 12:24:44 +01:00
Tony Torralba
b9e32208ee Move change note to new location 2022-01-11 12:23:16 +01:00
Michael Nebel
1d8f8f79bb C#: Add const interpolated string test case. 2022-01-11 12:02:07 +01:00
Michael Nebel
5b89f0e0b8 C#: Add example of const interpolated string. 2022-01-11 12:01:40 +01:00
Stephan Brandauer
132e0bf4b7 add database accesses as additional (heuristic) remote flow sources 2022-01-11 11:38:41 +01:00
Anders Schack-Mulligen
2a36744deb Merge pull request #7552 from smowton/smowton/fix/local-parameterized-classes
Note that parameterizations of local classes are themselves local
2022-01-11 09:36:15 +01:00
Alex Ford
b9ed8ed416 Merge pull request #7553 from github/revert-7498-dependabot/cargo/ruby/generator/clap-3.0
Ruby: Revert "Update clap requirement from 2.33 to 3.0 in /ruby/generator"
2022-01-10 19:36:40 +00:00
Alex Ford
17e5b9cffa Revert "Update clap requirement from 2.33 to 3.0 in /ruby/generator" 2022-01-10 18:21:04 +00:00
Chris Smowton
e352a4b994 Note that parameterizations of local classes are themselves local
Previously `LocalClass` itself would match `.isLocal()` whereas `LocalClass<Param>` would not. Rather than require each individual user to check for `.getSourceDeclaration().isLocal()`, let's note that the specializations themselves are local.
2022-01-10 18:19:31 +00:00
Tony Torralba
fbebf5e953 Move change note to new location 2022-01-10 17:27:02 +01:00
Tony Torralba
0e738622df Merge branch 'main' into atorralba/promote-log-injection 2022-01-10 17:24:25 +01:00
Tony Torralba
cc92ce2754 Fix QLDoc 2022-01-10 17:13:13 +01:00
Tony Torralba
e1e5e78464 Apply suggestions from code review
- Update CleartextStorage library to latest refactor
- Move change note to new location
2022-01-10 17:10:55 +01:00
Tony Torralba
d17e973b6b Apply suggestions from code review
Co-authored-by: Ethan Palm <56270045+ethanpalm@users.noreply.github.com>
2022-01-10 17:09:41 +01:00
Tony Torralba
ec8c234872 Fix predicate name 2022-01-10 17:09:41 +01:00
Tony Torralba
55dc783f28 Move from experimental and refactor 2022-01-10 17:09:37 +01:00
CodeQL CI
d912a98b02 Merge pull request #7171 from asgerf/js/mad
Approved by erik-krogh
2022-01-10 13:17:09 +00:00
Tom Hvitved
d2ebbe0819 Merge pull request #7469 from hvitved/csharp/promote-adhoc-consistency-checks
C#: Promote existing ad-hoc consistency checks to consistency queries
2022-01-10 11:10:25 +01:00
Michael Nebel
533fc7a912 Merge pull request #7532 from michaelnebel/csharp/file-scoped-namespace
C#: Make support for file scoped namespace declarations.
2022-01-10 09:02:18 +01:00
Mathias Vorreiter Pedersen
a5ccd6a23b Merge pull request #7521 from rdmarsh2/rdmarsh2/cpp/use-guards-in-overflow 2022-01-09 14:09:04 +00:00
Robert Marsh
673399719e C++: autoformat DataFlowPrivate 2022-01-07 15:23:24 -05:00
Felicity Chapman
3b0d55e2f9 Merge pull request #5893 from niroshan/patch-1
Update README.md
2022-01-07 19:33:41 +00:00
Robert Marsh
78b8d113bb C++: PR comments on DataFlow Position 2022-01-07 14:21:56 -05:00
Robert Marsh
4322a39807 C++: fix typo in Overflow.qll abs handling 2022-01-07 14:09:47 -05:00
Erik Krogh Kristensen
f7a63d5ea0 remove duplicated line 2022-01-07 18:38:02 +01:00
Erik Krogh Kristensen
c8d29a9cf1 sync files 2022-01-07 18:38:02 +01:00
Erik Krogh Kristensen
1a8b6d7414 recognize ranges without upper bounds 2022-01-07 18:38:01 +01:00
Erik Krogh Kristensen
acaf294bee support a limited number of regexp ranges 2022-01-07 18:36:30 +01:00
Robert Marsh
a126154dfb C++: use -1 for this in dataflow Position 2022-01-07 11:39:26 -05:00
Robert Marsh
1890a14026 C++: IPA for pointer arg instead of negative index
This takes advantage of the new ArgumentPosition and ParameterPosition
types in the shared DataFlow library interface to represent indirections
with an IPA type rather than the negative-index system in use previously
2022-01-07 11:39:26 -05:00
Robert Marsh
4f23cce63b C++: Accept more test output 2022-01-07 11:27:45 -05:00
Michael Nebel
23b8444348 C#: Cleanup C# source code file and add a test case for namespace delcarations. 2022-01-07 16:04:43 +01:00
Michael Nebel
b8f6d17bc1 C#: Add test for file scoped namespace. 2022-01-07 16:04:43 +01:00
Michael Nebel
a6d847b532 C#: Make support for FileScoped namespace declaration in the extrator. 2022-01-07 16:04:43 +01:00
Mathias Vorreiter Pedersen
4ee653378e Merge pull request #7517 from MathiasVP/avoid-self-joins-in-toctou-query
C++: Remove bad self joins in `cpp/toctou-race-condition`.
2022-01-07 13:08:30 +00:00
Michael Nebel
94c1a489e0 Merge pull request #7507 from michaelnebel/csharp-libdataflow-cleanup
C#: Refactor and cleanup LibraryTypeDataFlow
2022-01-07 13:16:08 +01:00
Michael Nebel
17219eff61 Merge pull request #7530 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-07 13:15:49 +01:00
Michael Nebel
929f6ca578 C#: Address review comments. 2022-01-07 10:26:33 +01:00
Michael Nebel
d3368dcc23 C#: Remove the LibraryTypeDataFlow file as the remaining code is dead. 2022-01-07 10:26:32 +01:00
Michael Nebel
9b47249f6a C#: Migrate the legacy clearContent flow summaries to the new framework. 2022-01-07 10:26:32 +01:00
Michael Nebel
fd317c2e7b C#: Move RecordConstructorFlow. 2022-01-07 10:26:32 +01:00
Michael Nebel
fb950848c7 C#: Remove unused case, when converting SummaryComponent stacks. 2022-01-07 10:26:32 +01:00
Michael Nebel
5a0e6ed8e6 C#: Remove unsued predicates in CallableFlowSource and subclasses. 2022-01-07 10:26:32 +01:00
Michael Nebel
19914aba89 C#: Remove CallableFlowSink. 2022-01-07 10:26:32 +01:00
Michael Nebel
ed4d09bc8b C#: Remove unneeded imports. 2022-01-07 10:26:32 +01:00
Michael Nebel
d042c4b3e4 C#: Remove unsused type,class and module AccessPath. 2022-01-07 10:26:32 +01:00
Michael Nebel
d5768bf4ed C#: Remove more empty predicates. 2022-01-07 10:26:31 +01:00
Michael Nebel
a6b79926b2 C#: Remove unused predicate toCallableFlowSink. 2022-01-07 10:26:31 +01:00
Michael Nebel
ecc9593f00 C#: Remove the unused predicate callable flow. 2022-01-07 10:26:31 +01:00
Michael Nebel
c52787c741 C#: Move the declaration of synthetic fields to where they are needed. 2022-01-07 10:26:31 +01:00
Michael Nebel
608aba7cff C#: Delete empty predicate requiresAccessPath. 2022-01-07 10:26:31 +01:00
Felicity Chapman
ad82523b91 Apply suggestions from code review 2022-01-07 08:49:37 +00:00
Felicity Chapman
95c9f89b04 Merge branch 'main' into patch-1 2022-01-07 08:49:13 +00:00
github-actions[bot]
efb1cd4f3b Add changed framework coverage reports 2022-01-07 00:10:30 +00:00
Robert Marsh
c6da1f2be0 C++: re-add comment 2022-01-06 12:43:22 -05:00
Robert Marsh
355fc0ae63 C++: Use Guards library in Overflow.qll
Replaces the ad-hoc guard handling with the Guards library. Fixes an
observed false positive pattern, and (hopefully) means some pragmas are
no longer necessary for performance.
2022-01-06 12:15:37 -05:00
Robert Marsh
617bdbc5ba C++: test for guard-by-return in Overflow.qll 2022-01-06 12:15:37 -05:00
Robert Marsh
d5682f157a Merge pull request #7525 from MathiasVP/remove-rank-in-ssa-internals
C++: Remove `rank` aggregate in `SsaInternals`
2022-01-06 12:09:57 -05:00
Andrew Eisenberg
6d62227576 Merge pull request #7431 from aeisenberg/aeisenberg/solorigate-publish
Solorigate: Extract to separate qlpack
2022-01-06 08:53:32 -08:00
Mathias Vorreiter Pedersen
173cefd7e4 C++: Respond to PR reviews. 2022-01-06 15:39:40 +00:00
Michael Nebel
b3cb250ece Merge pull request #7516 from michaelnebel/csharp/improve-csv-validation
C#: Introduce Csv validation on kind.
2022-01-06 14:31:26 +01:00
Michael Nebel
9cafab1b4c Merge pull request #7465 from michaelnebel/csharp-stringvalues-csv
C#: Introduce flow summaries for StringValues.
2022-01-06 14:30:29 +01:00
Rasmus Wriedt Larsen
3e1dcc3d11 Merge pull request #7518 from tausbn/python-extend-unreachable-statement-test
Python: Extend unreachable statement test
2022-01-06 14:07:29 +01:00
Mathias Vorreiter Pedersen
671954025d C++: Fix qldoc. 2022-01-06 11:02:15 +00:00
Asger F
c9fcdb8261 Apply suggestions from code review
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2022-01-06 11:51:27 +01:00
Mathias Vorreiter Pedersen
2f42054f8f C++: Rename 'hasRankInBlock' to 'hasIndexInBlock' since it's not really a rank computation anymore. 2022-01-06 10:31:05 +00:00
Mathias Vorreiter Pedersen
fdb9fb588c C++: Remove the rank aggregate from 'SsaInternals.qll'. 2022-01-06 10:30:31 +00:00
Andrew Eisenberg
0a2f23f6f9 Update pack references in solorigate tests 2022-01-05 10:37:15 -08:00
Taus
ea538a1ee8 Merge pull request #7416 from github/not-that-kind-of-experimental
Remove experimental tag from non-ATM queries
2022-01-05 18:08:15 +01:00
Taus
5d4db3af15 Python: Extend unreachable statement test
Adds a test demostrating the false positive observed by andersfugmann.

Note that this does not change the `.expected` file, and so the tests
will fail. This is expected.
2022-01-05 16:45:38 +00:00
Michael Nebel
53000cf9f0 C#: Update the XSS expected file. 2022-01-05 16:44:03 +01:00
Michael Nebel
7e6d88d959 C#: Only use stubs for XSS test. 2022-01-05 16:44:03 +01:00
Michael Nebel
24543a2245 C#: Update the UrlRedirect expected file. 2022-01-05 16:44:03 +01:00
Michael Nebel
47ab2061d8 C#: Replace StringValues stub from stubs.cs with the stub in Microsoft.Extensions.Primitives. 2022-01-05 16:44:03 +01:00
Michael Nebel
b3f3c2de24 C#: Convert and cleanup flow summaries for Microsoft.Extensions.Primitives.StringValues. 2022-01-05 16:41:30 +01:00
Michael Nebel
48651a6113 C#: Update flow summaries for StringValues. 2022-01-05 16:41:30 +01:00
Michael Nebel
c36bf3cebc C#: Reduce the amount of trash flow summaries produced for StringValues. 2022-01-05 16:41:30 +01:00
Michael Nebel
9a355c1050 C#: Add stubs for Microsoft.Extensions.Primitives. 2022-01-05 16:41:30 +01:00
Michael Nebel
586fddb0ce Merge pull request #7509 from hvitved/csharp/stubs-from-source
C#: Treat QL test stubs as not from source
2022-01-05 16:40:19 +01:00
Mathias Vorreiter Pedersen
f5062c7d80 C++: Remove a bunch of bad self joins from 'cpp/toctou-race-condition'. 2022-01-05 15:28:53 +00:00
Alex Ford
f935df9865 Merge pull request #7313 from github/ruby/rails-cookie-config
Ruby: Add `rb/weak-cookie-configuration` query
2022-01-05 15:20:40 +00:00
Michael Nebel
83c05f72d9 C#: Update the expected output from MinimalStubsFromSource as the stubs are now considered library code and thus produced as a part of the minimal stub. 2022-01-05 15:35:42 +01:00
Alex Ford
da8c745bd8 Ruby: Restrict Rails Setting nodes to SetterMethodCalls 2022-01-05 14:11:07 +00:00
Asger Feldthaus
a7698b8727 JS: Fix double space 2022-01-05 14:35:02 +01:00
Asger Feldthaus
486beda2fa JS: Factor out common regexp in AccessPathToken 2022-01-05 14:35:02 +01:00
Asger Feldthaus
d33200ea83 JS: Add test for WithArity 2022-01-05 14:35:02 +01:00
Asger Feldthaus
21928bee6c JS: Rename padded -> inversePad 2022-01-05 14:35:01 +01:00
Asger Feldthaus
1989d51942 JS: Update documentation in Impl.qll 2022-01-05 14:35:01 +01:00
Asger Feldthaus
3ced5c9269 JS: Resolve first N tokens instead of constructing each prefix 2022-01-05 14:35:01 +01:00
Asger Feldthaus
772681d249 JS: Initial support for models as data 2022-01-05 14:34:52 +01:00
Tom Hvitved
433e373e41 C#: Remove restriction in CFG implementation to work with stubs 2022-01-05 14:12:17 +01:00
Michael Nebel
6fb112f8ec C#: Update tests to comply with Csv validation rules for kind. 2022-01-05 13:44:47 +01:00
Michael Nebel
45469a4fe6 C#: Fix error message. 2022-01-05 13:44:47 +01:00
Michael Nebel
c88355ea13 C#: Introduce Csv validation for kind. 2022-01-05 12:48:24 +01:00
Arthur Baars
e96fcf8568 Merge pull request #7498 from github/dependabot/cargo/ruby/generator/clap-3.0
Update clap requirement from 2.33 to 3.0 in /ruby/generator
2022-01-05 12:24:42 +01:00
Mathias Vorreiter Pedersen
a48d5dcf48 Merge pull request #7459 from MathiasVP/promote-arithmetic-uncontrolled
C++: Increase precision of `cpp/arithmetic-uncontrolled` to `high`
2022-01-05 11:24:09 +00:00
Mathias Vorreiter Pedersen
23b8b776ab C++: Add change-note. 2022-01-05 10:12:20 +00:00
Michael Nebel
9983c1cbfb C#: Remove generated comment checks in stub files as these are not present in handwritten stubs. 2022-01-05 10:37:37 +01:00
Mathias Vorreiter Pedersen
37c72cae3e Merge branch 'main' into promote-arithmetic-uncontrolled 2022-01-05 08:12:47 +00:00
Anders Schack-Mulligen
fdb3cd03ef Merge pull request #7513 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-05 08:54:46 +01:00
github-actions[bot]
0aa1152899 Add changed framework coverage reports 2022-01-05 00:10:19 +00:00
Erik Krogh Kristensen
c7da8df03c Merge pull request #7511 from erik-krogh/dedup-spaces
Python: remove duplicated spaces in qldoc
2022-01-04 21:39:15 +01:00
Erik Krogh Kristensen
fe1107ccac remove duplicated spaces in qldoc 2022-01-04 21:03:06 +01:00
Dave Bartolomeo
83ceb822aa Move upgrades into standard library packs
Move upgrade to new location

Remove incorrectly merged files

Fix upgrades section
2022-01-04 11:30:25 -08:00
Alex Ford
712972cb82 Ruby: formatting 2022-01-04 16:41:23 +00:00
Alex Ford
36ea360b25 Ruby: behaviour -> behavior 2022-01-04 15:43:38 +00:00
Mathias Vorreiter Pedersen
8f843209a8 Merge pull request #7493 from MrAnno/relax-ambiguously-signed-bit-field
C++: relax ambiguously-signed-bit-field by allowing GLib's gboolean
2022-01-04 16:18:46 +01:00
Mathias Vorreiter Pedersen
e31185fea4 C++: add change-note for cpp/ambiguously-signed-bit-field. 2022-01-04 14:31:19 +00:00
László Várady
6496bf8c1d C++: relax ambiguously-signed-bit-field by allowing GLib's gboolean
The gboolean type of GLib (a widely used C library) is a typedef to int.
It is meant to represent a simple true/false value.

Resolves #7491
2022-01-04 14:22:48 +00:00
Tom Hvitved
964915ee2e C#: Treat QL test stubs as not from source 2022-01-04 14:53:28 +01:00
Tom Hvitved
a1bbe58516 C#: More uses of PopulateArguments 2022-01-04 13:47:55 +01:00
Alex Ford
dadaf25262 Merge branch 'main' into ruby/rails-cookie-config 2022-01-04 12:04:44 +00:00
dependabot[bot]
b74af00b2b Update clap requirement from 2.33 to 3.0 in /ruby/generator
Updates the requirements on [clap](https://github.com/clap-rs/clap) to permit the latest version.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_generate-v3.0.0-rc.0...clap_complete-v3.0.0)

---
updated-dependencies:
- dependency-name: clap
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-03 16:12:45 +00:00
Alex Ford
7d3932dc8d Merge remote-tracking branch 'origin/main' into ruby/rails-cookie-config 2021-12-22 17:54:03 +00:00
Alex Ford
7f01be7067 Ruby: use new changenote format for rb/weak-cookie-configuration 2021-12-22 17:47:44 +00:00
Alex Ford
d977e8a473 Ruby: remove unnecessary custom transitive version of getReceiver 2021-12-22 17:47:44 +00:00
Alex Ford
9821c4a06c Ruby: behaviour -> behavior
Co-authored-by: Nick Rolfe <nickrolfe@github.com>
2021-12-22 17:47:44 +00:00
Alex Ford
2cd02157c9 Ruby: fix import 2021-12-22 17:47:44 +00:00
Alex Ford
db967bde89 Ruby: add a change note for rb/weak-cookie-configuration 2021-12-22 17:47:44 +00:00
Alex Ford
71c5711eb3 Ruby: add some rb/weak-cookie-configuration tests 2021-12-22 17:47:44 +00:00
Alex Ford
8976469d9b Ruby: Model some Rails cookie configuration settings 2021-12-22 17:47:44 +00:00
Alex Ford
5ce6e63590 Ruby: Tidy Rails.qll to make adding new settings modeling easier 2021-12-22 17:47:44 +00:00
Alex Ford
737f7332bc Ruby: add rb/weak-cookie-configuration query 2021-12-22 17:47:44 +00:00
Alex Ford
8a3d1fe174 Ruby: add CookieSecurityConfigurationSetting concept 2021-12-22 17:47:43 +00:00
Tom Hvitved
8a62778e92 C#: Extract out/ref information in this(...) constructor calls 2021-12-22 13:05:58 +01:00
Tom Hvitved
a3b1fb603a C#: Add missing tuple declarations to PatternExpr
`x` and `y` in `pair is var (x, y) ? x : null` are now correctly part of `PatternExpr`.
2021-12-22 13:05:58 +01:00
Tom Hvitved
915c0fdf9b Shared SSA: Sync files 2021-12-22 13:05:58 +01:00
Tom Hvitved
05e37a7465 C#: Promote existing ad-hoc consistency checks to consistency queries 2021-12-22 13:05:58 +01:00
Mathias Vorreiter Pedersen
5a38f81e23 C++: Accept test changes. 2021-12-21 08:08:59 +01:00
Mathias Vorreiter Pedersen
bbb936154a C++: Increase the precision of 'cpp/uncontrolled-arithmetic' to high. 2021-12-20 14:03:13 +01:00
Mathias Vorreiter Pedersen
95fa93b274 C++: Only recognize signed integers as sinks in 'cpp/uncontrolled-arithmetic' in the case of overflow. 2021-12-20 14:02:44 +01:00
Andrew Eisenberg
7a38618e24 Solorigate: Post-release version bump 2021-12-17 12:30:09 -08:00
Andrew Eisenberg
50ee4ab330 Solorigate: Extract to separate qlpack
Extracts solorigate to separate qlpacks in preparation for
publishing them to the registry.
2021-12-16 16:09:20 -08:00
Sam Partington
db7b3bc136 Remove experimental tag from non-ATM queries 2021-12-15 16:17:14 +00:00
Tony Torralba
6613a98e02 Fix references to logging library 2021-11-04 09:15:57 +01:00
Tony Torralba
ea7e259cfc Add change note 2021-11-04 08:51:13 +01:00
Tony Torralba
474bf576a7 Minor corrections in QLDoc, qhelp and example code 2021-11-04 08:46:23 +01:00
Tony Torralba
f1df542345 Add stubs & tests
Fix mistakes detected by the tests
2021-11-03 17:26:13 +01:00
Tony Torralba
7d88f80fb9 Add tests for summaries 2021-11-03 10:35:38 +01:00
Tony Torralba
ebd6529469 WIP: add tests 2021-11-02 10:37:41 +01:00
Tony Torralba
3ea1af3819 Refactor into separate libraries 2021-10-29 17:36:02 +02:00
Tony Torralba
7f15177498 Move from experimental 2021-10-29 10:19:05 +02:00
Niroshan Rajadurai
d9826c571a Update README.md
Updates to point to GHAS Capabilities, and tighter wording on License terms
2021-05-13 13:17:16 +01:00
606 changed files with 9250 additions and 2285 deletions

View File

@@ -4,10 +4,12 @@
"*/ql/lib/qlpack.yml", "*/ql/lib/qlpack.yml",
"*/ql/test/qlpack.yml", "*/ql/test/qlpack.yml",
"*/ql/examples/qlpack.yml", "*/ql/examples/qlpack.yml",
"*/upgrades/qlpack.yml",
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml", "cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml", "javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml", "javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
"csharp/ql/campaigns/Solorigate/lib/qlpack.yml",
"csharp/ql/campaigns/Solorigate/src/qlpack.yml",
"csharp/ql/campaigns/Solorigate/test/qlpack.yml",
"misc/legacy-support/*/qlpack.yml", "misc/legacy-support/*/qlpack.yml",
"misc/suite-helpers/qlpack.yml", "misc/suite-helpers/qlpack.yml",
"ruby/extractor-pack/codeql-extractor.yml", "ruby/extractor-pack/codeql-extractor.yml",

View File

@@ -1,11 +1,11 @@
# CodeQL # CodeQL
This open source repository contains the standard CodeQL libraries and queries that power [LGTM](https://lgtm.com) and the other CodeQL products that [GitHub](https://github.com) makes available to its customers worldwide. For the queries, libraries, and extractor that power Go analysis, visit the [CodeQL for Go repository](https://github.com/github/codeql-go). This open source repository contains the standard CodeQL libraries and queries that power [GitHub Advanced Security](https://github.com/features/security/code) and the other application security products that [GitHub](https://github.com/features/security/) makes available to its customers worldwide. For the queries, libraries, and extractor that power Go analysis, visit the [CodeQL for Go repository](https://github.com/github/codeql-go).
## How do I learn CodeQL and run queries? ## How do I learn CodeQL and run queries?
There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL. There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension to try out your queries on any open source project that's currently being analyzed. You can use the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension or the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com (Semmle Legacy product) to try out your queries on any open source project that's currently being analyzed.
## Contributing ## Contributing
@@ -13,7 +13,7 @@ We welcome contributions to our standard library and standard checks. Do you hav
## License ## License
The code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com). The code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com). The use of CodeQL on open source code is licensed under specific [Terms & Conditions](https://securitylab.github.com/tools/codeql/license/) UNLESS you have a commercial license in place. If you'd like to use CodeQL with a commercial codebase, please [contact us](https://github.com/enterprise/contact) for further help.
## Visual Studio Code integration ## Visual Studio Code integration

View File

@@ -4,5 +4,4 @@ groups: cpp
dbscheme: semmlecode.cpp.dbscheme dbscheme: semmlecode.cpp.dbscheme
extractor: cpp extractor: cpp
library: true library: true
dependencies: upgrades: upgrades
codeql/cpp-upgrades: ^0.0.3

View File

@@ -435,7 +435,7 @@ module FlowVar_internal {
parameterIsNonConstReference(p) and parameterIsNonConstReference(p) and
p = v and p = v and
// This definition reaches the exit node of the function CFG // This definition reaches the exit node of the function CFG
getAReachedBlockVarSBB(this).getANode() = p.getFunction() getAReachedBlockVarSBB(this).getEnd() = p.getFunction()
} }
override predicate definedByInitialValue(StackVariable lsv) { override predicate definedByInitialValue(StackVariable lsv) {

View File

@@ -63,7 +63,7 @@ private module VirtualDispatch {
this.flowsFrom(other, allowOtherFromArg) this.flowsFrom(other, allowOtherFromArg)
| |
// Call argument // Call argument
exists(DataFlowCall call, int i | exists(DataFlowCall call, Position i |
other other
.(DataFlow::ParameterNode) .(DataFlow::ParameterNode)
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and .isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
@@ -268,16 +268,6 @@ Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) {
) )
} }
/** A parameter position represented by an integer. */
class ParameterPosition extends int {
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
}
/** An argument position represented by an integer. */
class ArgumentPosition extends int {
ArgumentPosition() { any(ArgumentNode a).argumentOf(_, this) }
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */ /** Holds if arguments at position `apos` match parameters at position `ppos`. */
pragma[inline] pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }

View File

@@ -27,7 +27,7 @@ abstract class ArgumentNode extends OperandNode {
* Holds if this argument occurs at the given position in the given call. * Holds if this argument occurs at the given position in the given call.
* The instance argument is considered to have index `-1`. * The instance argument is considered to have index `-1`.
*/ */
abstract predicate argumentOf(DataFlowCall call, int pos); abstract predicate argumentOf(DataFlowCall call, ArgumentPosition pos);
/** Gets the call in which this node is an argument. */ /** Gets the call in which this node is an argument. */
DataFlowCall getCall() { this.argumentOf(result, _) } DataFlowCall getCall() { this.argumentOf(result, _) }
@@ -42,7 +42,9 @@ private class PrimaryArgumentNode extends ArgumentNode {
PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) } PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) }
override predicate argumentOf(DataFlowCall call, int pos) { op = call.getArgumentOperand(pos) } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
op = call.getArgumentOperand(pos.(DirectPosition).getIndex())
}
override string toString() { override string toString() {
exists(Expr unconverted | exists(Expr unconverted |
@@ -71,9 +73,9 @@ private class SideEffectArgumentNode extends ArgumentNode {
SideEffectArgumentNode() { op = read.getSideEffectOperand() } SideEffectArgumentNode() { op = read.getSideEffectOperand() }
override predicate argumentOf(DataFlowCall call, int pos) { override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
read.getPrimaryInstruction() = call and read.getPrimaryInstruction() = call and
pos = getArgumentPosOfSideEffect(read.getIndex()) pos.(IndirectionPosition).getIndex() = read.getIndex()
} }
override string toString() { override string toString() {
@@ -90,6 +92,54 @@ private class SideEffectArgumentNode extends ArgumentNode {
} }
} }
/** A parameter position represented by an integer. */
class ParameterPosition = Position;
/** An argument position represented by an integer. */
class ArgumentPosition = Position;
class Position extends TPosition {
abstract string toString();
}
class DirectPosition extends TDirectPosition {
int index;
DirectPosition() { this = TDirectPosition(index) }
string toString() {
index = -1 and
result = "this"
or
index != -1 and
result = index.toString()
}
int getIndex() { result = index }
}
class IndirectionPosition extends TIndirectionPosition {
int index;
IndirectionPosition() { this = TIndirectionPosition(index) }
string toString() {
index = -1 and
result = "this"
or
index != -1 and
result = index.toString()
}
int getIndex() { result = index }
}
newtype TPosition =
TDirectPosition(int index) { exists(any(CallInstruction c).getArgument(index)) } or
TIndirectionPosition(int index) {
exists(ReadSideEffectInstruction instr | instr.getIndex() = index)
}
private newtype TReturnKind = private newtype TReturnKind =
TNormalReturnKind() or TNormalReturnKind() or
TIndirectReturnKind(ParameterIndex index) TIndirectReturnKind(ParameterIndex index)

View File

@@ -490,19 +490,6 @@ class ExprNode extends InstructionNode {
override string toString() { result = this.asConvertedExpr().toString() } override string toString() { result = this.asConvertedExpr().toString() }
} }
/**
* INTERNAL: do not use. Translates a parameter/argument index into a negative
* number that denotes the index of its side effect (pointer indirection).
*/
bindingset[index]
int getArgumentPosOfSideEffect(int index) {
// -1 -> -2
// 0 -> -3
// 1 -> -4
// ...
result = -3 - index
}
/** /**
* The value of a parameter at function entry, viewed as a node in a data * The value of a parameter at function entry, viewed as a node in a data
* flow graph. This includes both explicit parameters such as `x` in `f(x)` * flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -525,7 +512,7 @@ class ParameterNode extends InstructionNode {
* implicit `this` parameter is considered to have position `-1`, and * implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions. * pointer-indirection parameters are at further negative positions.
*/ */
predicate isParameterOf(Function f, int pos) { none() } // overridden by subclasses predicate isParameterOf(Function f, ParameterPosition pos) { none() } // overridden by subclasses
} }
/** An explicit positional parameter, not including `this` or `...`. */ /** An explicit positional parameter, not including `this` or `...`. */
@@ -534,8 +521,8 @@ private class ExplicitParameterNode extends ParameterNode {
ExplicitParameterNode() { exists(instr.getParameter()) } ExplicitParameterNode() { exists(instr.getParameter()) }
override predicate isParameterOf(Function f, int pos) { override predicate isParameterOf(Function f, ParameterPosition pos) {
f.getParameter(pos) = instr.getParameter() f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
} }
/** Gets the `Parameter` associated with this node. */ /** Gets the `Parameter` associated with this node. */
@@ -550,8 +537,8 @@ class ThisParameterNode extends ParameterNode {
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable } ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
override predicate isParameterOf(Function f, int pos) { override predicate isParameterOf(Function f, ParameterPosition pos) {
pos = -1 and instr.getEnclosingFunction() = f pos.(DirectPosition).getIndex() = -1 and instr.getEnclosingFunction() = f
} }
override string toString() { result = "this" } override string toString() { result = "this" }
@@ -561,12 +548,12 @@ class ThisParameterNode extends ParameterNode {
class ParameterIndirectionNode extends ParameterNode { class ParameterIndirectionNode extends ParameterNode {
override InitializeIndirectionInstruction instr; override InitializeIndirectionInstruction instr;
override predicate isParameterOf(Function f, int pos) { override predicate isParameterOf(Function f, ParameterPosition pos) {
exists(int index | exists(int index |
instr.getEnclosingFunction() = f and instr.getEnclosingFunction() = f and
instr.hasIndex(index) instr.hasIndex(index)
| |
pos = getArgumentPosOfSideEffect(index) pos.(IndirectionPosition).getIndex() = index
) )
} }

View File

@@ -659,4 +659,15 @@ module Consistency {
not phiHasInputFromBlock(_, def, _) and not phiHasInputFromBlock(_, def, _) and
not uncertainWriteDefinitionInput(_, def) not uncertainWriteDefinitionInput(_, def)
} }
query predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) {
exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef) |
ssaDefReachesReadWithinBlock(v, def, bb, i) and
(bb != bbDef or i < iDef)
or
ssaDefReachesRead(v, def, bb, i) and
not ssaDefReachesReadWithinBlock(v, def, bb, i) and
not def.definesAt(v, getImmediateBasicBlockDominator*(bb), _)
)
}
} }

View File

@@ -51,16 +51,6 @@ private newtype TDefOrUse =
TExplicitUse(Operand op) { isExplicitUse(op) } or TExplicitUse(Operand op) { isExplicitUse(op) } or
TReturnParamIndirection(Operand op) { returnParameterIndirection(op, _) } TReturnParamIndirection(Operand op) { returnParameterIndirection(op, _) }
pragma[nomagic]
private int getRank(DefOrUse defOrUse, IRBlock block) {
defOrUse =
rank[result](int i, DefOrUse cand |
block.getInstruction(i) = toInstruction(cand)
|
cand order by i
)
}
private class DefOrUse extends TDefOrUse { private class DefOrUse extends TDefOrUse {
/** Gets the instruction associated with this definition, if any. */ /** Gets the instruction associated with this definition, if any. */
Instruction asDef() { none() } Instruction asDef() { none() }
@@ -74,9 +64,10 @@ private class DefOrUse extends TDefOrUse {
/** Gets the block of this definition or use. */ /** Gets the block of this definition or use. */
abstract IRBlock getBlock(); abstract IRBlock getBlock();
/** Holds if this definition or use has rank `rank` in block `block`. */ /** Holds if this definition or use has index `index` in block `block`. */
cached final predicate hasIndexInBlock(IRBlock block, int index) {
final predicate hasRankInBlock(IRBlock block, int rnk) { rnk = getRank(this, block) } block.getInstruction(index) = toInstruction(this)
}
/** Gets the location of this element. */ /** Gets the location of this element. */
abstract Cpp::Location getLocation(); abstract Cpp::Location getLocation();
@@ -313,8 +304,8 @@ cached
private module Cached { private module Cached {
private predicate defUseFlow(Node nodeFrom, Node nodeTo) { private predicate defUseFlow(Node nodeFrom, Node nodeTo) {
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, DefOrUse defOrUse, Use use | exists(IRBlock bb1, int i1, IRBlock bb2, int i2, DefOrUse defOrUse, Use use |
defOrUse.hasRankInBlock(bb1, i1) and defOrUse.hasIndexInBlock(bb1, i1) and
use.hasRankInBlock(bb2, i2) and use.hasIndexInBlock(bb2, i2) and
adjacentDefRead(_, bb1, i1, bb2, i2) and adjacentDefRead(_, bb1, i1, bb2, i2) and
nodeFrom.asInstruction() = toInstruction(defOrUse) and nodeFrom.asInstruction() = toInstruction(defOrUse) and
flowOutOfAddressStep(use.getOperand(), nodeTo) flowOutOfAddressStep(use.getOperand(), nodeTo)
@@ -326,9 +317,9 @@ private module Cached {
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Def def, Use use | exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Def def, Use use |
nodeFrom.isTerminal() and nodeFrom.isTerminal() and
def.getInstruction() = nodeFrom.getStoreInstruction() and def.getInstruction() = nodeFrom.getStoreInstruction() and
def.hasRankInBlock(bb1, i1) and def.hasIndexInBlock(bb1, i1) and
adjacentDefRead(_, bb1, i1, bb2, i2) and adjacentDefRead(_, bb1, i1, bb2, i2) and
use.hasRankInBlock(bb2, i2) and use.hasIndexInBlock(bb2, i2) and
flowOutOfAddressStep(use.getOperand(), nodeTo) flowOutOfAddressStep(use.getOperand(), nodeTo)
) )
or or
@@ -359,8 +350,8 @@ private module Cached {
private predicate fromReadNode(ReadNode nodeFrom, Node nodeTo) { private predicate fromReadNode(ReadNode nodeFrom, Node nodeTo) {
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Use use1, Use use2 | exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Use use1, Use use2 |
use1.hasRankInBlock(bb1, i1) and use1.hasIndexInBlock(bb1, i1) and
use2.hasRankInBlock(bb2, i2) and use2.hasIndexInBlock(bb2, i2) and
use1.getOperand().getDef() = nodeFrom.getInstruction() and use1.getOperand().getDef() = nodeFrom.getInstruction() and
adjacentDefRead(_, bb1, i1, bb2, i2) and adjacentDefRead(_, bb1, i1, bb2, i2) and
flowOutOfAddressStep(use2.getOperand(), nodeTo) flowOutOfAddressStep(use2.getOperand(), nodeTo)
@@ -371,7 +362,7 @@ private module Cached {
exists(PhiNode phi, Use use, IRBlock block, int rnk | exists(PhiNode phi, Use use, IRBlock block, int rnk |
phi = nodeFrom.getPhiNode() and phi = nodeFrom.getPhiNode() and
adjacentDefRead(phi, _, _, block, rnk) and adjacentDefRead(phi, _, _, block, rnk) and
use.hasRankInBlock(block, rnk) and use.hasIndexInBlock(block, rnk) and
flowOutOfAddressStep(use.getOperand(), nodeTo) flowOutOfAddressStep(use.getOperand(), nodeTo)
) )
} }
@@ -379,7 +370,7 @@ private module Cached {
private predicate toPhiNode(Node nodeFrom, SsaPhiNode nodeTo) { private predicate toPhiNode(Node nodeFrom, SsaPhiNode nodeTo) {
// Flow to phi nodes // Flow to phi nodes
exists(Def def, IRBlock block, int rnk | exists(Def def, IRBlock block, int rnk |
def.hasRankInBlock(block, rnk) and def.hasIndexInBlock(block, rnk) and
nodeTo.hasInputAtRankInBlock(block, rnk) nodeTo.hasInputAtRankInBlock(block, rnk)
| |
exists(StoreNodeInstr storeNode | exists(StoreNodeInstr storeNode |
@@ -512,8 +503,8 @@ private module Cached {
| |
store = def.getInstruction() and store = def.getInstruction() and
store.getSourceValueOperand() = operand and store.getSourceValueOperand() = operand and
def.hasRankInBlock(block1, rnk1) and def.hasIndexInBlock(block1, rnk1) and
use.hasRankInBlock(block2, rnk2) and use.hasIndexInBlock(block2, rnk2) and
adjacentDefRead(_, block1, rnk1, block2, rnk2) adjacentDefRead(_, block1, rnk1, block2, rnk2)
| |
// The shared SSA library has determined that `use` is the next use of the operand // The shared SSA library has determined that `use` is the next use of the operand
@@ -543,12 +534,12 @@ private module Cached {
not operand = getSourceAddressOperand(_) and not operand = getSourceAddressOperand(_) and
exists(Use use1, Use use2, IRBlock block1, int rnk1, IRBlock block2, int rnk2 | exists(Use use1, Use use2, IRBlock block1, int rnk1, IRBlock block2, int rnk2 |
use1.getOperand() = operand and use1.getOperand() = operand and
use1.hasRankInBlock(block1, rnk1) and use1.hasIndexInBlock(block1, rnk1) and
// Don't flow to the next use if this use is part of a store operation that totally // Don't flow to the next use if this use is part of a store operation that totally
// overrides a variable. // overrides a variable.
not explicitWrite(true, _, use1.getOperand().getDef()) and not explicitWrite(true, _, use1.getOperand().getDef()) and
adjacentDefRead(_, block1, rnk1, block2, rnk2) and adjacentDefRead(_, block1, rnk1, block2, rnk2) and
use2.hasRankInBlock(block2, rnk2) and use2.hasIndexInBlock(block2, rnk2) and
flowOutOfAddressStep(use2.getOperand(), nodeTo) flowOutOfAddressStep(use2.getOperand(), nodeTo)
) )
or or
@@ -620,7 +611,7 @@ import Cached
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) { predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
DataFlowImplCommon::forceCachingInSameStage() and DataFlowImplCommon::forceCachingInSameStage() and
exists(Def def | exists(Def def |
def.hasRankInBlock(bb, i) and def.hasIndexInBlock(bb, i) and
v = def.getSourceVariable() and v = def.getSourceVariable() and
(if def.isCertain() then certain = true else certain = false) (if def.isCertain() then certain = true else certain = false)
) )
@@ -632,7 +623,7 @@ predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
*/ */
predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) { predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) {
exists(Use use | exists(Use use |
use.hasRankInBlock(bb, i) and use.hasIndexInBlock(bb, i) and
v = use.getSourceVariable() and v = use.getSourceVariable() and
certain = true certain = true
) )

View File

@@ -9,6 +9,7 @@ import semmle.code.cpp.controlflow.Dominance
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
import semmle.code.cpp.controlflow.Guards
/** /**
* Holds if the value of `use` is guarded using `abs`. * Holds if the value of `use` is guarded using `abs`.
@@ -16,53 +17,16 @@ import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
predicate guardedAbs(Operation e, Expr use) { predicate guardedAbs(Operation e, Expr use) {
exists(FunctionCall fc | fc.getTarget().getName() = ["abs", "labs", "llabs", "imaxabs"] | exists(FunctionCall fc | fc.getTarget().getName() = ["abs", "labs", "llabs", "imaxabs"] |
fc.getArgument(0).getAChild*() = use and fc.getArgument(0).getAChild*() = use and
guardedLesser(e, fc) exists(GuardCondition c | c.ensuresLt(fc, _, _, e.getBasicBlock(), true))
) )
} }
/**
* Gets the position of `stmt` in basic block `block` (this is a thin layer
* over `BasicBlock.getNode`, intended to improve performance).
*/
pragma[noinline]
private int getStmtIndexInBlock(BasicBlock block, Stmt stmt) { block.getNode(result) = stmt }
pragma[inline]
private predicate stmtDominates(Stmt dominator, Stmt dominated) {
// In same block
exists(BasicBlock block, int dominatorIndex, int dominatedIndex |
dominatorIndex = getStmtIndexInBlock(block, dominator) and
dominatedIndex = getStmtIndexInBlock(block, dominated) and
dominatedIndex >= dominatorIndex
)
or
// In (possibly) different blocks
bbStrictlyDominates(dominator.getBasicBlock(), dominated.getBasicBlock())
}
/** /**
* Holds if the value of `use` is guarded to be less than something, and `e` * Holds if the value of `use` is guarded to be less than something, and `e`
* is in code controlled by that guard (where the guard condition held). * is in code controlled by that guard (where the guard condition held).
*/ */
pragma[nomagic]
predicate guardedLesser(Operation e, Expr use) { predicate guardedLesser(Operation e, Expr use) {
exists(IfStmt c, RelationalOperation guard | exists(GuardCondition c | c.ensuresLt(use, _, _, e.getBasicBlock(), true))
use = guard.getLesserOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
stmtDominates(c.getThen(), e.getEnclosingStmt())
)
or
exists(Loop c, RelationalOperation guard |
use = guard.getLesserOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
stmtDominates(c.getStmt(), e.getEnclosingStmt())
)
or
exists(ConditionalExpr c, RelationalOperation guard |
use = guard.getLesserOperand().getAChild*() and
guard = c.getCondition().getAChild*() and
c.getThen().getAChild*() = e
)
or or
guardedAbs(e, use) guardedAbs(e, use)
} }
@@ -71,25 +35,8 @@ predicate guardedLesser(Operation e, Expr use) {
* Holds if the value of `use` is guarded to be greater than something, and `e` * Holds if the value of `use` is guarded to be greater than something, and `e`
* is in code controlled by that guard (where the guard condition held). * is in code controlled by that guard (where the guard condition held).
*/ */
pragma[nomagic]
predicate guardedGreater(Operation e, Expr use) { predicate guardedGreater(Operation e, Expr use) {
exists(IfStmt c, RelationalOperation guard | exists(GuardCondition c | c.ensuresLt(use, _, _, e.getBasicBlock(), false))
use = guard.getGreaterOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
stmtDominates(c.getThen(), e.getEnclosingStmt())
)
or
exists(Loop c, RelationalOperation guard |
use = guard.getGreaterOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
stmtDominates(c.getStmt(), e.getEnclosingStmt())
)
or
exists(ConditionalExpr c, RelationalOperation guard |
use = guard.getGreaterOperand().getAChild*() and
guard = c.getCondition().getAChild*() and
c.getThen().getAChild*() = e
)
or or
guardedAbs(e, use) guardedAbs(e, use)
} }

View File

@@ -26,6 +26,8 @@ where
// At least for C programs on Windows, BOOL is a common typedef for a type // At least for C programs on Windows, BOOL is a common typedef for a type
// representing BoolType. // representing BoolType.
not bf.getType().hasName("BOOL") and not bf.getType().hasName("BOOL") and
// GLib's gboolean is a typedef for a type representing BoolType.
not bf.getType().hasName("gboolean") and
// If this is true, then there cannot be unsigned sign extension or overflow. // If this is true, then there cannot be unsigned sign extension or overflow.
not bf.getDeclaredNumBits() = bf.getType().getSize() * 8 and not bf.getDeclaredNumBits() = bf.getType().getSize() * 8 and
not bf.isAnonymous() and not bf.isAnonymous() and

View File

@@ -5,7 +5,7 @@
* @kind path-problem * @kind path-problem
* @problem.severity warning * @problem.severity warning
* @security-severity 8.6 * @security-severity 8.6
* @precision medium * @precision high
* @id cpp/uncontrolled-arithmetic * @id cpp/uncontrolled-arithmetic
* @tags security * @tags security
* external/cwe/cwe-190 * external/cwe/cwe-190
@@ -82,8 +82,11 @@ predicate missingGuard(VariableAccess va, string effect) {
op.getUnspecifiedType().(IntegralType).isUnsigned() and op.getUnspecifiedType().(IntegralType).isUnsigned() and
not op instanceof MulExpr not op instanceof MulExpr
or or
// overflow // overflow - only report signed integer overflow since unsigned overflow
missingGuardAgainstOverflow(op, va) and effect = "overflow" // is well-defined.
op.getUnspecifiedType().(IntegralType).isSigned() and
missingGuardAgainstOverflow(op, va) and
effect = "overflow"
) )
} }

View File

@@ -89,11 +89,13 @@ predicate referenceTo(Expr source, Expr use) {
) )
} }
from Expr check, Expr checkPath, FunctionCall use, Expr usePath pragma[noinline]
where predicate statCallWithPointer(Expr checkPath, Expr call, Expr e, Variable v) {
// `check` looks like a check on a filename call = stat(checkPath, e) and
( e.getAChild*().(VariableAccess).getTarget() = v
( }
predicate checksPath(Expr check, Expr checkPath) {
// either: // either:
// an access check // an access check
check = accessCheck(checkPath) check = accessCheck(checkPath)
@@ -105,29 +107,65 @@ where
// (morally, this should be a use-use pair, but it seems unlikely // (morally, this should be a use-use pair, but it seems unlikely
// that this variable will get reused in practice) // that this variable will get reused in practice)
exists(Expr call, Expr e, Variable v | exists(Expr call, Expr e, Variable v |
call = stat(checkPath, e) and statCallWithPointer(checkPath, call, e, v) and
e.getAChild*().(VariableAccess).getTarget() = v and
check.(VariableAccess).getTarget() = v and check.(VariableAccess).getTarget() = v and
not e.getAChild*() = check // the call that writes to the pointer is not where the pointer is checked. not e.getAChild*() = check // the call that writes to the pointer is not where the pointer is checked.
) )
}
pragma[nomagic]
predicate checkPathControlsUse(Expr check, Expr checkPath, Expr use) {
exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) |
guard.controls(use.getBasicBlock(), _)
) and ) and
checksPath(pragma[only_bind_into](check), checkPath)
}
pragma[nomagic]
predicate fileNameOperationControlsUse(Expr check, Expr checkPath, Expr use) {
exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) |
guard.controls(use.getBasicBlock(), _)
) and
pragma[only_bind_into](check) = filenameOperation(checkPath)
}
predicate checkUse(Expr check, Expr checkPath, FunctionCall use, Expr usePath) {
// `check` is part of a guard that controls `use`
checkPathControlsUse(check, checkPath, use) and
// `check` looks like a check on a filename
checksPath(check, checkPath) and
// `op` looks like an operation on a filename // `op` looks like an operation on a filename
use = filenameOperation(usePath) use = filenameOperation(usePath)
or or
// `check` is part of a guard that controls `use`
fileNameOperationControlsUse(check, checkPath, use) and
// another filename operation (null pointers can indicate errors) // another filename operation (null pointers can indicate errors)
check = filenameOperation(checkPath) and check = filenameOperation(checkPath) and
// `op` looks like a sensitive operation on a filename // `op` looks like a sensitive operation on a filename
use = sensitiveFilenameOperation(usePath) use = sensitiveFilenameOperation(usePath)
) and }
pragma[noinline]
predicate isCheckedPath(
Expr check, SsaDefinition def, StackVariable v, FunctionCall use, Expr usePath, Expr checkPath
) {
checkUse(check, checkPath, use, usePath) and
def.getAUse(v) = checkPath
}
pragma[noinline]
predicate isUsedPath(
Expr check, SsaDefinition def, StackVariable v, FunctionCall use, Expr usePath, Expr checkPath
) {
checkUse(check, checkPath, use, usePath) and
def.getAUse(v) = usePath
}
from Expr check, Expr checkPath, FunctionCall use, Expr usePath, SsaDefinition def, StackVariable v
where
// `checkPath` and `usePath` refer to the same SSA variable // `checkPath` and `usePath` refer to the same SSA variable
exists(SsaDefinition def, StackVariable v | isCheckedPath(check, def, v, use, usePath, checkPath) and
def.getAUse(v) = checkPath and def.getAUse(v) = usePath isUsedPath(check, def, v, use, usePath, checkPath)
) and
// the return value of `check` is used (possibly with one step of
// variable indirection) in a guard which controls `use`
exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) |
guard.controls(use.(ControlFlowNode).getBasicBlock(), _)
)
select use, select use,
"The $@ being operated upon was previously $@, but the underlying file may have been changed since then.", "The $@ being operated upon was previously $@, but the underlying file may have been changed since then.",
usePath, "filename", check, "checked" usePath, "filename", check, "checked"

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added exception for GLib's gboolean to cpp/ambiguously-signed-bit-field.
This change reduces the number of false positives in the query.

View File

@@ -0,0 +1,4 @@
---
category: newQuery
---
* The "Uncontrolled data in arithmetic expression" (cpp/uncontrolled-arithmetic) query has been enhanced to reduce false positive results and its @precision increased to high.

View File

@@ -35,8 +35,6 @@ edges
| test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y |
| test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y |
| test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x |
| test.cpp:223:20:223:23 | call to rand | test.cpp:227:8:227:8 | x |
| test.cpp:223:20:223:25 | (unsigned int)... | test.cpp:227:8:227:8 | x |
nodes nodes
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand | | test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
| test.c:21:17:21:17 | r | semmle.label | r | | test.c:21:17:21:17 | r | semmle.label | r |
@@ -92,9 +90,6 @@ nodes
| test.cpp:208:7:208:7 | y | semmle.label | y | | test.cpp:208:7:208:7 | y | semmle.label | y |
| test.cpp:215:11:215:14 | call to rand | semmle.label | call to rand | | test.cpp:215:11:215:14 | call to rand | semmle.label | call to rand |
| test.cpp:219:8:219:8 | x | semmle.label | x | | test.cpp:219:8:219:8 | x | semmle.label | x |
| test.cpp:223:20:223:23 | call to rand | semmle.label | call to rand |
| test.cpp:223:20:223:25 | (unsigned int)... | semmle.label | (unsigned int)... |
| test.cpp:227:8:227:8 | x | semmle.label | x |
subpaths subpaths
#select #select
| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | Uncontrolled value | | test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | Uncontrolled value |
@@ -125,5 +120,3 @@ subpaths
| test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | Uncontrolled value | | test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | Uncontrolled value |
| test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | Uncontrolled value | | test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | Uncontrolled value |
| test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | Uncontrolled value | | test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | Uncontrolled value |
| test.cpp:227:8:227:8 | x | test.cpp:223:20:223:23 | call to rand | test.cpp:227:8:227:8 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:223:20:223:23 | call to rand | Uncontrolled value |
| test.cpp:227:8:227:8 | x | test.cpp:223:20:223:25 | (unsigned int)... | test.cpp:227:8:227:8 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:223:20:223:23 | call to rand | Uncontrolled value |

View File

@@ -157,3 +157,11 @@ void moreTests() {
r = r - 100; // BAD r = r - 100; // BAD
} }
} }
void guarded_test(unsigned p) {
unsigned data = (unsigned int)rand();
if (p >= data) {
return;
}
unsigned z = data - p; // GOOD
}

Some files were not shown because too many files have changed in this diff Show More