Compare commits

..

674 Commits

Author SHA1 Message Date
Calum Grant
18304c13cb C++: Update expected results 2024-06-28 16:08:36 +01:00
Jami
42925b56e3 Merge pull request #15921 from jcogs33/jcogs33/unsafe-url-forward-promotion-resource-and-file-methods
Java: add models for some resource-related methods
2024-06-28 08:05:50 -04:00
Erik Krogh Kristensen
60811116ab Merge pull request #16332 from erik-krogh/ts55
JS: upgrade TypeScript to 5.5
2024-06-28 13:59:52 +02:00
Tamás Vajk
1cf5e89b96 Merge pull request #16747 from tamasvajk/buildless/binary-log-extractor-2
C#: Add binlog support to buildless with source generator support
2024-06-28 12:39:54 +02:00
Erik Krogh Kristensen
fd3089ee5a Merge pull request #14342 from maikypedia/maikypedia/javascript-cors
JS: Add Permissive CORS query (CWE-942)
2024-06-28 11:27:37 +02:00
Mathias Vorreiter Pedersen
72caadb7db Merge pull request #16869 from hvitved/shared/cfg/mermaid-output
Shared: Generate mermaid output in `View CFG` query
2024-06-28 10:21:02 +01:00
Tom Hvitved
e1c1314824 Shared: Generate mermaid output in View CFG query 2024-06-28 09:45:22 +02:00
Tamas Vajk
4db586f17d Add TSP diagnostic for binlog usage 2024-06-28 09:40:41 +02:00
Tamas Vajk
c8927447f5 Record diagnostics in binlog extraction test 2024-06-28 09:40:13 +02:00
Jami Cogswell
85a1e1a972 Java: update change note date 2024-06-27 22:11:01 -04:00
Jami Cogswell
be565288f2 Java: update more test cases due to shifted alert provenance line numbers 2024-06-27 22:08:38 -04:00
Jami Cogswell
c73af7f789 Java: update some test cases due to shifted alert provenance line numbers 2024-06-27 21:07:35 -04:00
Maiky
d0cf2a978c Merge branch 'main' into maikypedia/javascript-cors 2024-06-27 20:24:42 +02:00
yoff
40b7534210 Merge pull request #16860 from yoff/python/MaD-doc-fixup
Python: fix typo pointed out in review but missed by me
2024-06-27 17:02:39 +02:00
Owen Mansel-Chan
5d7a6e3836 Merge pull request #16851 from github/workflow/coverage/update
Update CSV framework coverage reports
2024-06-27 13:57:30 +01:00
Tamas Vajk
1e2d1ef715 Use dedicated API to get generated syntax trees 2024-06-27 14:49:29 +02:00
Tamas Vajk
0b41d5121a Compute unique identifier (folder path) for each compilation 2024-06-27 14:49:24 +02:00
Tamas Vajk
1ae40c95b1 Change binlog test to have colliding generated file locations 2024-06-27 14:49:20 +02:00
Tamas Vajk
b22f5f557a Fix failed extraction handling 2024-06-27 14:49:16 +02:00
Tamas Vajk
fb0520c74a C#: Adjust trap location, database ID and archiving of generated sources 2024-06-27 14:49:10 +02:00
Tamas Vajk
dcd84f47a4 Improve source archiving to handle non-existent files 2024-06-27 14:49:06 +02:00
Tamas Vajk
31ad195dc3 C#: Add binlog support to buildless with source generator support 2024-06-27 14:48:54 +02:00
Tamás Vajk
b2d2f2d0d8 Merge pull request #16858 from tamasvajk/fix/solution
C#: Fix solution file
2024-06-27 14:31:15 +02:00
Owen Mansel-Chan
50cc720117 Merge branch 'main' into workflow/coverage/update 2024-06-27 10:51:23 +01:00
Rasmus Lerchedahl Petersen
da03237b32 Python: fix typo pointed out in review but missed by me 2024-06-27 11:21:28 +02:00
Tamás Vajk
6c727b1e7d Merge pull request #16857 from tamasvajk/feature/stringformat
C#: Change `string.Format` calls to interpolated strings
2024-06-27 10:55:21 +02:00
Tamas Vajk
3e20d908c4 C#: Fix solution file 2024-06-27 10:53:39 +02:00
Chris Smowton
c5678ad156 Merge pull request #16847 from smowton/smowton/admin/java-diagnostic-test-expectations
Java: Adjust test expectations for Java diagnostic severity changes
2024-06-27 09:53:25 +01:00
Tamas Vajk
0c34b4535a C#: Change string.Format calls to interpolated strings 2024-06-27 09:20:50 +02:00
Tamás Vajk
4a98436884 Merge pull request #16855 from tamasvajk/fix/integration-test
C#: Fix integration test expected file
2024-06-27 08:52:05 +02:00
Tamas Vajk
6b6d705b4f C#: Fix integration test expected file 2024-06-27 08:14:37 +02:00
Jami
901245ae3d Merge branch 'main' into jcogs33/unsafe-url-forward-promotion-resource-and-file-methods 2024-06-26 21:57:07 -04:00
github-actions[bot]
0a8c9da0ac Add changed framework coverage reports 2024-06-27 00:17:25 +00:00
Chris Smowton
f2cbf08d15 Adjust test expectations 2024-06-26 17:37:48 +01:00
Owen Mansel-Chan
272132a09a Merge pull request #16799 from owen-mc/go/mad/match-all-package-versions
Go: Make models-as-data package column match any version without "$ANYVERSION"
2024-06-26 13:46:49 +01:00
Anders Schack-Mulligen
9d8ee99c1c Merge pull request #16806 from aschackmull/dataflow/debug-stages
Dataflow: Add path-problem view of intermediate stages for debug purposes.
2024-06-26 12:53:12 +02:00
Michael Nebel
e1f65d1f8b Merge pull request #16836 from michaelnebel/csharp/bestlocation
C#: Be more consistent when picking between locations.
2024-06-26 12:46:50 +02:00
Cornelius Riemenschneider
c4cc30fb7a Merge pull request #16839 from github/criemen/bazel-721
Bump to bazel 7.2.1.
2024-06-26 11:26:19 +02:00
Paolo Tranquilli
53a7d823ec Merge pull request #16841 from github/redsun82/kotlin
Kotlin: exclude `KotlinExtractorDbScheme.kt` generated by hand
2024-06-26 11:18:44 +02:00
Tamás Vajk
81f4786643 Merge pull request #16832 from tamasvajk/feature/update-dependencies
C#: Update (some) nuget dependencies
2024-06-26 11:12:26 +02:00
Michael Nebel
e258d9fa74 C#: Use the first best location from the list of locations. 2024-06-26 11:04:38 +02:00
Paolo Tranquilli
a52a412c24 Kotlin: exclude KotlinExtractorDbScheme.kt generated by hand 2024-06-26 09:05:09 +02:00
Owen Mansel-Chan
a30b34c4bd Used "fixed-version:" prefix in a test 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
418a56d385 Replace "$THISVERSION" suffix with "fixed-version:" prefix 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
081f32141c Accept review suggestion fixing a comment
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
d4e8e4c943 Add QLDoc for majorVersionSuffixRegex 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
46d0c6ff9c Use lookahead in regex to not match e.g. "/v2foo" 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
c8a3bedf44 Move major version suffix regex into one place 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
cb2ccef5fa Refactor suffix check 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
c045e77d61 Fix QLDoc for interpretPackage 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
7d11fc2c7d Fix bug in regex
I accidentally included a `$` at the end, so it only matched a major
version suffix at the end of the package path.
2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
a9afbfa993 Document version matching and "$THISVERSION" 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
3e2bbd38d4 Remove "$ANYVERSION" from models 2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
47d946fb1c Make MaD package match any version without $ANYVERSION
Note that if the package column contains major version suffix (like
"/v2") or if it ends with "$THISVERSION" (which is removed) then we
don't do any version matching.
2024-06-26 05:01:09 +01:00
Owen Mansel-Chan
ea0db4d55e Add predicate for package path without "/v2" etc 2024-06-26 05:01:09 +01:00
Ian Lynagh
f9ae44ca5c Merge pull request #16736 from igfoo/igfoo/debugLoC
Java/Kotlin: Tag the LoC queries 'debug'
2024-06-25 22:57:36 +01:00
Cornelius Riemenschneider
37da3e1bb3 Bump to bazel 7.2.1. 2024-06-25 21:21:39 +02:00
Chris Smowton
2413332553 Merge pull request #16802 from github/smowton/admin/note-java-system-requirements
Java: document extraction system requirements
2024-06-25 15:53:09 +01:00
Ian Lynagh
c12adbeeaa Java/Kotlin: Tag the LoC queries 'debug'
This brings them into line with LinesOfCode.ql
2024-06-25 15:46:10 +01:00
Michael Nebel
d18915a1e4 C#: Update expected test output. 2024-06-25 16:02:58 +02:00
Michael Nebel
e15a47d58c C#: Update the extractor to use the BestOrDefault extension method to choose between multiple locations. 2024-06-25 16:02:54 +02:00
Michael Nebel
dd65d960be C#: Introduce a Location extension method to help pick a unique location. 2024-06-25 16:02:49 +02:00
Michael Nebel
8dc95ce9b0 Merge pull request #16722 from michaelnebel/csharp/modelgensourcesink
C#/Java: Respect manual neutrals, sources and sinks in model generation.
2024-06-25 15:55:06 +02:00
yoff
58b6b3f601 Merge pull request #16789 from yoff/python/document-models-as-data
python: Document MaD format
2024-06-25 15:46:28 +02:00
Tamas Vajk
5058727980 C#: Update (some) nuget dependencies 2024-06-25 15:24:08 +02:00
Anders Schack-Mulligen
1cc49af454 Dataflow: Address review comments. 2024-06-25 15:19:55 +02:00
Asger F
6a3bb4dd28 Merge pull request #16834 from asgerf/shared/capture-this-location
Shared: add location for 'this' CaptureContainer
2024-06-25 13:18:41 +02:00
Mathias Vorreiter Pedersen
17edfdf801 Merge pull request #16833 from MathiasVP/simplify-incorrect-allocation-error-handling
C++: Simplify `cpp/incorrect-allocation-error-handling`
2024-06-25 12:16:21 +01:00
Rasmus Lerchedahl Petersen
6524b8e25d Python: consistent double quotes in examples 2024-06-25 12:11:52 +02:00
Rasmus Lerchedahl Petersen
09905ee228 Python: double back-tics 2024-06-25 12:05:38 +02:00
Rasmus Lerchedahl Petersen
6d4e993dea Python: remove named parameter filename 2024-06-25 12:00:53 +02:00
Rasmus Lerchedahl Petersen
aa4fd1992e Python: compact types in type models 2024-06-25 11:59:55 +02:00
Rasmus Lerchedahl Petersen
b902dd5680 Python: add change note 2024-06-25 11:54:30 +02:00
Jeroen Ketema
e0e5bdec8a Merge pull request #16818 from jketema/predef
C++: Update expected test results
2024-06-25 11:06:53 +02:00
Mathias Vorreiter Pedersen
921afb71e2 Update cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2024-06-25 10:03:53 +01:00
Owen Mansel-Chan
890da5377e Merge pull request #16819 from owen-mc/go/remove-dataflowtype-optimizer-bug-workaround
Go: Make DataFlowType a singleton (remove workaround)
2024-06-25 10:03:08 +01:00
Asger F
551743e000 Shared: add location for 'this' CaptureContainer
Only has an effect for debugging purposes
2024-06-25 10:34:28 +02:00
Mathias Vorreiter Pedersen
982f845be7 C++: Accept test changes. 2024-06-25 09:31:00 +01:00
Mathias Vorreiter Pedersen
bb8b0d0bf5 C++: Use the unary version of 'comparesEq' to handle both disjuncts. 2024-06-25 09:30:53 +01:00
Jeroen Ketema
285ed3630b C++: Update expected test results 2024-06-25 09:16:05 +02:00
Dave Bartolomeo
1e46e431e8 Merge pull request #16823 from smowton/smowton/admin/maven-transfer-failure-test-expectations
Java: Adjust and tolerate variability in test expectations
2024-06-24 13:54:25 -04:00
Paolo Tranquilli
d2a00fa773 Merge pull request #16822 from github/redsun82/nodejs-mirror
Bazel: add `nodejs` mirror
2024-06-24 17:59:08 +02:00
Chris Smowton
351b908f62 Adjust and tolerate variability in test expectations 2024-06-24 16:38:18 +01:00
Paolo Tranquilli
0669186713 Bazel: remove unneeded upstream rules_nodejs patch 2024-06-24 17:09:40 +02:00
Paolo Tranquilli
a02cf07833 Bazel: add nodejs mirror
This patches `rules_nodejs` with the contents of
https://github.com/bazelbuild/rules_nodejs/pull/3763
in order to allow specifying a mirror for nodejs, as nodejs.org has
hit us with intermittent downtimes.
2024-06-24 16:59:25 +02:00
Mathias Vorreiter Pedersen
5b1b60cc92 Merge pull request #16797 from MathiasVP/yml-for-allocation-and-deallocation
C++: Add extensible predicates to `Allocation` and `Deallocation`
2024-06-24 15:34:27 +01:00
Anders Schack-Mulligen
25d520a7f1 Merge pull request #16785 from aschackmull/dataflow/stage3-notypes
Dataflow: Replace stage 3 type pruning with flow-insensitive type pruning.
2024-06-24 15:21:37 +02:00
Mathias Vorreiter Pedersen
36d59cef7e C++: Add 'bsl::free' as a deallocation function model. 2024-06-24 13:56:44 +01:00
Mathias Vorreiter Pedersen
82ed1ee671 Update cpp/ql/lib/change-notes/2024-06-20-extensible-allocation-deallocation.md
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2024-06-24 13:50:24 +01:00
Owen Mansel-Chan
d8df38c683 Make DataFlowType a singleton (remove workaround) 2024-06-24 13:43:10 +01:00
Mathias Vorreiter Pedersen
19b6d24bc2 Merge pull request #16816 from MathiasVP/fix-valuenumber-imports
C++: Fix value numbering imports
2024-06-24 13:37:38 +01:00
Anders Schack-Mulligen
fdf6e30888 Dataflow: Handle non-trivial type systems with stores into a top type. 2024-06-24 13:35:50 +02:00
Anders Schack-Mulligen
a26132e818 Dataflow: Replace stage 3 type pruning with flow-insensitive type pruning. 2024-06-24 13:35:50 +02:00
Anders Schack-Mulligen
3ede3af6f2 C#: Fix join-order. 2024-06-24 13:35:49 +02:00
Anders Schack-Mulligen
8c23e21073 Dataflow: Cache compatibleTypes. 2024-06-24 13:35:48 +02:00
Anders Schack-Mulligen
06a7e3f3ee Dataflow: Cache typeStrongerThan. 2024-06-24 13:35:48 +02:00
Anders Schack-Mulligen
bd99f32a4b Dataflow: Check types on ParamReturnNode. 2024-06-24 13:35:47 +02:00
Michael Nebel
24685a07c0 Java: Update model generator test expected output. 2024-06-24 13:07:42 +02:00
Michael Nebel
c687dcb094 Java: Sync files and make language specific implementation. 2024-06-24 13:07:39 +02:00
Michael Nebel
30249e4f2b Java: Add some spurious source and sink examples. 2024-06-24 13:07:34 +02:00
Michael Nebel
854674a71c C#: Update expected test output. 2024-06-24 13:07:30 +02:00
Michael Nebel
b27a9d948a C#: Exclude APIs with a manual source neutral from source model generation and allow source generation for all source kinds. 2024-06-24 13:07:14 +02:00
Michael Nebel
2657e7f56d C#: Add some source and sink modelling examples where a neutral exist. 2024-06-24 13:05:35 +02:00
Mathias Vorreiter Pedersen
00d772f980 C++: Fix value numbering imports. 2024-06-24 11:53:24 +01:00
Michael Nebel
abc7cc39d4 Merge pull request #16775 from michaelnebel/modelgen/refactorprinting
C#/Java: Parameterized module for model printing.
2024-06-24 12:51:07 +02:00
Michael Nebel
9cd16fd9d6 Java: Base the model printing on the shared implementation. 2024-06-24 11:52:50 +02:00
Michael Nebel
8630583856 C#/Java: Exclude the model printing implementation form sync files. 2024-06-24 11:50:57 +02:00
Michael Nebel
b7bc540325 C#: Adjust implementation to use the shared model printer. 2024-06-24 11:50:46 +02:00
Michael Nebel
65e150b416 Add parameterized module for MaD model printing. 2024-06-24 11:48:33 +02:00
Owen Mansel-Chan
f04a85e121 Merge pull request #16753 from owen-mc/go/misc-clean-up
Go: a few small clean ups
2024-06-24 10:47:21 +01:00
Michael Nebel
94d12edfdb Merge pull request #16759 from michaelnebel/modelgen/sourcesinkmodelgen
C#/Java: Introduce source and sink model generation sanitisers.
2024-06-24 11:47:11 +02:00
Rasmus Lerchedahl Petersen
4626e134fa Python: update doc to use operations module 2024-06-24 10:56:34 +02:00
Rasmus Lerchedahl Petersen
00fbada41d Python: recognize fabric.operations 2024-06-24 10:54:59 +02:00
Rasmus Lerchedahl Petersen
21a0f8af07 Python: address reviewer comments
- fix wording on `builtins`
- add named argument/parameter access path components
2024-06-24 10:48:53 +02:00
yoff
d603b48884 Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2024-06-24 10:29:33 +02:00
Mathias Vorreiter Pedersen
a1743aa12e Merge pull request #16805 from MathiasVP/tc-in-temp-materialization
C++: Fix missing `asExpr` for temporary materializations with conversions
2024-06-23 13:38:01 +01:00
Owen Mansel-Chan
513ec16691 Merge pull request #16796 from owen-mc/go/fix/package-vendor
Go: Fix bug removing "vendor/" from package paths
2024-06-22 07:54:18 +01:00
Mathias Vorreiter Pedersen
1bb762bea9 C++: Accept test changes. 2024-06-21 13:35:10 +01:00
Mathias Vorreiter Pedersen
7d41e8ef73 C++: Perform a TC to skip conversions when special-casing materialization of temporaries. 2024-06-21 13:35:09 +01:00
Mathias Vorreiter Pedersen
3b585b4196 C++: Add test with missing flow. 2024-06-21 13:35:08 +01:00
Taus
4a448f445e Merge pull request #15715 from am0o0/am0o0-python-codeExec
Python: New command execution sinks
2024-06-21 14:26:33 +02:00
Anders Schack-Mulligen
accc73d1d0 Dataflow: Add debug graph for pruning stages. 2024-06-21 14:25:32 +02:00
Erik Krogh Kristensen
49f74bacf2 Merge pull request #16729 from mbaluda/main
JS: Extract SAP XSJS file types as Javascript
2024-06-21 14:23:55 +02:00
Anders Schack-Mulligen
bbdae5188d Dataflow: Add ArgNodeEx column to fwdFlowIsEntered. 2024-06-21 14:10:37 +02:00
Anders Schack-Mulligen
fa13861e53 Dataflow: Add Debug module with stage references. 2024-06-21 14:02:07 +02:00
Mauro Baluda
b75514c990 Merge branch 'github:main' into main 2024-06-21 13:36:38 +02:00
Chris Smowton
cfb48ace73 Java: document extraction system requirements
Note that a `java` binary is at least highly recommended for Java extraction, and in many circumstances a hard requirement. The same goes for `mvn` and `gradle`.
2024-06-21 11:53:36 +01:00
Kasper Svendsen
988d0671bb Merge pull request #16734 from kaspersv/kaspersv/doc-intern-sets-builtin
Document builtin InternSets module
2024-06-21 12:06:40 +02:00
Tom Hvitved
dff3ce2a9f Merge pull request #16794 from hvitved/ruby/sinatra-flow
Ruby: Rework `Sinatra.FilterJumpStep`
2024-06-21 11:38:10 +02:00
Mathias Vorreiter Pedersen
c357cc9f08 C++: Add change note. 2024-06-21 08:54:12 +01:00
Mathias Vorreiter Pedersen
69490c62cd C++: Add qlpack dependency. 2024-06-21 08:54:10 +01:00
Mathias Vorreiter Pedersen
6bf22bda58 C++: Replace allocation models with models from extensible predicates. 2024-06-21 08:54:09 +01:00
Tom Hvitved
8ea4f85de3 Ruby: Rework Sinatra.FilterJumpStep 2024-06-21 08:57:59 +02:00
Tom Hvitved
95c764eff6 Fix Sinatra test to properly output pathgraph 2024-06-21 08:57:19 +02:00
Erik Krogh Kristensen
db768960f4 Merge pull request #15060 from am0o0/amammad-js-envinjection
JS: Env Injection query
2024-06-20 21:27:21 +02:00
Erik Krogh Kristensen
555d7e5958 Merge pull request #14293 from am0o0/amammad-js-CodeInjection_dynamic_import
JS: Dynamic import as code injection sink
2024-06-20 21:19:57 +02:00
erik-krogh
0de4fd8430 add test for the better type-narrowing in TS 5.5 2024-06-20 20:55:44 +02:00
erik-krogh
9966be6975 update to the stable release of TypeScript 5.5 2024-06-20 20:47:43 +02:00
erik-krogh
b936f725b5 update to 5.5.1-rc 2024-06-20 20:43:01 +02:00
erik-krogh
a691ec01b3 add test for the inferred type predicates in TS5.5 2024-06-20 20:42:59 +02:00
erik-krogh
5336a1a251 upgrade TypeScript to 5.5-beta 2024-06-20 20:42:57 +02:00
Erik Krogh Kristensen
60ed51781e Merge pull request #16790 from github/max-schaefer-patch-1
JavaScript: Fix CodeQL alert in extractor
2024-06-20 20:20:00 +02:00
Erik Krogh Kristensen
e84028d01e Merge pull request #14088 from am0o0/amammad-js-JWT
JS: decoding JWT without signature verification
2024-06-20 20:13:40 +02:00
Mathias Vorreiter Pedersen
d308178781 C++: Add extensible predicate for allocation. 2024-06-20 16:26:52 +01:00
Mathias Vorreiter Pedersen
ce5ab4c4b7 C++: Add qlpack dependency. 2024-06-20 16:26:50 +01:00
Mathias Vorreiter Pedersen
3457551264 C++: Replace deallocation models with models from extensible predicates. 2024-06-20 16:26:49 +01:00
Jeroen Ketema
0e04a59c08 Merge pull request #16795 from jketema/test-cleanup
C++: Remove unneeded options from tests
2024-06-20 16:24:07 +02:00
Mathias Vorreiter Pedersen
e5c20b13cf C++: Add extensible predicate for deallocation. 2024-06-20 14:51:09 +01:00
Jeroen Ketema
4c4c15b425 C++: Remove unneeded options from tests 2024-06-20 14:21:34 +02:00
Owen Mansel-Chan
aa35bd771b Fix bug removing "vendor/" from package paths 2024-06-20 13:18:21 +01:00
Asger F
a36e39359f Merge pull request #16739 from RasmusWL/js-array-steps
JS: Allow many Array steps to be used in type-tracking
2024-06-20 11:39:46 +02:00
Rasmus Lerchedahl Petersen
a7386b6670 Python: include new documentation 2024-06-20 11:25:25 +02:00
Rasmus Lerchedahl Petersen
f0e68887d4 Python: autoformat 2024-06-20 10:59:39 +02:00
yoff
b4fdf3c342 Apply suggestions from code review
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
2024-06-20 10:57:54 +02:00
Rasmus Wriedt Larsen
596102d3fb Update javascript/ql/lib/change-notes/2024-06-14-type-tracking-array-steps.md
Co-authored-by: Asger F <asgerf@github.com>
2024-06-20 10:07:49 +02:00
Owen Mansel-Chan
754fd8e84c Drop leading . from getQualifiedName for built-in functions
So it will be "panic" instead of ".panic".
2024-06-19 22:04:21 +01:00
Owen Mansel-Chan
68a661f3c7 Write out whole function names 2024-06-19 21:58:31 +01:00
Owen Mansel-Chan
b79711b17e Move deprecated notice to top of comment 2024-06-19 21:58:28 +01:00
Max Schaefer
2be171746b JavaScript: Fix CodeQL alert in extractor
This doesn't make a difference in practice because we only run the method on arrays of even length, but we might as well fix it.
2024-06-19 17:13:01 +01:00
Rasmus Lerchedahl Petersen
5cb37f5c4c python: Document MaD format
- add a few tests reflecting the documentation
- make the mentioned sink-kinds have an effect on relevant queries
2024-06-19 17:00:15 +02:00
Michael Nebel
aa962f9b03 Java: Update expected output of model generation. 2024-06-19 14:10:59 +02:00
Michael Nebel
1185e28ea2 Java: Add some spurious source and sink model generation examples. 2024-06-19 14:10:56 +02:00
Michael Nebel
ed3f1e40db Java: Sync changes and make dummy language specific implementation. 2024-06-19 14:10:54 +02:00
Michael Nebel
99907471b2 C#: Update model generator expected output. 2024-06-19 14:10:52 +02:00
Michael Nebel
40204911bc C#: Only allow source propgatation upwards in the call stack if the call path consists of unique call targets (to avoid unwanted virtual dispatch). This severely tightens the generation of extrapolated sources. 2024-06-19 14:10:49 +02:00
Tom Hvitved
6dbdc9e17f Merge pull request #16784 from github/redsun82/fix-warnings-in-ql-tests
C++/Java: Accept new warning format in ql tests
2024-06-19 13:05:50 +02:00
Paolo Tranquilli
b7a2ea8981 CI: accept other diagnostic format related test changes 2024-06-19 11:33:50 +02:00
Paolo Tranquilli
59f8f8a394 Merge branch 'main' into redsun82/fix-warnings-in-ql-tests 2024-06-19 11:21:36 +02:00
Tamás Vajk
45ece48b6f Merge pull request #16776 from tamasvajk/fix/source-generator-folder
C#: Make sure no file is added twice to the compilation
2024-06-19 10:09:50 +02:00
Paolo Tranquilli
919ddccfdb C++/Java: Accept new warning format in ql tests 2024-06-19 09:13:18 +02:00
Edward Minnix III
7adfa6bbed Merge pull request #16709 from egregius313/egregius313/go/df/threat-models/refactor-queries
Go: Refactor queries to use `ThreatModelFlowSource` instead of `RemoteFlowSource`
2024-06-18 13:56:00 -04:00
am0o0
eb1999f8b3 revert .vscode/settings.json :(( 2024-06-18 18:43:20 +02:00
am0o0
ccb923a436 fix formatting 2024-06-18 18:31:29 +02:00
Ed Minnix
5bbd003dfc Reword change note 2024-06-18 12:27:21 -04:00
Ed Minnix
b53712cae0 Change note 2024-06-18 12:27:19 -04:00
Ed Minnix
6a0be6ad09 ExternalAPIs 2024-06-18 12:27:18 -04:00
Ed Minnix
46e16b88bb Refactor experimental queries to use ThreadModelFlowSource 2024-06-18 12:27:17 -04:00
Ed Minnix
cfd5f53eb0 Refactor Customizations libraries to use ThreatModelFlowSource 2024-06-18 12:27:15 -04:00
Edward Minnix III
8997f2cdf2 Merge pull request #16697 from egregius313/egregius313/go/dataflow/threat-modeling
Go: Introduce Threat Modeling
2024-06-18 12:25:33 -04:00
am0o0
1f99559e9f Revert "update id of the query file"
This reverts commit 1f112467ce.
2024-06-18 17:33:07 +02:00
am0o0
cb39ae7dd3 revert .vscode/settings.json 2024-06-18 17:27:15 +02:00
am0o0
8a7fdfa6fe fix conflict 2024-06-18 17:18:59 +02:00
Taus
59a77a873c Merge pull request #16754 from github/tausbn/python-disregard-unused-imports-in-pytest-tests
Python: Disregard unused imports in `pytest` tests
2024-06-18 15:10:31 +02:00
Owen Mansel-Chan
9403bf25d8 Merge pull request #16667 from smowton/smowton/fix/global-variable-side-effect
Add support for flow through content of global variables
2024-06-18 13:41:57 +01:00
Tamas Vajk
6c8e391a63 C#: Make sure no file is added twice to the compilation 2024-06-18 13:45:09 +02:00
Tamas Vajk
5170585515 C#: Add integration test with file added multiple times in the same compilation 2024-06-18 13:45:06 +02:00
Michael Nebel
1c3ceacf04 C#: Some renaming and re-factoring. 2024-06-18 13:05:21 +02:00
Michael Nebel
dfaa40a1d2 C#: Update expected test output from model generation. 2024-06-18 13:05:17 +02:00
Michael Nebel
b5d6a6db7e C#: Use the same types as sanitizers for source and sink model as we use for summary model generation. 2024-06-18 13:05:12 +02:00
Michael Nebel
031e44b157 C#: Add some source/sink model generator test examples. 2024-06-18 13:05:07 +02:00
Max Schaefer
2c4a95bb5e Merge pull request #16777 from github/max-schaefer-patch-1
Swift: Add missing bracket in example
2024-06-18 11:39:42 +01:00
Alex Ford
6c3d90e8a0 Merge pull request #16650 from alexrford/rb/routing-improvements
Ruby: ActionDispatch - support `path => target` route format
2024-06-18 11:17:05 +01:00
Max Schaefer
9ca74de3e9 Swift: Add missing bracket in example 2024-06-18 11:00:59 +01:00
Joe Farebrother
33704779ea Merge pull request #16503 from joefarebrother/ruby-sensitive-sources
Ruby: Use additional sensitive data heuristics for CleartextSources
2024-06-18 10:57:55 +01:00
Michael Nebel
cd9d58fdc8 Merge pull request #16772 from michaelnebel/java/taintedpermissionthreatmodel
Java: Opt-in `java/tainted-permissions-check` to threat models.
2024-06-18 10:54:28 +02:00
Joe Farebrother
eee7f5a896 Use a combined regex for performance 2024-06-17 22:21:33 +01:00
Cornelius Riemenschneider
0f98d9e815 Merge pull request #16774 from github/criemen/cleanup
Remove unused bzl files.
2024-06-17 20:04:25 +02:00
Chris Smowton
4da5d6660a Add change note 2024-06-17 16:49:09 +01:00
Chris Smowton
38ee085782 Adjust test expectation 2024-06-17 16:46:49 +01:00
Chris Smowton
822f6eebfb Add support for flow through content of global variables 2024-06-17 16:42:23 +01:00
Ed Minnix
b4ecc81145 Fix provenance numbers in tests 2024-06-17 11:33:19 -04:00
Ed Minnix
fa2c50616b Remove getSourceType definitions 2024-06-17 10:57:11 -04:00
Ed Minnix
b6adff6377 Fix jsoniter test 2024-06-17 10:51:13 -04:00
Ed Minnix
53dd269f9f Go: Threat model tests 2024-06-17 10:51:11 -04:00
Ed Minnix
7f19f449eb Change note 2024-06-17 10:51:10 -04:00
Ed Minnix
49fb372eb9 Add getSourceType declarations to existing remote flow sources 2024-06-17 10:51:09 -04:00
Ed Minnix
df6449cfc7 Go: Add the SourceNode and ThreatModelFlowSource classes 2024-06-17 10:51:07 -04:00
Ed Minnix
b697068e9a Go: Add threat modeling shared library 2024-06-17 10:51:06 -04:00
Michael Nebel
5686efd25c Update java/ql/src/change-notes/2024-06-17-tainted-permissions-check.md
Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com>
2024-06-17 16:47:22 +02:00
Cornelius Riemenschneider
f41bd41bd0 Remove unused bzl files. 2024-06-17 15:15:08 +02:00
Michael Nebel
197cdab43d Merge pull request #16752 from michaelnebel/shared/sourcesinkcallables
C#/Java: Add some (shared) helper classes for Neutrals, Sources and Sink
2024-06-17 14:58:27 +02:00
Anders Schack-Mulligen
0e8af39b77 Merge pull request #16719 from aschackmull/shared/fix-qldoc
Shared: Fix file-module qldoc.
2024-06-17 13:26:57 +02:00
Anders Schack-Mulligen
96b6ddefe0 Merge pull request #16751 from aschackmull/java/sndlevelscope-fix
Java: Calculate 2nd level scopes for implicit instance accesses.
2024-06-17 13:10:46 +02:00
Michael Nebel
57925373c6 Address review comment. 2024-06-17 13:02:25 +02:00
Michael Nebel
833b4f90bf Java: Make source and sink callable adapters. 2024-06-17 12:53:08 +02:00
Michael Nebel
0fabca94db C#: Use the new shared classes for Source and Sink callables. 2024-06-17 12:53:06 +02:00
Michael Nebel
3d53ddf919 DataFlow: Add some shared classes for Neutrals, Source and Sink callables. 2024-06-17 12:53:03 +02:00
Michael Nebel
e1317ddcb6 Merge pull request #16768 from github/workflow/coverage/update
Update CSV framework coverage reports
2024-06-17 11:51:35 +02:00
Anders Schack-Mulligen
b8b95fd81d Java: Add change note. 2024-06-17 11:46:54 +02:00
Michael Nebel
c3862660e4 Java: Add change note. 2024-06-17 11:07:29 +02:00
Michael Nebel
327dab69d0 Java: Opt-in the tainted permissions check query to threat models. 2024-06-17 11:02:08 +02:00
Jeroen Ketema
1d1a84962b Merge pull request #16765 from jketema/attrib-dup
C++: Add more tests that show we do not properly deduplicate attributes
2024-06-17 07:07:55 +02:00
github-actions[bot]
abe2deb6a6 Add changed framework coverage reports 2024-06-17 00:18:39 +00:00
Andrew Eisenberg
3d3a315456 Merge pull request #16766 from github/aeisenberg/requirements
Add powershell to list of requirements on windows
2024-06-14 15:15:28 -07:00
Andrew Eisenberg
d238b9198d Clarify that this applies to both autobuild and regular builds 2024-06-14 14:41:29 -07:00
Owen Mansel-Chan
b0afba49a2 Merge pull request #16761 from owen-mc/java/reverse-dns-get-loopback-address
Java: Exclude loopback address from reverse DNS source
2024-06-14 22:39:55 +01:00
Andrew Eisenberg
39a8af6519 Add powershell to list of requirements on windows 2024-06-14 14:30:47 -07:00
Jeroen Ketema
14b5114aa6 C++: Add more tests that show we do not properly deduplicate attributes 2024-06-14 17:44:05 +02:00
Jeroen Ketema
c0df22950b Merge pull request #16763 from jketema/attrib-dup
C++: Add test that show that routine attributes are not fully de-duplicated
2024-06-14 17:15:27 +02:00
Taus
b7b0f84e8b Python: Handle @pytest.fixture decorations with arguments as well
Not the prettiest of solutions, but it seems to work well enough.
2024-06-14 15:11:25 +00:00
Taus
c75e66c433 Merge pull request #16762 from github/redsun82/python-disregard-unused-imports-in-pytest-tests
Python: failing unused import test case
2024-06-14 16:57:53 +02:00
Owen Mansel-Chan
9aa0c9f1f3 Fix test expectations 2024-06-14 15:55:30 +01:00
Paolo Tranquilli
1046d03486 Python: update unused import test case for pytest 2024-06-14 16:55:05 +02:00
Jeroen Ketema
7d97463e4d C++: Add test that show that routine attributes are not fully de-duplicated 2024-06-14 16:43:29 +02:00
Ian Lynagh
079717bbc0 Merge pull request #16694 from igfoo/igfoo/PopulationSpecFile
Kotlin: Remove unused PopulationSpecFile
2024-06-14 15:06:39 +01:00
Rasmus Wriedt Larsen
3fc8401370 JS: Add change-note 2024-06-14 15:37:25 +02:00
Rasmus Wriedt Larsen
3f2befc3e5 JS: Support spread arguments in array.splice 2024-06-14 15:33:17 +02:00
Rasmus Wriedt Larsen
269f8ca2cd JS: Add splice(...arr) test 2024-06-14 15:19:56 +02:00
Rasmus Wriedt Larsen
68ccec3d43 JS: Prepare for new test 2024-06-14 15:18:47 +02:00
Taus
2f00a0d323 Python: Also test pytest fixture factories 2024-06-14 13:11:00 +00:00
Owen Mansel-Chan
6cfd9458b0 Add change note 2024-06-14 14:05:25 +01:00
Owen Mansel-Chan
7a13c31021 Exclude loopback address from reverse DNS source 2024-06-14 14:05:01 +01:00
Owen Mansel-Chan
5973f3fadc Add test for reverse DNS from loopback address 2024-06-14 14:04:47 +01:00
Owen Mansel-Chan
098b732937 Fix formatting of inline expectation test comment 2024-06-14 14:04:42 +01:00
Rasmus Wriedt Larsen
194ef607f7 JS: Updated .expected 2024-06-14 14:49:34 +02:00
Taus
78729180ad Python: Fix pytest fixture unused import FPs 2024-06-14 12:05:55 +00:00
Taus
f3a9c9a9dc Python: Add tests for pytest fixture unused import FPs 2024-06-14 12:03:43 +00:00
am0o0
4e1f7a930d fix invalid js file sample in qlhelp 2024-06-14 13:47:01 +02:00
Paolo Tranquilli
e2a47e7c18 Merge pull request #16720 from github/redsun82/kotlin
Kotlin: cleanup after internal changes
2024-06-14 13:28:22 +02:00
Cornelius Riemenschneider
c808953b1d Merge pull request #16723 from github/criemen/codeql-pack-group
`pkg.bzl`: Significantly restructure `codeql_pack` rule.
2024-06-14 13:19:00 +02:00
Michael Nebel
3525967143 Merge pull request #16701 from michaelnebel/csharp/modelgentaintmembers
C#/Java: Improve Sink and Summary model generation.
2024-06-14 12:30:50 +02:00
Tom Hvitved
c7b4f51077 Merge pull request #16758 from hvitved/ruby/shared-ci-trigger
Ruby: Trigger `ruby-build.yml` on changes to shared extractor
2024-06-14 12:00:18 +02:00
Michael B. Gale
039537f7ba Merge pull request #16727 from github/mbg/go/fix/too-many-go-mod-files-initialised 2024-06-14 10:14:57 +01:00
Tom Hvitved
be66ea2178 Ruby: Trigger ruby-build.yml on changes to shared extractor 2024-06-14 11:09:03 +02:00
Michael Nebel
a29446a566 C#/Java: Address review comments. 2024-06-14 10:46:19 +02:00
Cornelius Riemenschneider
58f69c9385 Make CodeQLPackInfo provider public. 2024-06-13 21:57:46 +02:00
Cornelius Riemenschneider
02100e58d9 Address review. 2024-06-13 21:55:56 +02:00
Cornelius Riemenschneider
ede0b5bdf4 Merge remote-tracking branch 'origin/main' into criemen/codeql-pack-group 2024-06-13 21:53:31 +02:00
Paolo Tranquilli
f9db7864e1 Change note: reword 2024-06-13 18:04:23 +02:00
Paolo Tranquilli
0198806658 Merge branch 'main' into redsun82/kotlin 2024-06-13 16:29:13 +02:00
am0o0
bb03a9faba format the query file 2024-06-13 14:54:29 +02:00
am0o0
f0a467e80b update tests 2024-06-13 14:52:22 +02:00
am0o0
84b9d4d1ac fix qlhelp errors 2024-06-13 14:32:41 +02:00
Mathias Vorreiter Pedersen
3d037e73f0 Merge pull request #16749 from MathiasVP/fix-fps-on-double-free
C++: Fix `ArrayExpr` FPs in `cpp/double-free`
2024-06-13 12:58:41 +01:00
Paolo Tranquilli
b8de2ea03b Merge pull request #16731 from github/redsun82/kotlin-fix-version-picker
Kotlin: expose kotlin version picker for internal packaging
2024-06-13 13:57:38 +02:00
Anders Schack-Mulligen
b47831af14 Java: Calculate 2nd level scopes for implicit instance accesses. 2024-06-13 13:57:18 +02:00
Michael B. Gale
1834a399d2 Merge pull request #16738 from github/mbg/go/remove-go-work
Go: Remove `go.work` file
2024-06-13 12:20:12 +01:00
Mathias Vorreiter Pedersen
4bbeda08d6 C++: Fix change note naming. 2024-06-13 11:10:00 +01:00
Mathias Vorreiter Pedersen
83108e3e25 C++: Add change note. 2024-06-13 11:03:52 +01:00
Mathias Vorreiter Pedersen
bcabc88649 C++: Accept test changes. 2024-06-13 10:59:46 +01:00
Mathias Vorreiter Pedersen
4079de125f C++: Fix FP by also excluding indirections of array expressions. 2024-06-13 10:59:39 +01:00
Mathias Vorreiter Pedersen
eec259279a C++: Add another FP test. We already have tests for this, but it doesn't hurt to have another one, I guess. 2024-06-13 10:57:49 +01:00
Mathias Vorreiter Pedersen
e244eef3b5 Merge pull request #16748 from MathiasVP/rc-3.14-mergeback-2
Mergeback from `rc/3.14`
2024-06-13 10:44:46 +01:00
Michael Nebel
7f7c5d7c94 Java: Update model generator expected test output. 2024-06-13 10:57:15 +02:00
Michael Nebel
e247d5b316 Java: Sync files and make dummy language specific implementation. 2024-06-13 10:55:17 +02:00
Michael Nebel
e56c185f32 Java: Add some model generator sink examples. 2024-06-13 10:49:57 +02:00
Mathias Vorreiter Pedersen
0150269503 Merge branch 'rc/3.14' into rc-3.14-mergeback-2 2024-06-13 09:14:40 +01:00
Mathias Vorreiter Pedersen
9384f6189e Merge pull request #16740 from MathiasVP/fix-join-in-ssa
SSA: Fix bad join in `lastRefRedefExt`
2024-06-13 09:06:20 +01:00
Paolo Tranquilli
11c37734c3 Kotlin: add change note for having fixed kotlin QL tests in release 2024-06-13 09:49:39 +02:00
Michael Nebel
854c6fa813 C#: Update expected test output after .NET 8 models update. 2024-06-13 09:24:13 +02:00
Michael Nebel
9ea2b463f0 C#: Update .NET 8 Runtime models. 2024-06-13 08:36:23 +02:00
Michael Nebel
78d23ee044 C#/Java: Allow the model generator to use 32GB of ram. 2024-06-13 08:35:52 +02:00
Maiky
8ba7ac678d Update javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfigurationCustomizations.qll
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2024-06-12 19:38:13 +02:00
Maiky
4be5cf4e78 Update javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfigurationCustomizations.qll
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2024-06-12 19:38:02 +02:00
Rasmus Wriedt Larsen
ec18786488 JS: Provide better model for Array.splice 2024-06-12 16:29:21 +02:00
Mathias Vorreiter Pedersen
5b3403c4b1 C++: Fix bad join in 'lastRefRedefExt'. 2024-06-12 15:24:58 +01:00
Michael B. Gale
e10e2899bd Go: Update comment in gen.py 2024-06-12 15:24:33 +01:00
Rasmus Wriedt Larsen
54a0e6dc45 JS: Add new test for Array.splice 2024-06-12 16:24:33 +02:00
Michael B. Gale
8629e00686 Go: Remove workspace from vendor/modules.txt 2024-06-12 15:22:56 +01:00
Rasmus Wriedt Larsen
9ed6da1072 JS: prepare to extend Array tests
Oh how I have enjoyed working with InlineExpectationTests for these sort
of things, not worrying about all the .expected files changing because
you add a few lines in the middle of your tests :D
2024-06-12 16:22:55 +02:00
Michael B. Gale
a90968d277 Go: Replace go work vendor with go mod vendor 2024-06-12 15:19:14 +01:00
Rasmus Wriedt Larsen
1027ca266d JS: Allow many Array steps to be used in type-tracking 2024-06-12 16:14:13 +02:00
Joe Farebrother
90d6f2ece3 Factor out nameIndicatesRelevantSensitiveData 2024-06-12 15:11:47 +01:00
Tom Hvitved
605fe54a06 Ruby: Remove two Cartesian products 2024-06-12 15:11:43 +01:00
Joe Farebrother
5f08371f19 Add change note 2024-06-12 15:11:39 +01:00
Joe Farebrother
07f03be8cc Add unit tests 2024-06-12 15:11:35 +01:00
Joe Farebrother
b0c03f6d68 Allow implicit read steps on sinks 2024-06-12 15:11:32 +01:00
Joe Farebrother
8b51ee8fe8 Use additional sensitive data heuristics in CleartextSources 2024-06-12 15:11:27 +01:00
Michael B. Gale
a04f08f026 Go: Remove go.work file 2024-06-12 15:10:28 +01:00
Tamás Vajk
a756f86847 Merge pull request #16732 from tamasvajk/refactor/extraction-states
C#: Refactor extractor state classes and simplify extraction code
2024-06-12 15:20:11 +02:00
Tamas Vajk
0df6a1c4b1 Fix quality issues 2024-06-12 14:48:16 +02:00
Michael Nebel
48739da565 C#: Update expected test output. 2024-06-12 14:16:31 +02:00
Michael Nebel
91ebeee429 C#: Perceive field and property reads as additional flow steps in sink extrapolation. 2024-06-12 14:16:26 +02:00
Michael Nebel
5aee35256d C#: Add member flow example. 2024-06-12 14:16:22 +02:00
Michael Nebel
4b62cb64ed C#: Update expected test output. 2024-06-12 14:16:17 +02:00
Michael Nebel
0bbf131fdb C#: Add some compound sink examples. 2024-06-12 14:16:12 +02:00
Kasper Svendsen
7c2ee80bc3 Document builtin InternSets module 2024-06-12 13:56:48 +02:00
Tamas Vajk
e3cbf1479a Fix quality issue 2024-06-12 13:25:34 +02:00
Arthur Baars
4ee80653e2 Merge pull request #16471 from Sim4n6/ruby-UBV
Ruby: Add some method calls as a Source
2024-06-12 12:42:08 +02:00
Tamas Vajk
3551386a1a Simplify standalone extractor 2024-06-12 12:30:08 +02:00
Owen Mansel-Chan
6af1ed9d75 Merge pull request #16730 from github/workflow/coverage/update
Update CSV framework coverage reports
2024-06-12 11:22:29 +01:00
Tamas Vajk
cdca607828 Rename Extractor to ExtractionContext 2024-06-12 11:43:19 +02:00
Tamas Vajk
af2a78ea4d Reduce references to Extract class 2024-06-12 11:13:05 +02:00
Paolo Tranquilli
183a825841 Kotlin: expose kotlin version picker for internal packaging 2024-06-12 09:29:57 +02:00
github-actions[bot]
bbeebfae73 Add changed framework coverage reports 2024-06-12 00:17:31 +00:00
Joe Farebrother
f441c68f7e Merge pull request #16657 from joefarebrother/python-partial-ssrf-fp
Python: Add additional sanitizers to SSRF
2024-06-11 23:20:50 +01:00
Mauro Baluda
1db5e32e86 Extract SAP XSJS file types as Javascript 2024-06-11 23:53:41 +02:00
Mauro Baluda
45a48f360f Extract SAP XSJS file types as Javascript 2024-06-11 23:51:44 +02:00
Michael B. Gale
e9bd85e0ba Merge pull request #16704 from github/mbg/go/fix/build-scripts-running-more-than-once 2024-06-11 22:23:15 +01:00
Michael B. Gale
202d77d94f Merge pull request #16726 from github/mbg/go/log-one-line-for-stray-sources
Go: Only log one line for stray .go files
2024-06-11 22:16:21 +01:00
Owen Mansel-Chan
24c9062b35 Merge pull request #16671 from owen-mc/go/mad-builtin-taint-models-try-2
Go: Convert old-style models for built-ins to MaD
2024-06-11 19:45:34 +01:00
Michael B. Gale
d8d1ae632c Merge branch 'mbg/go/fix/build-scripts-running-more-than-once' into mbg/go/fix/too-many-go-mod-files-initialised 2024-06-11 18:31:03 +01:00
Michael B. Gale
0f56e408f8 Merge branch 'main' into mbg/go/fix/build-scripts-running-more-than-once 2024-06-11 18:29:41 +01:00
Michael B. Gale
864d629a13 Go: Prevent go.mod files from being added to every directory with stray source files 2024-06-11 18:24:11 +01:00
Michael B. Gale
20b7def543 Go: Only log one line for stray .go files 2024-06-11 18:06:08 +01:00
Geoffrey White
cf4736c8f6 Merge pull request #16545 from geoffw0/salvage
Swift: Salvage
2024-06-11 17:51:17 +01:00
Mathias Vorreiter Pedersen
67b327a0f7 Merge pull request #16725 from MathiasVP/rc-3.14-mergeback
Mergeback from `rc/3.14`
2024-06-11 17:37:40 +01:00
Tony Torralba
a299afaf51 Merge pull request #16712 from mbaluda/main
Java: Add `FileUtils` sinks to path injection
2024-06-11 17:50:08 +02:00
Paolo Tranquilli
3d3652c63f Merge branch 'main' into redsun82/kotlin 2024-06-11 17:25:10 +02:00
Cornelius Riemenschneider
92957a63ad Add prefix feature to codeql_pack_group.
Turns out we need this for our production targets.
2024-06-11 17:22:35 +02:00
Mathias Vorreiter Pedersen
3351b9547d Merge branch 'rc/3.14' into rc-3.14-mergeback 2024-06-11 16:21:08 +01:00
Owen Mansel-Chan
2ae7fa4897 Tests: accept expected changes 2024-06-11 16:20:06 +01:00
Owen Mansel-Chan
6fd2ab7cef Tests: Accept model renumbering in edge provenance 2024-06-11 16:18:18 +01:00
Mathias Vorreiter Pedersen
b88a1b2d1e Merge pull request #16724 from MathiasVP/cache-asexpr
C++: Cache `asExpr` (and `asIndirectExpr`) implementation predicates
2024-06-11 16:17:29 +01:00
Owen Mansel-Chan
700604a1c2 Convert old-style models for built-ins to MaD
These models are to cover the special cases where `append` can be used
with a second argument which is a string followed by `...`, and `copy`
can be used with a second argument which is a string. In this case the
taint is carried by the whole string, rather than in array elements.
2024-06-11 16:16:45 +01:00
Joe Farebrother
93f10fcf14 Add sanitizers for compiled regexes 2024-06-11 15:44:16 +01:00
Mathias Vorreiter Pedersen
6a6978398a C++: Add file QLDoc. 2024-06-11 15:39:45 +01:00
Mathias Vorreiter Pedersen
333df03f64 C++: Cache more things. 2024-06-11 15:39:43 +01:00
Mauro Baluda
a464a8e48e @mbaluda
Update provenance in test expectations
2024-06-11 15:15:50 +02:00
Tamas Vajk
11faf08ed0 Remove specific standalone/tracing extractor state classes 2024-06-11 14:16:35 +02:00
Geoffrey White
214db5c20d Swift: Make CI more happy. 2024-06-11 12:49:58 +01:00
Cornelius Riemenschneider
3cf719cb39 pkg.bzl: Significantly restructure codeql_pack rule.
This PR introduces a `codeql_pack_rule` that does the heavy lifting
of extracting arch- and common zip files for production dist building.
It also factors out the installer targets for individual packs,
as well as pack groups.

This changes the contract between the internal build system and the pack
definition significantly, which is why an accompanying internal PR is required.
No backwards compatibility layer is provided, as the PR as complex enough as-is.

The individual `codeql_pack` rules are now much simpler,
as they mostly stuff their inputs into a new `_CodeQLPackInfo` provider,
and let the installer and `codeql_pack_group` rules do the heavy lifting.
For working in the external repo with self-contained packs,
the per-pack installer targets are still available.
Internally, we'll only use the new `codeql_pack_group` targets
going forward, both for defining intree-dists and for building
the production zip files.
2024-06-11 13:15:05 +02:00
Cornelius Riemenschneider
3574b9fd4f Merge pull request #16716 from github/criemen/rust-bzlmod-new
Rust: Move to bzlmod.
2024-06-11 13:13:16 +02:00
Mauro Baluda
29e3816412 Apply suggestions from code review
Address reviewiew comments

Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2024-06-11 12:05:14 +02:00
Paolo Tranquilli
01416838a1 Merge branch 'main' into redsun82/kotlin 2024-06-11 11:57:19 +02:00
Cornelius Riemenschneider
4226270ef9 Merge branch 'main' into criemen/rust-bzlmod-new 2024-06-11 11:40:40 +02:00
Anders Schack-Mulligen
73caa48302 Merge pull request #16721 from aschackmull/dataflow/remove-unused-import
Dataflow: Remove unused import.
2024-06-11 09:54:05 +02:00
Chris Smowton
3172054073 Merge pull request #16717 from github/post-release-prep/codeql-cli-2.17.5
Post-release preparation for codeql-cli-2.17.5
2024-06-11 07:56:55 +01:00
Anders Schack-Mulligen
939ae4a561 Dataflow: Remove unused import. 2024-06-11 08:55:44 +02:00
Paolo Tranquilli
90db894d01 Kotlin: remove obsolete scripts and reword comments 2024-06-11 08:52:26 +02:00
Anders Schack-Mulligen
87316784ad Shared: Fix file-module qldoc. 2024-06-11 08:49:15 +02:00
Mauro Baluda
bb5ef3ccd9 Update provenance in test expectations 2024-06-10 19:57:37 +02:00
Mauro Baluda
e9dba59f11 Merge branch 'main' into main 2024-06-10 19:57:00 +02:00
Geoffrey White
ae0bf037ac Swift: Make CI happy. 2024-06-10 18:54:16 +01:00
Geoffrey White
2f33b9422b Merge branch 'main' into salvage 2024-06-10 18:31:46 +01:00
Geoffrey White
83860acdde Swift: Test BuiltinLiteralExpr. 2024-06-10 18:20:25 +01:00
Geoffrey White
f2b1e09650 Swift: Add some conversion test cases. 2024-06-10 17:25:25 +01:00
Michael B. Gale
317790eac3 Merge pull request #16703 from github/mbg/go/improve-version-selection-v2
Go: Use toolchain directives for version selection if available, and add tests (v2)
2024-06-10 16:03:00 +00:00
Mathias Vorreiter Pedersen
ec34007a88 Merge pull request #16714 from MathiasVP/handle-unlikely-in-guards-2
C++: Support `__builtin_expect` in `IRGuards`
2024-06-10 16:54:01 +01:00
github-actions[bot]
8a25081a0e Post-release preparation for codeql-cli-2.17.5 2024-06-10 15:33:08 +00:00
Tony Torralba
7336dd1ae5 Merge pull request #16482 from grakshith/rakshith/tune-java-crypto
Java: Add RSA/ECB/OEAP ciphers to the list of secure algorithms
2024-06-10 17:27:35 +02:00
Cornelius Riemenschneider
496fff4273 C#: Remove empty glob pattern. 2024-06-10 17:04:00 +02:00
Cornelius Riemenschneider
00319c5010 Upgrade bazel to 7.2.0.
This also bumps a bunch of external dependencies.
2024-06-10 17:03:59 +02:00
Cornelius Riemenschneider
092bc6445d Rust/bazel: Port to bzlmod.
This gets rid of our last workspace dependency.
In particular, this change also gets rid of the checked-in extra
lock files that took forever to generate.
2024-06-10 17:03:58 +02:00
Michael B. Gale
d4adc373c6 Replace if with else if in RequiredGoVersion 2024-06-10 15:48:29 +01:00
Chris Smowton
a160b891c8 Merge pull request #16715 from github/release-prep/2.17.5
Release preparation for version 2.17.5
2024-06-10 14:46:30 +01:00
github-actions[bot]
877bfa2468 Release preparation for version 2.17.5 2024-06-10 13:40:39 +00:00
Mathias Vorreiter Pedersen
c3bba38950 C++: Fix QLDoc. 2024-06-10 13:39:34 +01:00
Cornelius Riemenschneider
7ecf1f9010 Merge pull request #16713 from github/criemen/csharp-version-fallback
C#: Add fallback for branch detection.
2024-06-10 14:24:37 +02:00
Mathias Vorreiter Pedersen
1aea120e89 C++: Add change note. 2024-06-10 13:01:01 +01:00
Mathias Vorreiter Pedersen
b0c4fcec57 C++: Cleanup. 2024-06-10 12:53:07 +01:00
Mathias Vorreiter Pedersen
9e088f3e4a C++: Accept test changes. 2024-06-10 12:53:06 +01:00
Mathias Vorreiter Pedersen
84c1341b62 C++: Support builtin expect in IRGuards. 2024-06-10 12:53:04 +01:00
Mathias Vorreiter Pedersen
d76700497b C++: Add testcases using the builtin expect operation. 2024-06-10 12:47:45 +01:00
Mathias Vorreiter Pedersen
9c98652116 C++: Handle 'unlikely' in IRGuards. 2024-06-10 12:47:44 +01:00
Jeroen Ketema
000a81fd29 Merge pull request #16690 from MathiasVP/better-guards
C++: Fix missing results for `comparesEq` in `IRGuardCondition`
2024-06-10 13:32:10 +02:00
Sim4n6
7c0ce6486b Rerun the test learn 2024-06-10 12:21:10 +01:00
Cornelius Riemenschneider
027c7d0d43 C#: Add fallback for branch detection.
Apparently, when building a release build, we're getting `no-git`
as first part o the version string for the submodule.
If we do, fall back to the internal repo's branch name.
For releases, that's the same anyways.
Luckily, the commit SHA is correct.
2024-06-10 12:14:03 +02:00
Mauro Baluda
1d44f45be2 Update org.apache.commons.io.model.yml 2024-06-10 12:03:57 +02:00
Mathias Vorreiter Pedersen
7819cc1c36 C++: Add more QLDoc. 2024-06-10 10:58:52 +01:00
Mauro Baluda
71505f4003 Added more org.apache.commons.io.FileUtils-related sinks to the path injection query. 2024-06-10 11:29:51 +02:00
Tamás Vajk
06aa2664bf Merge pull request #16705 from tamasvajk/build/fix-attributes
C#: Add assembly attributes to assemblies built with Bazel
2024-06-10 09:26:31 +02:00
am0o0
9db334d02f update select statement, update test cases 2024-06-07 21:26:20 +02:00
am0o0
2c9340331d update test cases expected results 2024-06-07 21:16:31 +02:00
am0o0
5e0a78c4c7 make predicate for env key and value nodes, use propertyRead/Write instead of API nodes to find env key and value assignments, fix a bug thanks to @erik-krogh 2024-06-07 21:15:30 +02:00
Michael B. Gale
e7a60b72f1 Go: Check dependencies per workspace 2024-06-07 16:22:41 +00:00
Michael B. Gale
b9586a81ef Go: Add functions for constructing go list commands 2024-06-07 16:22:40 +00:00
Michael B. Gale
6c0c3365cf Go: Fix vendor issues and go.sum files in separate loop 2024-06-07 16:22:39 +00:00
Michael B. Gale
d344f720aa Go: Add methods to GoModule for the tidy and vendor commands
These ensure that the module path is used automatically
2024-06-07 16:22:37 +00:00
Tamas Vajk
5f98f2aec9 Add assembly attributes to bazel build script 2024-06-07 15:42:12 +02:00
Cornelius Riemenschneider
6731bccc92 C#: Provide skeleton to generate an assemblyInfo file.
Each unit gets a unique assemblyInfo file, on top
of the ones for entrypoints that also gets the git info embedded.
2024-06-07 15:24:53 +02:00
Tamas Vajk
16f8be4ba4 C#: Add product name to assemblies 2024-06-07 15:24:21 +02:00
Tamas Vajk
beffc2a49d C#: Remove unneeded source folder from Bazel build scripts 2024-06-07 15:23:45 +02:00
Anders Schack-Mulligen
32260e2823 Merge pull request #16210 from aschackmull/dataflow/provenance-for-tests
Dataflow: Add support for pretty-printed alert provenance in tests
2024-06-07 14:53:56 +02:00
Michael B. Gale
881b2586e1 Go: Add tests for RequiredGoVersion 2024-06-07 12:20:44 +00:00
Michael B. Gale
504a233299 Go: Use Toolchain directives in go.mod files, if available 2024-06-07 12:20:43 +00:00
Michael B. Gale
1d6f09c750 Go: Refactor go.mod version retrieval into its own method 2024-06-07 12:20:42 +00:00
Michael B. Gale
44a16cef6c Go: Use Toolchain directives in go.work files, if available 2024-06-07 12:20:41 +00:00
Michael B. Gale
ea3a3db847 Merge pull request #16460 from github/mbg/go/semver-type
Go: Use new type for all semantic versions
2024-06-07 12:19:12 +00:00
Michael B. Gale
9d1c2c6ba1 Merge branch 'main' into mbg/go/semver-type 2024-06-07 12:09:10 +00:00
Anders Schack-Mulligen
9b1e4d7895 Go: Fix test failure. 2024-06-07 13:16:20 +02:00
Pierre
0ab67d1790 Merge pull request #16684 from github/sitedocs/2.17.4
Add changelog for 2.17.4
2024-06-07 02:50:38 -07:00
Anders Schack-Mulligen
7e980d9524 Add a bit more qldoc. 2024-06-07 11:47:50 +02:00
Anders Schack-Mulligen
0c47203580 Javascript: Add support for pretty-printed provenace in tests. 2024-06-07 11:47:49 +02:00
Anders Schack-Mulligen
68ddae2918 Python: Add support for pretty-printed provenace in tests. 2024-06-07 11:47:48 +02:00
Anders Schack-Mulligen
5d51b5b97b Ruby: Add support for pretty-printed provenace in tests. Convert one test. 2024-06-07 11:47:48 +02:00
Anders Schack-Mulligen
a26c01d7c7 Go: Add support for pretty-printed provenace in tests. Convert one test. 2024-06-07 11:47:45 +02:00
Anders Schack-Mulligen
0e8d72c126 C#: Add support for pretty-printed provenace in tests. Convert one test. 2024-06-07 11:45:16 +02:00
Anders Schack-Mulligen
4ec4da4c8c Dataflow/Java: Add support for pretty-printed provenace in tests. Convert one test. 2024-06-07 11:45:13 +02:00
Tamás Vajk
68a78fa3ed Merge pull request #16700 from tamasvajk/buildless/tsp-warning-config
C#: Add TSP warning if `buildless` option is used instead of `build-mode`
2024-06-07 11:07:16 +02:00
Michael Nebel
d5af71a6c9 Merge pull request #16647 from michaelnebel/csharp/idempotentsummarygeneration
C#: Make summary generation idempotent.
2024-06-07 10:38:25 +02:00
Tamas Vajk
9366eb8288 C#: Add TSP warning if buildless option is used instead of build-mode 2024-06-07 10:33:13 +02:00
Mathias Vorreiter Pedersen
7f62085be5 C++: Delete unused predicate. 2024-06-07 09:13:29 +01:00
Jeroen Ketema
456c046b09 Merge pull request #16693 from jketema/func-fix
C++: Correctly identify orphaned variables as static
2024-06-07 07:54:11 +02:00
am0o0
1033bf9c4c remove unused imports from javascript test cases 2024-06-07 06:04:12 +02:00
am0o0
b9e3b3310e update the remote flow based query thanks to @erik-krogh, update tests and separate the local and remote query tests 2024-06-07 06:01:49 +02:00
Ian Lynagh
97cb0c89c8 Kotlin: Remove unused PopulationSpecFile 2024-06-06 21:14:28 +01:00
Mathias Vorreiter Pedersen
ed525fce70 C++: Accept test changes. 2024-06-06 20:38:31 +01:00
Mathias Vorreiter Pedersen
b5a3575130 C++: Make proper use of barrier guards in test. 2024-06-06 20:38:17 +01:00
Jeroen Ketema
4488518838 C++: Update expected test results 2024-06-06 21:12:34 +02:00
Jeroen Ketema
5ae8fe502a C++: Correctly identify orphaned variables as static 2024-06-06 20:35:26 +02:00
Jeroen Ketema
798357ffc6 C++: Add test case that shows that __func__ is not considered static 2024-06-06 20:31:45 +02:00
Mathias Vorreiter Pedersen
7b92554cf2 Merge branch 'main' into better-guards 2024-06-06 19:22:10 +01:00
Mathias Vorreiter Pedersen
9f4c1380e5 Merge pull request #16677 from MathiasVP/phi-input-nodes
C++: Extend barrier guards to handle phi inputs
2024-06-06 19:21:30 +01:00
Michael B. Gale
2662808629 Go: Output setup-go compatible pre-release identifiers 2024-06-06 17:14:45 +00:00
Mathias Vorreiter Pedersen
9564ae1ca4 C++: Accept more test changes. 2024-06-06 17:04:48 +01:00
Tom Hvitved
eae6406629 Merge pull request #16687 from hvitved/ruby/bump-ts-grammar
Ruby: Bump tree-sitter grammar
2024-06-06 17:44:18 +02:00
Mathias Vorreiter Pedersen
528afba919 C++: Accept test changes. 2024-06-06 16:32:29 +01:00
Mathias Vorreiter Pedersen
36aac3ffd8 C++: Get rid of 'relevantUnaryComparison' since it was excluding too much. The performance is most likely fine with that restriction. 2024-06-06 16:32:16 +01:00
Mathias Vorreiter Pedersen
703832f5a1 C++: Remove a column from a few predicates. 2024-06-06 16:30:32 +01:00
Mathias Vorreiter Pedersen
0298755975 C++: Add a test. 2024-06-06 16:22:23 +01:00
Mathias Vorreiter Pedersen
8aaa2a1079 C++: Improve comment. 2024-06-06 15:58:52 +01:00
Mathias Vorreiter Pedersen
f7b2d98c6e C++: Add tests to demonstrate that it's not barrier guard that's buggy. Rather, it's the GuardCondition library. 2024-06-06 15:35:16 +01:00
Mathias Vorreiter Pedersen
fa09d21c32 C++: Simplify. No need for the 'PhiInputNodeExt' class. 2024-06-06 15:33:38 +01:00
Asger F
6e0f3df573 Merge pull request #14120 from asgerf/dynamic/typemodel-istypeused
Dynamic: add TypeModel.isTypeUsed
2024-06-06 15:31:16 +02:00
Mathias Vorreiter Pedersen
5deb9002bf Merge pull request #16665 from geoffw0/yml
C++: Support for extension models (.yml)
2024-06-06 14:21:42 +01:00
Geoffrey White
8acb11924d C++: Remove redundant import. 2024-06-06 13:39:10 +01:00
Mathias Vorreiter Pedersen
314eb5db72 Merge pull request #16688 from MathiasVP/flow-through-builtin-bit-cast
C++: Fix IR generation for builtins and add flow through `__builtin_bit_cast`
2024-06-06 13:28:41 +01:00
Geoffrey White
38acfcf42e C++: Doc tweaks addressing review comments. 2024-06-06 13:11:57 +01:00
am0o0
12df7dee17 Merge branch 'amammad-js-JWT' of https://github.com/amammad/codeql into amammad-js-JWT 2024-06-06 14:04:46 +02:00
Am
af016f9416 Merge branch 'github:main' into amammad-js-JWT 2024-06-06 15:33:26 +03:30
am0o0
8258e377dd use PascalCase for URLConstructorLabel 2024-06-06 14:00:56 +02:00
am0o0
d27a378008 change query-id to avoid duplicate ids 2024-06-06 13:59:58 +02:00
Geoffrey White
7aec488d8a C++: Permit ':' in models-as-data namespaces. 2024-06-06 12:53:42 +01:00
Geoffrey White
894497218d Shared: Recognize 'remote-sink' in ModelValidation.qll. 2024-06-06 12:49:13 +01:00
Geoffrey White
f9ef72eca6 C++: Fix typos. 2024-06-06 12:31:44 +01:00
Tom Hvitved
331f676832 Merge pull request #16523 from microsoft/jb1/chanely-insecure-sql-connection
Adding case to InsecureSQLConnection.ql when Encrypt set in initializer
2024-06-06 12:58:14 +02:00
Mathias Vorreiter Pedersen
31bc4263e7 C++: Fix QLDoc. 2024-06-06 10:52:37 +01:00
Paolo Tranquilli
ac6cc38b20 Merge pull request #16681 from github/redsun82/ripunzip
Ripunzip: provide installer
2024-06-06 11:52:04 +02:00
Paolo Tranquilli
2d42ea0f2f Merge pull request #16668 from github/criemen/pkg-js-fixup
JS: Use `resources/tools` from external repo, not internal.
2024-06-06 11:50:54 +02:00
Mathias Vorreiter Pedersen
bd9ece0bd3 C++: Add dataflow through '__builtin_bit_cast'. 2024-06-06 10:00:18 +01:00
Mathias Vorreiter Pedersen
48f2fd0460 C++: Accept IR changes. 2024-06-06 09:52:35 +01:00
Mathias Vorreiter Pedersen
d6352b47a1 C++: Fix IR generation for builtin operations. 2024-06-06 09:52:20 +01:00
Mathias Vorreiter Pedersen
f58757ff9d C++: Skip children we cannot translate when translating builtin operations. 2024-06-06 09:48:41 +01:00
Mathias Vorreiter Pedersen
af4d2f1ed3 C++: Add an IR test. 2024-06-06 09:48:03 +01:00
Tom Hvitved
523139259a Ruby: Update cargo-bazel-lock.json 2024-06-06 10:46:01 +02:00
Tom Hvitved
7122db0c45 Ruby: Bump tree-sitter grammar 2024-06-06 10:31:16 +02:00
Tom Hvitved
421c68a263 Merge pull request #16663 from hvitved/ruby/extraction-error-consistency
Ruby: Add consistency query for extraction errors
2024-06-06 10:29:56 +02:00
Tamás Vajk
0f09198bcd Merge pull request #16673 from tamasvajk/fix/logger-disposal
C#: Fix erroneous logger disposal
2024-06-06 09:13:27 +02:00
Sim4n6
dabc33bf66 simplify UnicodeBypassValidationQuery code 2024-06-05 22:45:49 +01:00
Erik Krogh Kristensen
2e5d9c34bf Merge pull request #16675 from mbaluda/main
Extract .xsaccess files as JSON
2024-06-05 20:19:40 +02:00
Chanel
7b5297b882 Merge branch 'main' into jb1/chanely-insecure-sql-connection 2024-06-05 09:02:13 -07:00
Chanel Young
716e2737d1 formatting 2024-06-05 09:01:10 -07:00
Owen Mansel-Chan
ef2f01613c Merge pull request #16676 from owen-mc/qldoc-external-flow
C/C#/Java/Swift: Cover all params in QLDoc of `modelCoverage`
2024-06-05 16:53:27 +01:00
Ian Lynagh
ac91a5167a Merge pull request #16682 from igfoo/igfoo/integ
Java integration tests: accept new output
2024-06-05 16:48:18 +01:00
Chris Smowton
e704bf353b Merge pull request #16685 from smowton/smowton/admin/ecj-change-note
Java: Add change note documenting ECJ improvements
2024-06-05 16:39:20 +01:00
Owen Mansel-Chan
3b51f1f722 Merge pull request #16683 from owen-mc/go/refactor-extractor
Go: Refactor findMethodWithGivenReceiver
2024-06-05 16:31:44 +01:00
Chris Smowton
79ae522349 Add change note documenting ECJ improvements 2024-06-05 15:12:33 +01:00
Michael B. Gale
c0142c1a91 Go: Add comment explaining why NewSemVer does not Canonicalise the result 2024-06-05 14:08:45 +00:00
Michael B. Gale
f830dc6852 Merge branch 'main' into mbg/go/semver-type 2024-06-05 13:59:20 +00:00
Owen Mansel-Chan
fcf06c59aa Refactor findMethodWithGivenReceiver 2024-06-05 14:52:31 +01:00
Chris Smowton
e267031f59 Merge pull request #16680 from smowton/smowton/admin/add-ecj-tests
Java: add basic ECJ integration tests
2024-06-05 14:33:36 +01:00
Ian Lynagh
13dd87f04c Java integration tests: accept new output
This means the expected output is in the order that the new test driver
creates it in, which means future diffs will be smaller.
2024-06-05 14:14:44 +01:00
Paolo Tranquilli
61847bc58b Ripunzip: provide installer 2024-06-05 14:46:59 +02:00
Michael B. Gale
5dd7e136e5 Merge branch 'main' into mbg/go/semver-type 2024-06-05 12:22:16 +00:00
Sim4n6
7dcbbbac91 Refactor UnicodeBypassValidationQuery to remove unnecessary code 2024-06-05 13:05:34 +01:00
Chris Smowton
54347c2642 Java: add basic ECJ integration tests 2024-06-05 12:49:25 +01:00
Mathias Vorreiter Pedersen
97f0c759c0 C++: Accept test changes. 2024-06-05 09:58:47 +01:00
Mathias Vorreiter Pedersen
44cc19cd6b C++: Handle phi inputs in barrier guards logic. 2024-06-05 09:58:45 +01:00
Mathias Vorreiter Pedersen
05d46a6793 C++: Also ignore phi input edges in 'AllocaInLoop.ql'. 2024-06-05 09:58:44 +01:00
Mathias Vorreiter Pedersen
0149fb640d C++: Simplify. 2024-06-05 09:58:43 +01:00
Mathias Vorreiter Pedersen
25179074c1 C++: Better toString on phi nodes. 2024-06-05 09:58:41 +01:00
Mathias Vorreiter Pedersen
85d0efcbed C++: Make the last use of a node before entering the phi node map to a phi input dataflow node. 2024-06-05 09:58:40 +01:00
Owen Mansel-Chan
6b2e86afea Accept review suggestion 2024-06-05 07:34:46 +01:00
Mauro Baluda
cc0271715b Merge branch 'main' into main 2024-06-04 23:27:10 +02:00
Mauro Baluda
0b9bafc9c3 Update AutoBuildTests.java 2024-06-04 21:07:57 +02:00
Mauro Baluda
168cba86c1 Add .xsaccess test data 2024-06-04 20:55:07 +02:00
Rakshith Gopalakrishna
798a736d16 fix: update changelog
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2024-06-04 11:20:05 -07:00
Rakshith Gopalakrishna
65af2556ed fix: remove rsa/ecb/* from getASecureAlgorithmName
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2024-06-04 11:20:05 -07:00
Rakshith Gopala krishna
97f9a882c6 fix: address PR comments 2024-06-04 11:20:05 -07:00
Rakshith Gopala krishna
0f63f0dda2 docs: add changenote 2024-06-04 11:20:05 -07:00
Rakshith Gopala krishna
80bf7cdb52 fix: remove the pkcs1 scheme 2024-06-04 11:20:05 -07:00
Rakshith Gopala krishna
dd223ed704 feat: add rsa/ecb/... variants to the list of secure algorithms 2024-06-04 11:20:05 -07:00
Mathias Vorreiter Pedersen
d020f93005 C++: This is never a definition. 2024-06-04 17:19:49 +01:00
Mathias Vorreiter Pedersen
3e53f3bd13 C++: Flow out of phi inputs to the phi node. 2024-06-04 17:19:47 +01:00
Mathias Vorreiter Pedersen
e04c75df24 C++: Introduce a new phi input dataflow node. 2024-06-04 17:19:46 +01:00
Mathias Vorreiter Pedersen
888a831a5c C++: Use 'ssaDefReachesReadExt' instead of 'ssaDefReachesRead'. 2024-06-04 17:19:45 +01:00
Mathias Vorreiter Pedersen
556dc282d2 C++: Use 'phiHasInputFromBlockExt' instead of 'phiHasInputFromBlock'. 2024-06-04 17:19:43 +01:00
Mathias Vorreiter Pedersen
ceccc9294c C++: Add a testcase that failed during development. 2024-06-04 17:19:41 +01:00
Mathias Vorreiter Pedersen
a9af28ede0 C++: Drive-by fix. This is not needed anymore after #16345 2024-06-04 17:19:40 +01:00
Mathias Vorreiter Pedersen
43c7ac36d9 C++: Add a test with spurious flow. 2024-06-04 17:19:36 +01:00
Owen Mansel-Chan
3fb5ad2a0d Cover all params in QLDoc of modelCoverage 2024-06-04 17:06:00 +01:00
Mauro Baluda
8791e67789 Add .xsaccess test data 2024-06-04 17:50:08 +02:00
Mauro Baluda
576ee7892d Add .xsaccess test data 2024-06-04 17:36:05 +02:00
Mauro Baluda
7b3e9b4ec1 Extract .xsaccess files as JSON 2024-06-04 16:28:08 +02:00
Mauro Baluda
73b18129d9 Extract .xsaccess files as JSON 2024-06-04 16:23:05 +02:00
Tamas Vajk
b8bc014297 Fix erroneous logger disposal 2024-06-04 15:12:44 +02:00
Tom Hvitved
e42de3de6f Ruby: Fix extraction errors 2024-06-04 14:54:02 +02:00
Am
e3e59e02e5 Merge branch 'github:main' into amammad-js-CodeInjection_dynamic_import 2024-06-04 16:22:06 +04:00
Cornelius Riemenschneider
e8c1e50276 JS: Use resources/tools from external repo, not internal.
This was missing in https://github.com/github/codeql/pull/16656, so we couldn't actually
delete the resources in the internal repo.
2024-06-04 13:54:41 +02:00
Tom Hvitved
ad99158838 Ruby: Fix/accept extraction errors 2024-06-04 12:55:44 +02:00
Tom Hvitved
858c7cead2 Ruby: Add consistency query for extraction errors 2024-06-04 12:55:42 +02:00
Geoffrey White
38c47a4b11 C++: Add change notes. 2024-06-04 10:47:25 +01:00
Geoffrey White
9c2b4c9446 C++: Update the doc examples for C/C++. 2024-06-04 10:21:06 +01:00
Geoffrey White
79e9198b20 C++: An empty models-as-data namespace / type is not 'dubious' in CPP. 2024-06-04 10:21:06 +01:00
Geoffrey White
f479649727 C++: Add Boost::Asio models. 2024-06-04 10:21:05 +01:00
Geoffrey White
7e5b7346c0 C++: Add flow test cases for Boost::Asio. 2024-06-04 10:21:05 +01:00
Geoffrey White
8a5b5d220a C++: Add source/sink test cases for Boost::Asio. 2024-06-04 10:21:05 +01:00
Geoffrey White
af6a08893a C++: Update the doc text for C/C++. 2024-06-04 10:20:59 +01:00
Joe Farebrother
6ff7fb2a70 Add change note 2024-06-04 09:52:57 +01:00
Joe Farebrother
9331c2c33a Add tests 2024-06-04 09:39:37 +01:00
Joe Farebrother
6ac46b8436 Add additional sanitizers to SSRF for methods that restrict the contents of a string. 2024-06-03 23:23:25 +01:00
Geoffrey White
e87593af75 C++: Add the doc (copy from csharp). 2024-06-03 13:49:38 +01:00
Geoffrey White
94413c8c2e C++: Implement YML extension models. 2024-06-03 13:49:38 +01:00
Geoffrey White
34130d50d3 C++: Add library tests for YML extension models. 2024-06-03 13:49:26 +01:00
Michael Nebel
546b260330 C#: Update expected test output and remove spurious result. 2024-06-03 10:40:13 +02:00
Michael Nebel
46f5b13854 C#: Only dispatch to summarized callables with generated summaries in case there are no source dispatch possibilities. 2024-06-03 10:40:10 +02:00
Michael Nebel
eb0925be60 C#: There should at least be one manual summary for a non-source summarized callable. 2024-06-03 10:40:06 +02:00
Michael Nebel
213e3918df C#: Add some more external flow testcases (one with a spurious result). 2024-06-03 10:40:02 +02:00
Michael Nebel
b08a0a303f C#: Re-factor external models tests to use compiled code instead of emulating it. 2024-06-03 10:39:59 +02:00
Alex Ford
1100b75a3c Ruby: handle routes with path/action pairs 2024-05-31 15:54:57 +01:00
Alex Ford
0473655752 Ruby: actiondispatch add hash arg testcase 2024-05-31 15:08:35 +01:00
Alex Ford
22858249f9 Ruby: actiondispatch test whitespace changes 2024-05-31 15:07:39 +01:00
Alex Ford
4644f08195 Ruby: Routing.qll - rename call as methodCall 2024-05-31 14:45:32 +01:00
Alex Ford
25f9449f53 Ruby: Routing.qll - rename method as httpMethod 2024-05-31 14:45:26 +01:00
Alex Ford
af9ed21c36 Ruby: Routing.qll - rename method as methodCall 2024-05-31 14:45:20 +01:00
am0o0
1f112467ce update id of the query file 2024-05-29 16:48:35 +02:00
am0o0
b9edcb7943 rename secondary to remote :), complete the previous commit changes 2024-05-29 16:47:37 +02:00
am0o0
52a809145e SecondaryCommandInjection to RemoteCommandExecution, change RemoteCommandExecution to module like SystemCommandExecution module 2024-05-29 16:18:55 +02:00
am0o0
fd9e6f48d7 fix the docs of secondary server cmd injection 2024-05-29 16:01:43 +02:00
am0o0
171486641e Ssh2.qll: fix a typo 2024-05-29 16:00:52 +02:00
am0o0
5299c4a845 fix the qhelp of secondary server cmd injectino 2024-05-29 16:00:06 +02:00
am0o0
66cba89fdb Torch.qll: use better alternative instead of exists 2024-05-29 15:43:41 +02:00
am0o0
8c3994bc9c Paramiko.qll: improve docs 2024-05-29 15:42:29 +02:00
am0o0
b1242e464e Pandas.qll: remove unnecessary exists, fix class naming 2024-05-29 15:41:45 +02:00
am0o0
fcd2bd6776 fabic.qll: remove test predicate and apply review changes 2024-05-29 15:37:11 +02:00
maikypedia
e96c3a36ad Move Apollo to experimental 2024-05-27 12:24:48 +02:00
maikypedia
cfd7c7a47c move change-note to javascript/ql/src/change-notes 2024-05-27 11:57:05 +02:00
am0o0
2b929c4d2d remove old expected test file 2024-05-25 20:45:34 +02:00
am0o0
1fc481ce81 v2: it is basically the first stable version :)) 2024-05-25 20:43:36 +02:00
am0o0
ea05b297a3 update expected test files 2024-05-25 19:40:37 +02:00
am0o0
14daf58767 update tests, add test cases for query with local sources 2024-05-25 18:17:56 +02:00
am0o0
8fde8c2db4 change test dir name 2024-05-25 13:54:31 +02:00
am0o0
b397f57357 change queries id according to new naming 2024-05-25 13:53:33 +02:00
am0o0
300c82a8ff use Verification instead of validation in files name 2024-05-25 13:52:32 +02:00
am0o0
76beffb04a change dir name 2024-05-25 13:49:34 +02:00
am0o0
f1533f40b6 change query files name 2024-05-25 13:49:01 +02:00
am0o0
d2d945c66d merge all JWT pkgs into one 2024-05-25 13:47:43 +02:00
am0o0
4af4040bd6 change duplicate query IDs 2024-05-25 13:29:16 +02:00
am0o0
f905ac10c4 add jsonWebToken library file to remove duplicate predicate declrations 2024-05-25 13:28:13 +02:00
am0o0
0895f7d971 update qlref files 2024-05-21 22:48:17 +02:00
am0o0
c470c078dc move to experimental 2024-05-21 22:42:16 +02:00
Geoffrey White
8dad622de2 Swift: Fix some inconsistencies. 2024-05-21 16:32:00 +01:00
Asger F
0b78d1d953 Python: add qldoc 2024-05-21 14:40:35 +02:00
Asger F
3b211089d6 JS: Remove redundant import 2024-05-21 14:40:17 +02:00
Asger F
13d01f1ec4 Ruby/Python: add recursion guard 2024-05-21 14:40:15 +02:00
Asger F
14c71a351e Sync shared files 2024-05-21 14:38:55 +02:00
Asger F
6f19fc2fcd JS: Add isTypeUsed to avoid overpruning 2024-05-21 14:38:52 +02:00
Asger F
632cce2c16 JS: Add failing test due to overpruning 2024-05-21 14:20:13 +02:00
Asger F
43abc72780 JS: Add TypeModel.isTypeUsed
f
2024-05-21 14:19:56 +02:00
Chanel Young
5ee7004a62 fp case if encrypt set in initializer 2024-05-16 17:59:17 -07:00
Michael B. Gale
81297aad8c Go: Use standard semver format in outputEnvironmentJson 2024-05-15 12:21:23 +01:00
Michael B. Gale
fabd7a9c51 Go: Better preserve original versions 2024-05-15 12:01:03 +01:00
Michael B. Gale
e0543d1d59 Go: Support all permutations of version prefixes and suffixes 2024-05-15 10:43:02 +01:00
Michael B. Gale
6652685f5a Go: Restore toolchain.IsInstalled check 2024-05-15 10:07:44 +01:00
Michael B. Gale
898383ccff Go: Fix comment in NewSemVer for empty string 2024-05-15 10:07:44 +01:00
Michael B. Gale
054efa648c Go: Move version constants to shared location 2024-05-15 10:03:35 +01:00
Michael B. Gale
9e618b6961 Go: Use SemVer type in autobuilder package 2024-05-15 10:03:35 +01:00
Michael B. Gale
a6d2aa3913 Go: Use SemVer type in project package 2024-05-15 10:03:32 +01:00
Michael B. Gale
010df54657 Go: Use SemVer type in toolchain package 2024-05-15 10:03:01 +01:00
Michael B. Gale
d171750678 Go: Add SemVer type to track valid semantic versions 2024-05-15 10:02:10 +01:00
am0o0
c7adb32bc4 simply replace duplicate class references with classRef() in Fabric.qll 2024-05-14 09:51:47 +02:00
am0o0
37d33186e5 revert classRef deletion, fix secondaryserverCmdInjection expected test results 2024-05-13 15:02:04 +02:00
am0o0
fb3d34ce11 format Torch.qll 2024-05-13 14:43:43 +02:00
Sim4n6
7f153ed07b Add some method calls as a Source 2024-05-12 09:46:36 +01:00
am0o0
90da07159e fix tests, chore on Find.ql 2024-05-10 08:51:23 +02:00
am0o0
a87d27b53e revert vscode settings.json file 2024-05-10 08:35:50 +02:00
am0o0
9435a62a86 revert vscode settings.json file 2024-05-10 08:34:08 +02:00
am0o0
0e80e867af fix actions reviews 2024-05-10 08:32:45 +02:00
am0o0
f93d4a0dd5 fix Fabric query library 2024-05-10 01:27:31 +02:00
am0o0
3a52cd186e Merge branch 'am0o0-python-codeExec' of https://github.com/amammad/codeql into am0o0-python-codeExec 2024-05-09 23:16:11 +02:00
Am
0043d93fc1 Merge branch 'github:main' into am0o0-python-codeExec 2024-05-09 23:15:56 +02:00
am0o0
9b4ea8877b Merge branch 'am0o0-python-codeExec' of https://github.com/amammad/codeql into am0o0-python-codeExec 2024-05-09 23:14:11 +02:00
am0o0
4a2ab49efb better structure for pandas DataFrame, it is now much better readable and also we can find much more DataFrame objects 2024-05-06 14:36:10 +02:00
am0o0
8b93e815b9 minor test cases change: remove unused dict 2024-05-06 14:36:10 +02:00
amammad
6b9cc1a278 update Twisted document link 2024-05-06 14:36:10 +02:00
amammad
c4a38d0a2f add twisted SSH client as secondary server command injection sinks, add proper test cases 2024-05-06 14:36:10 +02:00
amammad
0a765cc94a add jsonpickle and pexpect libs in case of unsafe decoding and secondary command execution, add proper test cases 2024-05-06 14:36:10 +02:00
amammad
7e93102097 finalize Secondary server command injection queries and tests. 2024-05-06 14:36:10 +02:00
amammad
ead247469d add ssh client libraries, add SecondaryServerCmdInjectionCustomizations 2024-05-06 14:36:10 +02:00
amammad
4df73f9975 continue to convert paramiko query to a more general query,
the proxy command is not a secondary command execution
so we can add proxy command to SystemCommandExecution::Range, update QLDocs,
add a proper Paramiko test case
fix a typo
2024-05-06 14:36:10 +02:00
amammad
5fea71e5d6 convert paramiko query to SecondaryServerCmdInjection query, Add inline tests 2024-05-06 14:36:10 +02:00
amammad
6520e2fdfb update Fabric models, add new sink to Fabric, add proper test cases 2024-05-06 14:36:10 +02:00
amammad
2708e57e4b add pyTorch :) code execution sinks, add proper tests 2024-05-06 14:36:10 +02:00
amammad
cffdc5b452 add panas code execution sinks, add proper tests 2024-05-06 14:36:10 +02:00
Geoffrey White
fc7fef3dd8 Swift: Add dataflow tests for dictionaries. 2024-04-15 18:50:41 +01:00
Geoffrey White
0c88d05a65 Swift: QLDoc BuiltinLiteralExpr subclasses and add BuiltinLiteral.getValueString. 2024-04-15 18:23:32 +01:00
Jami
5792f7b770 Merge branch 'main' into jcogs33/unsafe-url-forward-promotion-resource-and-file-methods 2024-04-08 10:26:42 -04:00
Jami Cogswell
e90f55a05f Java: move change note to lib 2024-03-27 20:56:19 -04:00
Jami Cogswell
e58e5fb825 Java: add change note 2024-03-27 20:51:13 -04:00
Jami Cogswell
b35f318910 Java: update models 2024-03-27 20:39:34 -04:00
Jami Cogswell
e285cf232c Java: add resource-related methods as path-injection sinks and as summaries 2024-03-13 22:48:57 -04:00
erik-krogh
f2d6640003 fix ambiguous import. It could refer both to a module or a file 2024-03-12 15:15:50 +01:00
erik-krogh
c1fd7a6190 autoformat 2024-03-12 15:09:45 +01:00
maikypedia
699d8d4719 x 2024-03-07 18:15:22 +01:00
am0o0
b20b733172 better structure for pandas DataFrame, it is now much better readable and also we can find much more DataFrame objects 2024-02-27 09:38:43 +04:00
am0o0
a636c47c84 minor test cases change: remove unused dict 2024-02-25 23:57:58 +04:00
amammad
4321c5c2da update Twisted document link 2024-02-25 17:53:19 +04:00
amammad
7dd1389b9e add twisted SSH client as secondary server command injection sinks, add proper test cases 2024-02-25 17:52:24 +04:00
amammad
ab219902a9 add jsonpickle and pexpect libs in case of unsafe decoding and secondary command execution, add proper test cases 2024-02-25 17:15:35 +04:00
amammad
3e6b4a161b finalize Secondary server command injection queries and tests. 2024-02-25 14:24:42 +04:00
amammad
95c9a3fc9a add ssh client libraries, add SecondaryServerCmdInjectionCustomizations 2024-02-25 12:50:12 +04:00
amammad
385c3ba7ff continue to convert paramiko query to a more general query,
the proxy command is not a secondary command execution
so we can add proxy command to SystemCommandExecution::Range, update QLDocs,
add a proper Paramiko test case
fix a typo
2024-02-25 01:18:34 +04:00
amammad
70282f9ebe convert paramiko query to SecondaryServerCmdInjection query, Add inline tests 2024-02-24 18:10:13 +04:00
amammad
d234a53c50 update Fabric models, add new sink to Fabric, add proper test cases 2024-02-24 17:43:51 +04:00
amammad
076faa3a4e add pyTorch :) code execution sinks, add proper tests 2024-02-24 15:55:33 +04:00
amammad
3d7db0e46b add panas code execution sinks, add proper tests 2024-02-24 14:44:06 +04:00
maikypedia
78e7793e01 Move to experimental 2024-01-09 01:11:58 +01:00
maikypedia
7662b2bd24 format 2023-12-19 13:23:05 +01:00
Maiky
191766a47b Use config.getCorsConfiguration().getOrigin())
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2023-12-18 12:38:39 +01:00
Maiky
4f68f60db2 Apply review
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2023-12-18 12:37:05 +01:00
amammad
102f09aa23 extend tests 2023-12-10 20:33:00 +01:00
amammad
18d0b28024 v1 2023-12-10 20:27:21 +01:00
maikypedia
87cac2a4e3 Express Argument has to be Cors 2023-12-07 23:01:41 +01:00
Maiky
83cbbd7043 Apply docstring changes
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2023-12-05 09:05:29 +01:00
Maiky
e6c7fc0ead Fixes CI 2023-11-29 19:45:08 +02:00
Maiky
6a3cdc90e2 Add change-node 2023-11-27 20:58:47 +02:00
Maiky
3bcb411d1a Using Express::RouteSetup 2023-11-27 20:31:19 +02:00
Maiky
f623db461a Change qldoc 2023-11-27 19:51:13 +02:00
Maiky
bb6ef72e67 getArgument returns Cors::Cors 2023-11-27 19:36:49 +02:00
Maiky
aa24ce5532 Apply suggestions from code review
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2023-11-27 17:48:21 +02:00
amammad
48a9b107b9 add query to detect strapi CVe too 2023-11-24 10:47:17 +01:00
Maiky
4ef4c92e2c Move Customizations and Query 2023-11-23 21:29:09 +01:00
Maiky
abd53e98a9 Fix minor issues 2023-11-23 13:17:54 +01:00
Maiky
413c11171e Move to /experimental 2023-11-23 11:00:47 +01:00
Maiky
d661f7f482 Add Flow Labels 2023-11-22 19:50:16 +01:00
amammad
5cc4206e00 add a temporary Query file to demonstrate unsuccessful usage of two DataFlow configs 2023-11-22 08:30:59 +01:00
amammad
0652afced3 update tests, updated qldoc and examples, upgrade all libraries to path-problem, update jsonwebtoken source and sinks 2023-11-07 08:25:25 +01:00
amammad
a9c8bc082f delete CWE-321 2023-11-02 16:27:31 +01:00
amammad
faa483a282 move to CWE-347, update comments of tests 2023-11-02 16:24:58 +01:00
amammad
9da815a5c0 move to new CWE-321 directory, make saparate query files for each JWT pkg, create a path query for jsonwebtoken package which is not work correctly 2023-11-02 14:13:52 +01:00
amammad
ee4d87bd96 remove hardcoded JWT secret-key query 2023-10-19 11:57:53 +02:00
amammad
7891e64d3e add sanitizers to hardcoded query 2023-10-17 10:37:27 +02:00
Maiky
acac534ed0 Forgot .js 2023-10-16 19:29:57 +02:00
Maiky
07ad596f77 Add coverage for express 2023-10-16 16:48:32 +02:00
Maiky
c0e6d7c049 Merge branch 'github:main' into maikypedia/javascript-cors 2023-10-11 12:20:42 +02:00
amammad
3f41a42c38 remove unused classes 2023-10-08 11:08:05 +02:00
amammad
15671682c5 remove unused flowLable, update path query alert message 2023-10-08 11:06:13 +02:00
amammad
00b6e1f0b0 fix tests 2023-10-08 11:03:19 +02:00
amammad
41e7b91d78 fix flowLabels 2023-10-08 11:00:07 +02:00
Maiky
ed066281b9 Add documentation string for CorsPermissiveConfiguration 2023-10-06 18:22:31 +02:00
Maiky
816eebbb51 Add .qhelp and apply some review changes 2023-10-02 18:05:39 +02:00
Maiky
142ab01b48 Remove comment line 2023-09-29 18:32:12 +02:00
Maiky
e171123589 Add initial query for CWE-942 2023-09-29 18:25:58 +02:00
amammad
f41bc1f631 revert nodeJSLib 2023-09-28 20:37:21 +10:00
amammad
75f0fc4a98 fix a mistake 2023-09-28 20:34:58 +10:00
amammad
921198ed30 add separate query for sinks that accepts data: URL 2023-09-28 20:33:38 +10:00
amammad
f6737b3d90 fix FP 2023-09-25 21:09:19 +10:00
amammad
344869f0d7 change commandExecution sink to CodeInjection sink 2023-09-22 19:37:17 +10:00
amammad
06114d91d8 V1 2023-09-22 19:19:52 +10:00
amammad
7a577ddd98 change Source to ConstantString, it seems that we have some duplicate results now, ConstantString is suggested as a better alternative for finding constant sources 2023-08-30 20:47:43 +10:00
amammad
3f64cc82eb fix qhelps 2023-08-29 22:42:21 +10:00
amammad
4f04dc8f6e add test cases 2023-08-29 21:34:02 +10:00
amammad
65b97745c2 V1 2023-08-29 21:23:02 +10:00
1098 changed files with 23283 additions and 21182 deletions

View File

@@ -1 +1 @@
7.1.2
7.2.1

2
.gitattributes vendored
View File

@@ -83,7 +83,7 @@
/csharp/paket.main_extension.bzl linguist-generated=true
# ripunzip tool
/misc/bazel/internal/ripunzip/ripunzip-* filter=lfs diff=lfs merge=lfs -text
/misc/ripunzip/ripunzip-* filter=lfs diff=lfs merge=lfs -text
# swift prebuilt resources
/swift/third_party/resource-dir/*.zip filter=lfs diff=lfs merge=lfs -text

View File

@@ -7,6 +7,7 @@ on:
- .github/workflows/ruby-build.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- "shared/tree-sitter-extractor/**"
branches:
- main
- "rc/*"
@@ -16,6 +17,7 @@ on:
- .github/workflows/ruby-build.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- "shared/tree-sitter-extractor/**"
branches:
- main
- "rc/*"

View File

@@ -13,22 +13,45 @@ local_path_override(
# see https://registry.bazel.build/ for a list of available packages
bazel_dep(name = "platforms", version = "0.0.9")
bazel_dep(name = "rules_go", version = "0.47.0")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_go", version = "0.48.0")
bazel_dep(name = "rules_pkg", version = "0.10.1")
bazel_dep(name = "rules_nodejs", version = "6.0.3")
bazel_dep(name = "rules_python", version = "0.31.0")
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
bazel_dep(name = "rules_python", version = "0.32.2")
bazel_dep(name = "bazel_skylib", version = "1.6.1")
bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl")
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
bazel_dep(name = "fmt", version = "10.0.0")
bazel_dep(name = "rules_kotlin", version = "1.9.4-codeql.1")
bazel_dep(name = "gazelle", version = "0.36.0")
bazel_dep(name = "gazelle", version = "0.37.0")
bazel_dep(name = "rules_dotnet", version = "0.15.1")
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
bazel_dep(name = "rules_rust", version = "0.46.0")
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
crate = use_extension(
"@rules_rust//crate_universe:extension.bzl",
"crate",
)
crate.from_cargo(
name = "py_deps",
cargo_lockfile = "//python/extractor/tsg-python:Cargo.lock",
manifests = [
"//python/extractor/tsg-python:Cargo.toml",
"//python/extractor/tsg-python/tsp:Cargo.toml",
],
)
crate.from_cargo(
name = "ruby_deps",
cargo_lockfile = "//ruby/extractor:Cargo.lock",
manifests = [
"//ruby/extractor:Cargo.toml",
"//ruby/extractor/codeql-extractor-fake-crate:Cargo.toml",
],
)
use_repo(crate, "py_deps", "ruby_deps")
dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
dotnet.toolchain(dotnet_version = "8.0.101")
use_repo(dotnet, "dotnet_toolchains")
@@ -62,6 +85,10 @@ use_repo(
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
node.toolchain(
name = "nodejs",
node_urls = [
"https://nodejs.org/dist/v{version}/{filename}",
"https://mirrors.dotsrc.org/nodejs/release/v{version}/{filename}",
],
node_version = "18.15.0",
)
use_repo(node, "nodejs", "nodejs_toolchains")
@@ -118,19 +145,19 @@ lfs_files = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_files")
lfs_files(
name = "ripunzip-linux",
srcs = ["//misc/bazel/internal/ripunzip:ripunzip-linux"],
srcs = ["//misc/ripunzip:ripunzip-linux"],
executable = True,
)
lfs_files(
name = "ripunzip-windows",
srcs = ["//misc/bazel/internal/ripunzip:ripunzip-windows.exe"],
srcs = ["//misc/ripunzip:ripunzip-windows.exe"],
executable = True,
)
lfs_files(
name = "ripunzip-macos",
srcs = ["//misc/bazel/internal/ripunzip:ripunzip-macos"],
srcs = ["//misc/ripunzip:ripunzip-macos"],
executable = True,
)

View File

@@ -61,10 +61,6 @@
"java/ql/src/utils/modelgenerator/internal/CaptureModels.qll",
"csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll"
],
"Model as Data Generation Java/C# - CaptureModelsPrinting": [
"java/ql/src/utils/modelgenerator/internal/CaptureModelsPrinting.qll",
"csharp/ql/src/utils/modelgenerator/internal/CaptureModelsPrinting.qll"
],
"Sign Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
@@ -185,11 +181,6 @@
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysisImports.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysisImports.qll"
],
"C++ IR ValueNumberingImports": [
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingImports.qll"
],
"IR SSA SSAConstruction": [
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll"

View File

@@ -1,3 +1,13 @@
## 1.1.0
### New Features
* Data models can now be added with data extensions. In this way source, sink and summary models can be added in extension `.model.yml` files, rather than by writing classes in QL code. New models should be added in the `lib/ext` folder.
### Minor Analysis Improvements
* A partial model for the `Boost.Asio` network library has been added. This includes sources, sinks and summaries for certain functions in `Boost.Asio`, such as `read_until` and `write`.
## 1.0.0
### Breaking Changes

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Guards" library (`semmle.code.cpp.controlflow.Guards`) now also infers guards from calls to the builtin operation `__builtin_expect`. As a result, some queries may produce fewer false positives.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The queries "Potential double free" (`cpp/double-free`) and "Potential use after free" (`cpp/use-after-free`) now produce fewer false positives.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* It is now possible to extend the classes `AllocationFunction` and `DeallocationFunction` via data extensions. Extensions of these classes should be added to the `lib/ext/allocation` and `lib/ext/deallocation` directories respectively.

View File

@@ -0,0 +1,9 @@
## 1.1.0
### New Features
* Data models can now be added with data extensions. In this way source, sink and summary models can be added in extension `.model.yml` files, rather than by writing classes in QL code. New models should be added in the `lib/ext` folder.
### Minor Analysis Improvements
* A partial model for the `Boost.Asio` network library has been added. This includes sources, sinks and summaries for certain functions in `Boost.Asio`, such as `read_until` and `write`.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.0.0
lastReleaseVersion: 1.1.0

View File

@@ -0,0 +1,26 @@
extensions:
# partial model of the Boost::Asio network library
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: sourceModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
- ["boost::asio", "", False, "read", "", "", "Argument[*1]", "remote", "manual"]
- ["boost::asio", "", False, "read_at", "", "", "Argument[*2]", "remote", "manual"]
- ["boost::asio", "", False, "read_until", "", "", "Argument[*1]", "remote", "manual"]
- ["boost::asio", "", False, "async_read", "", "", "Argument[*1]", "remote", "manual"]
- ["boost::asio", "", False, "async_read_at", "", "", "Argument[*2]", "remote", "manual"]
- ["boost::asio", "", False, "async_read_until", "", "", "Argument[*1]", "remote", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: sinkModel
data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
- ["boost::asio", "", False, "write", "", "", "Argument[*1]", "remote-sink", "manual"]
- ["boost::asio", "", False, "write_at", "", "", "Argument[*2]", "remote-sink", "manual"]
- ["boost::asio", "", False, "async_write", "", "", "Argument[*1]", "remote-sink", "manual"]
- ["boost::asio", "", False, "async_write_at", "", "", "Argument[*2]", "remote-sink", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["boost::asio", "", False, "buffer", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: allocationFunctionModel
data:
- ["", "", False, "kmem_alloc", "0", "", "", True]
- ["", "", False, "kmem_zalloc", "0", "", "", True]

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: allocationFunctionModel
data:
- ["", "", False, "g_malloc", "0", "", "", True]
- ["", "", False, "g_try_malloc", "0", "", "", True]

View File

@@ -0,0 +1,10 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: allocationFunctionModel
data:
- ["", "", False, "CRYPTO_malloc", "0", "", "", True]
- ["", "", False, "CRYPTO_zalloc", "0", "", "", True]
- ["", "", False, "CRYPTO_secure_malloc", "0", "", "", True]
- ["", "", False, "CRYPTO_secure_zalloc", "0", "", "", True]

View File

@@ -0,0 +1,15 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: allocationFunctionModel
data:
- ["", "", False, "malloc", "0", "", "", True]
- ["std", "", False, "malloc", "0", "", "", True]
- ["bsl", "", False, "malloc", "0", "", "", True]
- ["", "", False, "alloca", "0", "", "", False]
- ["", "", False, "__builtin_alloca", "0", "", "", False]
- ["", "", False, "_alloca", "0", "", "", False]
- ["", "", False, "_malloca", "0", "", "", False]
- ["", "", False, "calloc", "1", "0", "", True]
- ["std", "", False, "calloc", "1", "0", "", True]
- ["bsl", "", False, "calloc", "1", "0", "", True]

View File

@@ -0,0 +1,29 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: allocationFunctionModel
data:
- ["", "", False, "MmAllocateContiguousMemory", "0", "", "", True]
- ["", "", False, "MmAllocateContiguousNodeMemory", "0", "", "", True]
- ["", "", False, "MmAllocateContiguousMemorySpecifyCache", "0", "", "", True]
- ["", "", False, "MmAllocateContiguousMemorySpecifyCacheNode", "0", "", "", True]
- ["", "", False, "MmAllocateNonCachedMemory", "0", "", "", True]
- ["", "", False, "MmAllocateMappingAddress", "0", "", "", True]
- ["", "", False, "CoTaskMemAlloc", "0", "", "", True]
- ["", "", False, "ExAllocatePool", "1", "", "", True]
- ["", "", False, "ExAllocatePool2", "1", "", "", True]
- ["", "", False, "ExAllocatePool3", "1", "", "", True]
- ["", "", False, "ExAllocatePoolWithTag", "1", "", "", True]
- ["", "", False, "ExAllocatePoolWithTagPriority", "1", "", "", True]
- ["", "", False, "ExAllocatePoolWithQuota", "1", "", "", True]
- ["", "", False, "ExAllocatePoolWithQuotaTag", "1", "", "", True]
- ["", "", False, "ExAllocatePoolZero", "1", "", "", True]
- ["", "", False, "IoAllocateMdl", "1", "", "", True]
- ["", "", False, "IoAllocateErrorLogEntry", "1", "", "", True]
- ["", "", False, "LocalAlloc", "1", "", "", True]
- ["", "", False, "GlobalAlloc", "1", "", "", True]
- ["", "", False, "VirtualAlloc", "1", "", "", True]
- ["", "", False, "HeapAlloc", "2", "", "", True]
- ["", "", False, "MmAllocatePagesForMdl", "3", "", "", True]
- ["", "", False, "MmAllocatePagesForMdlEx", "3", "", "", True]
- ["", "", False, "MmAllocateNodePagesForMdlEx", "3", "", "", True]

View File

@@ -0,0 +1,5 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: allocationFunctionModel
data: []

View File

@@ -0,0 +1,8 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: deallocationFunctionModel
data:
- ["", "", False, "pool_put", "1"]
- ["", "", False, "pool_cache_put", "1"]
- ["", "", False, "kmem_free", "0"]

View File

@@ -0,0 +1,42 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: deallocationFunctionModel
data:
- ["", "", False, "free", "0"]
- ["std", "", False, "free", "0"]
- ["bsl", "", False, "free", "0"]
- ["", "", False, "realloc", "0"]
- ["std", "", False, "realloc", "0"]
- ["bsl", "", False, "realloc", "0"]
- ["", "", False, "CRYPTO_free", "0"]
- ["", "", False, "CRYPTO_secure_free", "0"]
- ["", "", False, "g_free", "0"]
- ["", "", False, "ExFreePool", "0"]
- ["", "", False, "ExFreePoolWithTag", "0"]
- ["", "", False, "ExDeleteTimer", "0"]
- ["", "", False, "IoFreeIrp", "0"]
- ["", "", False, "IoFreeMdl", "0"]
- ["", "", False, "IoFreeErrorLogEntry", "0"]
- ["", "", False, "IoFreeWorkItem", "0"]
- ["", "", False, "MmFreeContiguousMemory", "0"]
- ["", "", False, "MmFreeContiguousMemorySpecifyCache", "0"]
- ["", "", False, "MmFreeNonCachedMemory", "0"]
- ["", "", False, "MmFreeMappingAddress", "0"]
- ["", "", False, "MmFreePagesFromMdl", "0"]
- ["", "", False, "MmUnmapReservedMapping", "0"]
- ["", "", False, "MmUnmapLockedPages", "0"]
- ["", "", False, "NdisFreeGenericObject", "0"]
- ["", "", False, "NdisFreeMemory", "0"]
- ["", "", False, "NdisFreeMemoryWithTag", "0"]
- ["", "", False, "NdisFreeMdl", "0"]
- ["", "", False, "NdisFreeNetBufferListPool", "0"]
- ["", "", False, "NdisFreeNetBufferPool", "0"]
- ["", "", False, "LocalFree", "0"]
- ["", "", False, "GlobalFree", "0"]
- ["", "", False, "LocalReAlloc", "0"]
- ["", "", False, "GlobalReAlloc", "0"]
- ["", "", False, "VirtualFree", "0"]
- ["", "", False, "CoTaskMemFree", "0"]
- ["", "", False, "CoTaskMemRealloc", "0"]
- ["", "", False, "SysFreeString", "0"]

View File

@@ -0,0 +1,41 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: deallocationFunctionModel
data:
- ["", "", False, "ExFreePool", "0"]
- ["", "", False, "ExFreePoolWithTag", "0"]
- ["", "", False, "ExDeleteTimer", "0"]
- ["", "", False, "IoFreeIrp", "0"]
- ["", "", False, "IoFreeMdl", "0"]
- ["", "", False, "IoFreeErrorLogEntry", "0"]
- ["", "", False, "IoFreeWorkItem", "0"]
- ["", "", False, "MmFreeContiguousMemory", "0"]
- ["", "", False, "MmFreeContiguousMemorySpecifyCache", "0"]
- ["", "", False, "MmFreeNonCachedMemory", "0"]
- ["", "", False, "MmFreeMappingAddress", "0"]
- ["", "", False, "MmFreePagesFromMdl", "0"]
- ["", "", False, "MmUnmapReservedMapping", "0"]
- ["", "", False, "MmUnmapLockedPages", "0"]
- ["", "", False, "NdisFreeGenericObject", "0"]
- ["", "", False, "NdisFreeMemory", "0"]
- ["", "", False, "NdisFreeMemoryWithTag", "0"]
- ["", "", False, "NdisFreeMdl", "0"]
- ["", "", False, "NdisFreeNetBufferListPool", "0"]
- ["", "", False, "NdisFreeNetBufferPool", "0"]
- ["", "", False, "LocalFree", "0"]
- ["", "", False, "GlobalFree", "0"]
- ["", "", False, "LocalReAlloc", "0"]
- ["", "", False, "GlobalReAlloc", "0"]
- ["", "", False, "VirtualFree", "0"]
- ["", "", False, "CoTaskMemFree", "0"]
- ["", "", False, "CoTaskMemRealloc", "0"]
- ["", "", False, "SysFreeString", "0"]
- ["", "", False, "ExFreeToLookasideListEx", "1"]
- ["", "", False, "ExFreeToPagedLookasideList", "1"]
- ["", "", False, "ExFreeToNPagedLookasideList", "1"]
- ["", "", False, "NdisFreeMemoryWithTagPriority", "1"]
- ["", "", False, "StorPortFreeMdl", "1"]
- ["", "", False, "StorPortFreePool", "1"]
- ["", "", False, "HeapFree", "2"]
- ["", "", False, "HeapReAlloc", "2"]

View File

@@ -0,0 +1,5 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: deallocationFunctionModel
data: []

View File

@@ -0,0 +1,15 @@
extensions:
# Make sure that the extensible model predicates have at least one definition
# to avoid errors about undefined extensionals.
- addsTo:
pack: codeql/cpp-all
extensible: sourceModel
data: []
- addsTo:
pack: codeql/cpp-all
extensible: sinkModel
data: []
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: []

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 1.0.1-dev
version: 1.1.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
@@ -14,4 +14,8 @@ dependencies:
codeql/tutorial: ${workspace}
codeql/util: ${workspace}
codeql/xml: ${workspace}
dataExtensions:
- ext/*.model.yml
- ext/deallocation/*.model.yml
- ext/allocation/*.model.yml
warnOnImplicitThis: true

View File

@@ -410,6 +410,10 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
or
orphaned_variables(underlyingElement(this), unresolveElement(result))
}
override predicate isStatic() {
super.isStatic() or orphaned_variables(underlyingElement(this), _)
}
}
/**

View File

@@ -375,6 +375,33 @@ cached
class IRGuardCondition extends Instruction {
Instruction branch;
/*
* An `IRGuardCondition` supports reasoning about four different kinds of
* relations:
* 1. A unary equality relation of the form `e == k`
* 2. A binary equality relation of the form `e1 == e2 + k`
* 3. A unary inequality relation of the form `e < k`
* 4. A binary inequality relation of the form `e1 < e2 + k`
*
* where `k` is a constant.
*
* Furthermore, the unary relations (i.e., case 1 and case 3) are also
* inferred from `switch` statement guards: equality relations are inferred
* from the unique `case` statement, if any, and inequality relations are
* inferred from the [case range](https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html)
* gcc extension.
*
* The implementation of all four follows the same structure: Each relation
* has a cached user-facing predicate that. For example,
* `GuardCondition::comparesEq` calls `compares_eq`. This predicate has
* several cases that recursively decompose the relation to bring it to a
* canonical form (i.e., a relation of the form `e1 == e2 + k`). The base
* case for this relation (i.e., `simple_comparison_eq`) handles
* `CompareEQInstruction`s and `CompareNEInstruction`, and recursive
* predicates (e.g., `complex_eq`) rewrites larger expressions such as
* `e1 + k1 == e2 + k2` into canonical the form `e1 == e2 + (k2 - k1)`.
*/
cached
IRGuardCondition() { branch = getBranchForCondition(this) }
@@ -735,6 +762,8 @@ private predicate compares_eq(
exists(AbstractValue dual | value = dual.getDualValue() |
compares_eq(test.(LogicalNotInstruction).getUnary(), left, right, k, areEqual, dual)
)
or
compares_eq(test.(BuiltinExpectCallInstruction).getCondition(), left, right, k, areEqual, value)
}
/**
@@ -776,7 +805,9 @@ private predicate unary_compares_eq(
Instruction test, Operand op, int k, boolean areEqual, boolean inNonZeroCase, AbstractValue value
) {
/* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */
exists(AbstractValue v | unary_simple_comparison_eq(test, op, k, inNonZeroCase, v) |
exists(AbstractValue v |
unary_simple_comparison_eq(test, k, inNonZeroCase, v) and op.getDef() = test
|
areEqual = true and value = v
or
areEqual = false and value = v.getDualValue()
@@ -802,6 +833,9 @@ private predicate unary_compares_eq(
int_value(const) = k1 and
k = k1 + k2
)
or
unary_compares_eq(test.(BuiltinExpectCallInstruction).getCondition(), op, k, areEqual,
inNonZeroCase, value)
}
/** Rearrange various simple comparisons into `left == right + k` form. */
@@ -821,45 +855,55 @@ private predicate simple_comparison_eq(
value.(BooleanValue).getValue() = false
}
/**
* Holds if `test` is an instruction that is part of test that eventually is
* used in a conditional branch.
*/
private predicate relevantUnaryComparison(Instruction test) {
not test instanceof CompareInstruction and
exists(IRType type, ConditionalBranchInstruction branch |
type instanceof IRAddressType or type instanceof IRIntegerType
|
type = test.getResultIRType() and
branch.getCondition() = test
)
or
exists(LogicalNotInstruction logicalNot |
relevantUnaryComparison(logicalNot) and
test = logicalNot.getUnary()
)
}
/**
* Rearrange various simple comparisons into `op == k` form.
*/
private predicate unary_simple_comparison_eq(
Instruction test, Operand op, int k, boolean inNonZeroCase, AbstractValue value
Instruction test, int k, boolean inNonZeroCase, AbstractValue value
) {
exists(SwitchInstruction switch, CaseEdge case |
test = switch.getExpression() and
op.getDef() = test and
case = value.(MatchValue).getCase() and
exists(switch.getSuccessor(case)) and
case.getValue().toInt() = k and
inNonZeroCase = false
)
or
// There's no implicit CompareInstruction in files compiled as C since C
// doesn't have implicit boolean conversions. So instead we check whether
// there's a branch on a value of pointer or integer type.
relevantUnaryComparison(test) and
op.getDef() = test and
// Any instruction with an integral type could potentially be part of a
// check for nullness when used in a guard. So we include all integral
// typed instructions here. However, since some of these instructions are
// already included as guards in other cases, we exclude those here.
// These are instructions that compute a binary equality or inequality
// relation. For example, the following:
// ```cpp
// if(a == b + 42) { ... }
// ```
// generates the following IR:
// ```
// r1(glval<int>) = VariableAddress[a] :
// r2(int) = Load[a] : &:r1, m1
// r3(glval<int>) = VariableAddress[b] :
// r4(int) = Load[b] : &:r3, m2
// r5(int) = Constant[42] :
// r6(int) = Add : r4, r5
// r7(bool) = CompareEQ : r2, r6
// v1(void) = ConditionalBranch : r7
// ```
// and since `r7` is an integral typed instruction this predicate could
// include a case for when `r7` evaluates to true (in which case we would
// infer that `r6` was non-zero, and a case for when `r7` evaluates to false
// (in which case we would infer that `r6` was zero).
// However, since `a == b + 42` is already supported when reasoning about
// binary equalities we exclude those cases here.
not test.isGLValue() and
not simple_comparison_eq(test, _, _, _, _) and
not simple_comparison_lt(test, _, _, _) and
not test = any(SwitchInstruction switch).getExpression() and
(
test.getResultIRType() instanceof IRAddressType or
test.getResultIRType() instanceof IRIntegerType or
test.getResultIRType() instanceof IRBooleanType
) and
(
k = 1 and
value.(BooleanValue).getValue() = true and
@@ -871,12 +915,68 @@ private predicate unary_simple_comparison_eq(
)
}
/** A call to the builtin operation `__builtin_expect`. */
private class BuiltinExpectCallInstruction extends CallInstruction {
BuiltinExpectCallInstruction() { this.getStaticCallTarget().hasName("__builtin_expect") }
/** Gets the condition of this call. */
Instruction getCondition() {
// The first parameter of `__builtin_expect` has type `long`. So we skip
// the conversion when inferring guards.
result = this.getArgument(0).(ConvertInstruction).getUnary()
}
}
/**
* Holds if `left == right + k` is `areEqual` if `cmp` evaluates to `value`,
* and `cmp` is an instruction that compares the value of
* `__builtin_expect(left == right + k, _)` to `0`.
*/
private predicate builtin_expect_eq(
CompareInstruction cmp, Operand left, Operand right, int k, boolean areEqual, AbstractValue value
) {
exists(BuiltinExpectCallInstruction call, Instruction const, AbstractValue innerValue |
int_value(const) = 0 and
cmp.hasOperands(call.getAUse(), const.getAUse()) and
compares_eq(call.getCondition(), left, right, k, areEqual, innerValue)
|
cmp instanceof CompareNEInstruction and
value = innerValue
or
cmp instanceof CompareEQInstruction and
value.getDualValue() = innerValue
)
}
private predicate complex_eq(
CompareInstruction cmp, Operand left, Operand right, int k, boolean areEqual, AbstractValue value
) {
sub_eq(cmp, left, right, k, areEqual, value)
or
add_eq(cmp, left, right, k, areEqual, value)
or
builtin_expect_eq(cmp, left, right, k, areEqual, value)
}
/**
* Holds if `op == k` is `areEqual` if `cmp` evaluates to `value`, and `cmp` is
* an instruction that compares the value of `__builtin_expect(op == k, _)` to `0`.
*/
private predicate unary_builtin_expect_eq(
CompareInstruction cmp, Operand op, int k, boolean areEqual, boolean inNonZeroCase,
AbstractValue value
) {
exists(BuiltinExpectCallInstruction call, Instruction const, AbstractValue innerValue |
int_value(const) = 0 and
cmp.hasOperands(call.getAUse(), const.getAUse()) and
unary_compares_eq(call.getCondition(), op, k, areEqual, inNonZeroCase, innerValue)
|
cmp instanceof CompareNEInstruction and
value = innerValue
or
cmp instanceof CompareEQInstruction and
value.getDualValue() = innerValue
)
}
private predicate unary_complex_eq(
@@ -885,6 +985,8 @@ private predicate unary_complex_eq(
unary_sub_eq(test, op, k, areEqual, inNonZeroCase, value)
or
unary_add_eq(test, op, k, areEqual, inNonZeroCase, value)
or
unary_builtin_expect_eq(test, op, k, areEqual, inNonZeroCase, value)
}
/*
@@ -913,7 +1015,8 @@ private predicate compares_lt(
/** Holds if `op < k` evaluates to `isLt` given that `test` evaluates to `value`. */
private predicate compares_lt(Instruction test, Operand op, int k, boolean isLt, AbstractValue value) {
simple_comparison_lt(test, op, k, isLt, value)
unary_simple_comparison_lt(test, k, isLt, value) and
op.getDef() = test
or
complex_lt(test, op, k, isLt, value)
or
@@ -960,12 +1063,11 @@ private predicate simple_comparison_lt(CompareInstruction cmp, Operand left, Ope
}
/** Rearrange various simple comparisons into `op < k` form. */
private predicate simple_comparison_lt(
Instruction test, Operand op, int k, boolean isLt, AbstractValue value
private predicate unary_simple_comparison_lt(
Instruction test, int k, boolean isLt, AbstractValue value
) {
exists(SwitchInstruction switch, CaseEdge case |
test = switch.getExpression() and
op.getDef() = test and
case = value.(MatchValue).getCase() and
exists(switch.getSuccessor(case)) and
case.getMaxValue() > case.getMinValue()

View File

@@ -78,6 +78,7 @@ private import internal.FlowSummaryImpl
private import internal.FlowSummaryImpl::Public
private import internal.FlowSummaryImpl::Private
private import internal.FlowSummaryImpl::Private::External
private import internal.ExternalFlowExtensions as Extensions
private import codeql.mad.ModelValidation as SharedModelVal
private import codeql.util.Unit
@@ -138,6 +139,9 @@ predicate sourceModel(
row.splitAt(";", 7) = kind
) and
provenance = "manual"
or
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance,
_)
}
/** Holds if a sink model exists for the given parameters. */
@@ -158,6 +162,8 @@ predicate sinkModel(
row.splitAt(";", 7) = kind
) and
provenance = "manual"
or
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, _)
}
/** Holds if a summary model exists for the given parameters. */
@@ -179,6 +185,9 @@ predicate summaryModel(
row.splitAt(";", 8) = kind
) and
provenance = "manual"
or
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
provenance, _)
}
private predicate relevantNamespace(string namespace) {
@@ -203,8 +212,10 @@ private predicate canonicalNamespaceLink(string namespace, string subns) {
}
/**
* Holds if CSV framework coverage of `namespace` is `n` api endpoints of the
* kind `(kind, part)`.
* Holds if MaD framework coverage of `namespace` is `n` api endpoints of the
* kind `(kind, part)`, and `namespaces` is the number of subnamespaces of
* `namespace` which have MaD framework coverage (including `namespace`
* itself).
*/
predicate modelCoverage(string namespace, int namespaces, string kind, string part, int n) {
namespaces = strictcount(string subns | canonicalNamespaceLink(namespace, subns)) and
@@ -321,10 +332,10 @@ module CsvValidation {
or
summaryModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "summary"
|
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
not namespace.regexpMatch("[a-zA-Z0-9_\\.:]*") and
result = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
or
not type.regexpMatch("[a-zA-Z0-9_<>,\\+]+") and
not type.regexpMatch("[a-zA-Z0-9_<>,\\+]*") and
result = "Dubious type \"" + type + "\" in " + pred + " model."
or
not name.regexpMatch("[a-zA-Z0-9_<>,]*") and

View File

@@ -216,7 +216,7 @@ predicate localMustFlowStep(Node node1, Node node2) { none() }
/** Gets the type of `n` used for type pruning. */
Type getNodeType(Node n) {
suppressUnusedNode(n) and
exists(n) and
result instanceof VoidType // stub implementation
}
@@ -227,13 +227,10 @@ string ppReprType(Type t) { none() } // stub implementation
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
* a node of type `t1` to a node of type `t2`.
*/
pragma[inline]
predicate compatibleTypes(Type t1, Type t2) {
any() // stub implementation
t1 instanceof VoidType and t2 instanceof VoidType // stub implementation
}
private predicate suppressUnusedNode(Node n) { any() }
//////////////////////////////////////////////////////////////////////////////
// Java QL library compatibility wrappers
//////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,27 @@
/**
* This module provides extensible predicates for defining MaD models.
*/
/**
* Holds if an external source model exists for the given parameters.
*/
extensible predicate sourceModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**
* Holds if an external sink model exists for the given parameters.
*/
extensible predicate sinkModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**
* Holds if an external summary model exists for the given parameters.
*/
extensible predicate summaryModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, QlBuiltins::ExtensionId madId
);

View File

@@ -988,7 +988,7 @@ predicate localMustFlowStep(Node node1, Node node2) { none() }
/** Gets the type of `n` used for type pruning. */
DataFlowType getNodeType(Node n) {
suppressUnusedNode(n) and
exists(n) and
result instanceof VoidType // stub implementation
}
@@ -999,13 +999,10 @@ string ppReprType(DataFlowType t) { none() } // stub implementation
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
* a node of type `t1` to a node of type `t2`.
*/
pragma[inline]
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
any() // stub implementation
t1 instanceof VoidType and t2 instanceof VoidType // stub implementation
}
private predicate suppressUnusedNode(Node n) { any() }
//////////////////////////////////////////////////////////////////////////////
// Java QL library compatibility wrappers
//////////////////////////////////////////////////////////////////////////////
@@ -1336,6 +1333,8 @@ predicate nodeIsHidden(Node n) {
n instanceof FinalGlobalValue
or
n instanceof InitialGlobalValue
or
n instanceof SsaPhiInputNode
}
predicate neverSkipInPathGraph(Node n) {
@@ -1634,6 +1633,8 @@ private Instruction getAnInstruction(Node n) {
or
result = n.(SsaPhiNode).getPhiNode().getBasicBlock().getFirstInstruction()
or
result = n.(SsaPhiInputNode).getBasicBlock().getFirstInstruction()
or
n.(IndirectInstruction).hasInstructionAndIndirectionIndex(result, _)
or
not n instanceof IndirectInstruction and
@@ -1763,7 +1764,7 @@ module IteratorFlow {
crementCall = def.getValue().asInstruction().(StoreInstruction).getSourceValue() and
sv = def.getSourceVariable() and
bb.getInstruction(i) = crementCall and
Ssa::ssaDefReachesRead(sv, result.asDef(), bb, i)
Ssa::ssaDefReachesReadExt(sv, result.asDef(), bb, i)
)
}
@@ -1797,7 +1798,7 @@ module IteratorFlow {
isIteratorWrite(writeToDeref, address) and
operandForFullyConvertedCall(address, starCall) and
bbStar.getInstruction(iStar) = starCall and
Ssa::ssaDefReachesRead(_, def.asDef(), bbStar, iStar) and
Ssa::ssaDefReachesReadExt(_, def.asDef(), bbStar, iStar) and
ultimate = getAnUltimateDefinition*(def) and
beginStore = ultimate.getValue().asInstruction() and
operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall)

View File

@@ -17,6 +17,7 @@ private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon
private import codeql.util.Unit
private import Node0ToString
import ExprNodes
/**
* The IR dataflow graph consists of the following nodes:
@@ -45,6 +46,7 @@ private newtype TIRDataFlowNode =
or
Ssa::isModifiableByCall(operand, indirectionIndex)
} or
TSsaPhiInputNode(Ssa::PhiNode phi, IRBlock input) { phi.hasInputFromBlock(_, _, _, _, input) } or
TSsaPhiNode(Ssa::PhiNode phi) or
TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
@@ -114,6 +116,13 @@ predicate conversionFlow(
instrTo.(CheckedConvertOrNullInstruction).getUnaryOperand() = opFrom
or
instrTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom
or
exists(BuiltInInstruction builtIn |
builtIn = instrTo and
// __builtin_bit_cast
builtIn.getBuiltInOperation() instanceof BuiltInBitCast and
opFrom = builtIn.getAnOperand()
)
)
or
additional = true and
@@ -158,6 +167,12 @@ class Node extends TIRDataFlowNode {
/** Gets the operands corresponding to this node, if any. */
Operand asOperand() { result = this.(OperandNode).getOperand() }
/**
* Gets the operand that is indirectly tracked by this node behind `index`
* number of indirections.
*/
Operand asIndirectOperand(int index) { hasOperandAndIndex(this, result, index) }
/**
* Holds if this node is at index `i` in basic block `block`.
*
@@ -170,6 +185,9 @@ class Node extends TIRDataFlowNode {
or
this.(SsaPhiNode).getPhiNode().getBasicBlock() = block and i = -1
or
this.(SsaPhiInputNode).getBlock() = block and
i = block.getInstructionCount()
or
this.(RawIndirectOperand).getOperand().getUse() = block.getInstruction(i)
or
this.(RawIndirectInstruction).getInstruction() = block.getInstruction(i)
@@ -622,7 +640,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
final override Location getLocationImpl() { result = phi.getBasicBlock().getLocation() }
override string toStringImpl() { result = "Phi" }
override string toStringImpl() { result = phi.toString() }
/**
* Gets a node that is used as input to this phi node.
@@ -631,7 +649,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
*/
cached
final Node getAnInput(boolean fromBackEdge) {
localFlowStep(result, this) and
result.(SsaPhiInputNode).getPhiNode() = phi and
exists(IRBlock bPhi, IRBlock bResult |
bPhi = phi.getBasicBlock() and bResult = result.getBasicBlock()
|
@@ -654,6 +672,58 @@ class SsaPhiNode extends Node, TSsaPhiNode {
predicate isPhiRead() { phi.isPhiRead() }
}
/**
* INTERNAL: Do not use.
*
* A node that is used as an input to a phi node.
*
* This class exists to allow more powerful barrier guards. Consider this
* example:
*
* ```cpp
* int x = source();
* if(!safe(x)) {
* x = clear();
* }
* // phi node for x here
* sink(x);
* ```
*
* At the phi node for `x` it is neither the case that `x` is dominated by
* `safe(x)`, or is the case that the phi is dominated by a clearing of `x`.
*
* By inserting a "phi input" node as the last entry in the basic block that
* defines the inputs to the phi we can conclude that each of those inputs are
* safe to pass to `sink`.
*/
class SsaPhiInputNode extends Node, TSsaPhiInputNode {
Ssa::PhiNode phi;
IRBlock block;
SsaPhiInputNode() { this = TSsaPhiInputNode(phi, block) }
/** Gets the phi node associated with this node. */
Ssa::PhiNode getPhiNode() { result = phi }
/** Gets the basic block in which this input originates. */
IRBlock getBlock() { result = block }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
override DataFlowType getType() { result = this.getSourceVariable().getType() }
override predicate isGLValue() { phi.getSourceVariable().isGLValue() }
final override Location getLocationImpl() { result = block.getLastInstruction().getLocation() }
override string toStringImpl() { result = "Phi input" }
/** Gets the source variable underlying this phi node. */
Ssa::SourceVariable getSourceVariable() { result = phi.getSourceVariable() }
}
/**
* INTERNAL: do not use.
*
@@ -1227,466 +1297,6 @@ class UninitializedNode extends Node {
LocalVariable getLocalVariable() { result = v }
}
private module GetConvertedResultExpression {
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
private Operand getAnInitializeDynamicAllocationInstructionAddress() {
result = any(InitializeDynamicAllocationInstruction init).getAllocationAddressOperand()
}
/**
* Gets the expression that should be returned as the result expression from `instr`.
*
* Note that this predicate may return multiple results in cases where a conversion belongs to a
* different AST element than its operand.
*/
Expr getConvertedResultExpression(Instruction instr, int n) {
// Only fully converted instructions have a result for `asConvertedExpr`
not conversionFlow(unique(Operand op |
// The address operand of a `InitializeDynamicAllocationInstruction` is
// special: we need to handle it during dataflow (since it's
// effectively a store to an indirection), but it doesn't appear in
// source syntax, so dataflow node <-> expression conversion shouldn't
// care about it.
op = getAUse(instr) and not op = getAnInitializeDynamicAllocationInstructionAddress()
|
op
), _, false, false) and
result = getConvertedResultExpressionImpl(instr) and
n = 0
or
// If the conversion also has a result then we return multiple results
exists(Operand operand | conversionFlow(operand, instr, false, false) |
n = 1 and
result = getConvertedResultExpressionImpl(operand.getDef())
or
result = getConvertedResultExpression(operand.getDef(), n - 1)
)
}
private Expr getConvertedResultExpressionImpl0(Instruction instr) {
// IR construction inserts an additional cast to a `size_t` on the extent
// of a `new[]` expression. The resulting `ConvertInstruction` doesn't have
// a result for `getConvertedResultExpression`. We remap this here so that
// this `ConvertInstruction` maps to the result of the expression that
// represents the extent.
exists(TranslatedNonConstantAllocationSize tas |
result = tas.getExtent().getExpr() and
instr = tas.getInstruction(AllocationExtentConvertTag())
)
or
// There's no instruction that returns `ParenthesisExpr`, but some queries
// expect this
exists(TranslatedTransparentConversion ttc |
result = ttc.getExpr().(ParenthesisExpr) and
instr = ttc.getResult()
)
or
// Certain expressions generate `CopyValueInstruction`s only when they
// are needed. Examples of this include crement operations and compound
// assignment operations. For example:
// ```cpp
// int x = ...
// int y = x++;
// ```
// this generate IR like:
// ```
// r1(glval<int>) = VariableAddress[x] :
// r2(int) = Constant[0] :
// m3(int) = Store[x] : &:r1, r2
// r4(glval<int>) = VariableAddress[y] :
// r5(glval<int>) = VariableAddress[x] :
// r6(int) = Load[x] : &:r5, m3
// r7(int) = Constant[1] :
// r8(int) = Add : r6, r7
// m9(int) = Store[x] : &:r5, r8
// r11(int) = CopyValue : r6
// m12(int) = Store[y] : &:r4, r11
// ```
// When the `CopyValueInstruction` is not generated there is no instruction
// whose `getConvertedResultExpression` maps back to the expression. When
// such an instruction doesn't exist it means that the old value is not
// needed, and in that case the only value that will propagate forward in
// the program is the value that's been updated. So in those cases we just
// use the result of `node.asDefinition()` as the result of `node.asExpr()`.
exists(TranslatedCoreExpr tco |
tco.getInstruction(_) = instr and
tco.producesExprResult() and
result = asDefinitionImpl0(instr)
)
}
private Expr getConvertedResultExpressionImpl(Instruction instr) {
result = getConvertedResultExpressionImpl0(instr)
or
not exists(getConvertedResultExpressionImpl0(instr)) and
result = instr.getConvertedResultExpression()
}
/**
* Gets the result for `node.asDefinition()` (when `node` is the instruction
* node that wraps `store`) in the cases where `store.getAst()` should not be
* used to define the result of `node.asDefinition()`.
*/
private Expr asDefinitionImpl0(StoreInstruction store) {
// For an expression such as `i += 2` we pretend that the generated
// `StoreInstruction` contains the result of the expression even though
// this isn't totally aligned with the C/C++ standard.
exists(TranslatedAssignOperation tao |
store = tao.getInstruction(AssignmentStoreTag()) and
result = tao.getExpr()
)
or
// Similarly for `i++` and `++i` we pretend that the generated
// `StoreInstruction` is contains the result of the expression even though
// this isn't totally aligned with the C/C++ standard.
exists(TranslatedCrementOperation tco |
store = tco.getInstruction(CrementStoreTag()) and
result = tco.getExpr()
)
}
/**
* Holds if the expression returned by `store.getAst()` should not be
* returned as the result of `node.asDefinition()` when `node` is the
* instruction node that wraps `store`.
*/
private predicate excludeAsDefinitionResult(StoreInstruction store) {
// Exclude the store to the temporary generated by a ternary expression.
exists(TranslatedConditionalExpr tce |
store = tce.getInstruction(ConditionValueFalseStoreTag())
or
store = tce.getInstruction(ConditionValueTrueStoreTag())
)
}
/**
* Gets the expression that represents the result of `StoreInstruction` for
* dataflow purposes.
*
* For example, consider the following example
* ```cpp
* int x = 42; // 1
* x = 34; // 2
* ++x; // 3
* x++; // 4
* x += 1; // 5
* int y = x += 2; // 6
* ```
* For (1) the result is `42`.
* For (2) the result is `x = 34`.
* For (3) the result is `++x`.
* For (4) the result is `x++`.
* For (5) the result is `x += 1`.
* For (6) there are two results:
* - For the `StoreInstruction` generated by `x += 2` the result
* is `x += 2`
* - For the `StoreInstruction` generated by `int y = ...` the result
* is also `x += 2`
*/
Expr asDefinitionImpl(StoreInstruction store) {
not exists(asDefinitionImpl0(store)) and
not excludeAsDefinitionResult(store) and
result = store.getAst().(Expr).getUnconverted()
or
result = asDefinitionImpl0(store)
}
}
private import GetConvertedResultExpression
/** Holds if `node` is an `OperandNode` that should map `node.asExpr()` to `e`. */
predicate exprNodeShouldBeOperand(OperandNode node, Expr e, int n) {
not exprNodeShouldBeIndirectOperand(_, e, n) and
exists(Instruction def |
unique( | | getAUse(def)) = node.getOperand() and
e = getConvertedResultExpression(def, n)
)
}
/** Holds if `node` should be an `IndirectOperand` that maps `node.asIndirectExpr()` to `e`. */
private predicate indirectExprNodeShouldBeIndirectOperand(
IndirectOperand node, Expr e, int n, int indirectionIndex
) {
exists(Instruction def |
node.hasOperandAndIndirectionIndex(unique( | | getAUse(def)), indirectionIndex) and
e = getConvertedResultExpression(def, n)
)
}
/** Holds if `node` should be an `IndirectOperand` that maps `node.asExpr()` to `e`. */
private predicate exprNodeShouldBeIndirectOperand(IndirectOperand node, Expr e, int n) {
exists(ArgumentOperand operand |
// When an argument (qualifier or positional) is a prvalue and the
// parameter (qualifier or positional) is a (const) reference, IR
// construction introduces a temporary `IRVariable`. The `VariableAddress`
// instruction has the argument as its `getConvertedResultExpression`
// result. However, the instruction actually represents the _address_ of
// the argument. So to fix this mismatch, we have the indirection of the
// `VariableAddressInstruction` map to the expression.
node.hasOperandAndIndirectionIndex(operand, 1) and
e = getConvertedResultExpression(operand.getDef(), n) and
operand.getDef().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable
)
}
private predicate exprNodeShouldBeIndirectOutNode(IndirectArgumentOutNode node, Expr e, int n) {
exists(CallInstruction call |
call.getStaticCallTarget() instanceof Constructor and
e = getConvertedResultExpression(call, n) and
call.getThisArgumentOperand() = node.getAddressOperand()
)
}
/** Holds if `node` should be an instruction node that maps `node.asExpr()` to `e`. */
predicate exprNodeShouldBeInstruction(Node node, Expr e, int n) {
not exprNodeShouldBeOperand(_, e, n) and
not exprNodeShouldBeIndirectOutNode(_, e, n) and
not exprNodeShouldBeIndirectOperand(_, e, n) and
e = getConvertedResultExpression(node.asInstruction(), n)
}
/** Holds if `node` should be an `IndirectInstruction` that maps `node.asIndirectExpr()` to `e`. */
predicate indirectExprNodeShouldBeIndirectInstruction(
IndirectInstruction node, Expr e, int n, int indirectionIndex
) {
not indirectExprNodeShouldBeIndirectOperand(_, e, n, indirectionIndex) and
exists(Instruction instr |
node.hasInstructionAndIndirectionIndex(instr, indirectionIndex) and
e = getConvertedResultExpression(instr, n)
)
}
abstract private class ExprNodeBase extends Node {
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
abstract Expr getConvertedExpr(int n);
/** Gets the non-conversion expression corresponding to this node, if any. */
final Expr getExpr(int n) { result = this.getConvertedExpr(n).getUnconverted() }
}
/**
* Holds if there exists a dataflow node whose `asExpr(n)` should evaluate
* to `e`.
*/
private predicate exprNodeShouldBe(Expr e, int n) {
exprNodeShouldBeInstruction(_, e, n) or
exprNodeShouldBeOperand(_, e, n) or
exprNodeShouldBeIndirectOutNode(_, e, n) or
exprNodeShouldBeIndirectOperand(_, e, n)
}
private class InstructionExprNode extends ExprNodeBase, InstructionNode {
InstructionExprNode() {
exists(Expr e, int n |
exprNodeShouldBeInstruction(this, e, n) and
not exists(Expr conv |
exprNodeShouldBe(conv, n + 1) and
conv.getUnconverted() = e.getUnconverted()
)
)
}
final override Expr getConvertedExpr(int n) { exprNodeShouldBeInstruction(this, result, n) }
}
private class OperandExprNode extends ExprNodeBase, OperandNode {
OperandExprNode() {
exists(Expr e, int n |
exprNodeShouldBeOperand(this, e, n) and
not exists(Expr conv |
exprNodeShouldBe(conv, n + 1) and
conv.getUnconverted() = e.getUnconverted()
)
)
}
final override Expr getConvertedExpr(int n) { exprNodeShouldBeOperand(this, result, n) }
}
abstract private class IndirectExprNodeBase extends Node {
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
abstract Expr getConvertedExpr(int n, int indirectionIndex);
/** Gets the non-conversion expression corresponding to this node, if any. */
final Expr getExpr(int n, int indirectionIndex) {
result = this.getConvertedExpr(n, indirectionIndex).getUnconverted()
}
}
/** A signature for converting an indirect node to an expression. */
private signature module IndirectNodeToIndirectExprSig {
/** The indirect node class to be converted to an expression */
class IndirectNode;
/**
* Holds if the indirect expression at indirection index `indirectionIndex`
* of `node` is `e`. The integer `n` specifies how many conversions has been
* applied to `node`.
*/
predicate indirectNodeHasIndirectExpr(IndirectNode node, Expr e, int n, int indirectionIndex);
}
/**
* A module that implements the logic for deciding whether an indirect node
* should be an `IndirectExprNode`.
*/
private module IndirectNodeToIndirectExpr<IndirectNodeToIndirectExprSig Sig> {
import Sig
/**
* This predicate shifts the indirection index by one when `conv` is a
* `ReferenceDereferenceExpr`.
*
* This is necessary because `ReferenceDereferenceExpr` is a conversion
* in the AST, but appears as a `LoadInstruction` in the IR.
*/
bindingset[e, indirectionIndex]
private predicate adjustForReference(
Expr e, int indirectionIndex, Expr conv, int adjustedIndirectionIndex
) {
conv.(ReferenceDereferenceExpr).getExpr() = e and
adjustedIndirectionIndex = indirectionIndex - 1
or
not conv instanceof ReferenceDereferenceExpr and
conv = e and
adjustedIndirectionIndex = indirectionIndex
}
/** Holds if `node` should be an `IndirectExprNode`. */
predicate charpred(IndirectNode node) {
exists(Expr e, int n, int indirectionIndex |
indirectNodeHasIndirectExpr(node, e, n, indirectionIndex) and
not exists(Expr conv, int adjustedIndirectionIndex |
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
indirectExprNodeShouldBe(conv, n + 1, adjustedIndirectionIndex)
)
)
}
}
private predicate indirectExprNodeShouldBe(Expr e, int n, int indirectionIndex) {
indirectExprNodeShouldBeIndirectOperand(_, e, n, indirectionIndex) or
indirectExprNodeShouldBeIndirectInstruction(_, e, n, indirectionIndex)
}
private module IndirectOperandIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
class IndirectNode = IndirectOperand;
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectOperand/4;
}
module IndirectOperandToIndirectExpr =
IndirectNodeToIndirectExpr<IndirectOperandIndirectExprNodeImpl>;
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
{
IndirectOperandIndirectExprNode() { IndirectOperandToIndirectExpr::charpred(this) }
final override Expr getConvertedExpr(int n, int index) {
IndirectOperandToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
}
}
private module IndirectInstructionIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
class IndirectNode = IndirectInstruction;
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectInstruction/4;
}
module IndirectInstructionToIndirectExpr =
IndirectNodeToIndirectExpr<IndirectInstructionIndirectExprNodeImpl>;
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
{
IndirectInstructionIndirectExprNode() { IndirectInstructionToIndirectExpr::charpred(this) }
final override Expr getConvertedExpr(int n, int index) {
IndirectInstructionToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
}
}
private class IndirectArgumentOutExprNode extends ExprNodeBase, IndirectArgumentOutNode {
IndirectArgumentOutExprNode() { exprNodeShouldBeIndirectOutNode(this, _, _) }
final override Expr getConvertedExpr(int n) { exprNodeShouldBeIndirectOutNode(this, result, n) }
}
private class IndirectOperandExprNode extends ExprNodeBase instanceof IndirectOperand {
IndirectOperandExprNode() { exprNodeShouldBeIndirectOperand(this, _, _) }
final override Expr getConvertedExpr(int n) { exprNodeShouldBeIndirectOperand(this, result, n) }
}
/**
* An expression, viewed as a node in a data flow graph.
*/
class ExprNode extends Node instanceof ExprNodeBase {
/**
* INTERNAL: Do not use.
*/
Expr getExpr(int n) { result = super.getExpr(n) }
/**
* Gets the non-conversion expression corresponding to this node, if any. If
* this node strictly (in the sense of `getConvertedExpr`) corresponds to a
* `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
* expression.
*/
final Expr getExpr() { result = this.getExpr(_) }
/**
* INTERNAL: Do not use.
*/
Expr getConvertedExpr(int n) { result = super.getConvertedExpr(n) }
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
final Expr getConvertedExpr() { result = this.getConvertedExpr(_) }
}
/**
* An indirect expression, viewed as a node in a data flow graph.
*/
class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
/**
* Gets the non-conversion expression corresponding to this node, if any. If
* this node strictly (in the sense of `getConvertedExpr`) corresponds to a
* `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
* expression.
*/
final Expr getExpr(int indirectionIndex) { result = this.getExpr(_, indirectionIndex) }
/**
* INTERNAL: Do not use.
*/
Expr getExpr(int n, int indirectionIndex) { result = super.getExpr(n, indirectionIndex) }
/**
* INTERNAL: Do not use.
*/
Expr getConvertedExpr(int n, int indirectionIndex) {
result = super.getConvertedExpr(n, indirectionIndex)
}
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
Expr getConvertedExpr(int indirectionIndex) {
result = this.getConvertedExpr(_, indirectionIndex)
}
}
abstract private class AbstractParameterNode extends Node {
/**
* Holds if this node is the parameter of `f` at the specified position. The
@@ -2176,6 +1786,9 @@ private module Cached {
// Def-use/Use-use flow
Ssa::ssaFlow(nodeFrom, nodeTo)
or
// Phi input -> Phi
nodeFrom.(SsaPhiInputNode).getPhiNode() = nodeTo.(SsaPhiNode).getPhiNode()
or
IteratorFlow::localFlowStep(nodeFrom, nodeTo)
or
// Operand -> Instruction flow
@@ -2614,6 +2227,22 @@ class ContentSet instanceof Content {
}
}
pragma[nomagic]
private predicate guardControlsPhiInput(
IRGuardCondition g, boolean branch, Ssa::Definition def, IRBlock input, Ssa::PhiNode phi
) {
phi.hasInputFromBlock(def, _, _, _, input) and
(
g.controls(input, branch)
or
exists(EdgeKind kind |
g.getBlock() = input and
kind = getConditionalEdge(branch) and
input.getSuccessor(kind) = phi.getBasicBlock()
)
)
}
/**
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
*
@@ -2662,13 +2291,21 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
*/
ExprNode getABarrierNode() {
Node getABarrierNode() {
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
e = value.getAnInstruction().getConvertedResultExpression() and
result.getConvertedExpr() = e and
result.asConvertedExpr() = e and
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
g.controls(result.getBasicBlock(), edge)
)
or
exists(
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
guardChecks(g, def.getARead().asOperand().getDef().getConvertedResultExpression(), branch) and
guardControlsPhiInput(g, branch, def, input, phi) and
result = TSsaPhiInputNode(phi, input)
)
}
/**
@@ -2704,7 +2341,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
IndirectExprNode getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
/**
* Gets an indirect expression node with indirection index `indirectionIndex` that is
@@ -2740,13 +2377,23 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
IndirectExprNode getAnIndirectBarrierNode(int indirectionIndex) {
Node getAnIndirectBarrierNode(int indirectionIndex) {
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
e = value.getAnInstruction().getConvertedResultExpression() and
result.getConvertedExpr(indirectionIndex) = e and
result.asIndirectConvertedExpr(indirectionIndex) = e and
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
g.controls(result.getBasicBlock(), edge)
)
or
exists(
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
guardChecks(g,
def.getARead().asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(),
branch) and
guardControlsPhiInput(g, branch, def, input, phi) and
result = TSsaPhiInputNode(phi, input)
)
}
}
@@ -2755,6 +2402,14 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*/
signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction instr, boolean branch);
private EdgeKind getConditionalEdge(boolean branch) {
branch = true and
result instanceof TrueEdge
or
branch = false and
result instanceof FalseEdge
}
/**
* Provides a set of barrier nodes for a guard that validates an instruction.
*
@@ -2763,12 +2418,20 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
*/
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
ExprNode getABarrierNode() {
Node getABarrierNode() {
exists(IRGuardCondition g, ValueNumber value, boolean edge, Operand use |
instructionGuardChecks(g, value.getAnInstruction(), edge) and
use = value.getAnInstruction().getAUse() and
result.asOperand() = use and
g.controls(use.getDef().getBlock(), edge)
g.controls(result.getBasicBlock(), edge)
)
or
exists(
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
instructionGuardChecks(g, def.getARead().asOperand().getDef(), branch) and
guardControlsPhiInput(g, branch, def, input, phi) and
result = TSsaPhiInputNode(phi, input)
)
}
}

View File

@@ -0,0 +1,518 @@
/**
* Provides the classes `ExprNode` and `IndirectExprNode` for converting between `Expr` and `Node`.
*/
private import cpp
private import semmle.code.cpp.ir.IR
private import DataFlowUtil
private import DataFlowPrivate
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
cached
private module Cached {
private Operand getAnInitializeDynamicAllocationInstructionAddress() {
result = any(InitializeDynamicAllocationInstruction init).getAllocationAddressOperand()
}
/**
* Gets the expression that should be returned as the result expression from `instr`.
*
* Note that this predicate may return multiple results in cases where a conversion belongs to a
* different AST element than its operand.
*/
private Expr getConvertedResultExpression(Instruction instr, int n) {
// Only fully converted instructions have a result for `asConvertedExpr`
not conversionFlow(unique(Operand op |
// The address operand of a `InitializeDynamicAllocationInstruction` is
// special: we need to handle it during dataflow (since it's
// effectively a store to an indirection), but it doesn't appear in
// source syntax, so dataflow node <-> expression conversion shouldn't
// care about it.
op = getAUse(instr) and not op = getAnInitializeDynamicAllocationInstructionAddress()
|
op
), _, false, false) and
result = getConvertedResultExpressionImpl(instr) and
n = 0
or
// If the conversion also has a result then we return multiple results
exists(Operand operand | conversionFlow(operand, instr, false, false) |
n = 1 and
result = getConvertedResultExpressionImpl(operand.getDef())
or
result = getConvertedResultExpression(operand.getDef(), n - 1)
)
}
private Expr getConvertedResultExpressionImpl0(Instruction instr) {
// IR construction inserts an additional cast to a `size_t` on the extent
// of a `new[]` expression. The resulting `ConvertInstruction` doesn't have
// a result for `getConvertedResultExpression`. We remap this here so that
// this `ConvertInstruction` maps to the result of the expression that
// represents the extent.
exists(TranslatedNonConstantAllocationSize tas |
result = tas.getExtent().getExpr() and
instr = tas.getInstruction(AllocationExtentConvertTag())
)
or
// There's no instruction that returns `ParenthesisExpr`, but some queries
// expect this
exists(TranslatedTransparentConversion ttc |
result = ttc.getExpr().(ParenthesisExpr) and
instr = ttc.getResult()
)
or
// Certain expressions generate `CopyValueInstruction`s only when they
// are needed. Examples of this include crement operations and compound
// assignment operations. For example:
// ```cpp
// int x = ...
// int y = x++;
// ```
// this generate IR like:
// ```
// r1(glval<int>) = VariableAddress[x] :
// r2(int) = Constant[0] :
// m3(int) = Store[x] : &:r1, r2
// r4(glval<int>) = VariableAddress[y] :
// r5(glval<int>) = VariableAddress[x] :
// r6(int) = Load[x] : &:r5, m3
// r7(int) = Constant[1] :
// r8(int) = Add : r6, r7
// m9(int) = Store[x] : &:r5, r8
// r11(int) = CopyValue : r6
// m12(int) = Store[y] : &:r4, r11
// ```
// When the `CopyValueInstruction` is not generated there is no instruction
// whose `getConvertedResultExpression` maps back to the expression. When
// such an instruction doesn't exist it means that the old value is not
// needed, and in that case the only value that will propagate forward in
// the program is the value that's been updated. So in those cases we just
// use the result of `node.asDefinition()` as the result of `node.asExpr()`.
exists(TranslatedCoreExpr tco |
tco.getInstruction(_) = instr and
tco.producesExprResult() and
result = asDefinitionImpl0(instr)
)
}
private Expr getConvertedResultExpressionImpl(Instruction instr) {
result = getConvertedResultExpressionImpl0(instr)
or
not exists(getConvertedResultExpressionImpl0(instr)) and
result = instr.getConvertedResultExpression()
}
/**
* Gets the result for `node.asDefinition()` (when `node` is the instruction
* node that wraps `store`) in the cases where `store.getAst()` should not be
* used to define the result of `node.asDefinition()`.
*/
private Expr asDefinitionImpl0(StoreInstruction store) {
// For an expression such as `i += 2` we pretend that the generated
// `StoreInstruction` contains the result of the expression even though
// this isn't totally aligned with the C/C++ standard.
exists(TranslatedAssignOperation tao |
store = tao.getInstruction(AssignmentStoreTag()) and
result = tao.getExpr()
)
or
// Similarly for `i++` and `++i` we pretend that the generated
// `StoreInstruction` is contains the result of the expression even though
// this isn't totally aligned with the C/C++ standard.
exists(TranslatedCrementOperation tco |
store = tco.getInstruction(CrementStoreTag()) and
result = tco.getExpr()
)
}
/**
* Holds if the expression returned by `store.getAst()` should not be
* returned as the result of `node.asDefinition()` when `node` is the
* instruction node that wraps `store`.
*/
private predicate excludeAsDefinitionResult(StoreInstruction store) {
// Exclude the store to the temporary generated by a ternary expression.
exists(TranslatedConditionalExpr tce |
store = tce.getInstruction(ConditionValueFalseStoreTag())
or
store = tce.getInstruction(ConditionValueTrueStoreTag())
)
}
/**
* Gets the expression that represents the result of `StoreInstruction` for
* dataflow purposes.
*
* For example, consider the following example
* ```cpp
* int x = 42; // 1
* x = 34; // 2
* ++x; // 3
* x++; // 4
* x += 1; // 5
* int y = x += 2; // 6
* ```
* For (1) the result is `42`.
* For (2) the result is `x = 34`.
* For (3) the result is `++x`.
* For (4) the result is `x++`.
* For (5) the result is `x += 1`.
* For (6) there are two results:
* - For the `StoreInstruction` generated by `x += 2` the result
* is `x += 2`
* - For the `StoreInstruction` generated by `int y = ...` the result
* is also `x += 2`
*/
cached
Expr asDefinitionImpl(StoreInstruction store) {
not exists(asDefinitionImpl0(store)) and
not excludeAsDefinitionResult(store) and
result = store.getAst().(Expr).getUnconverted()
or
result = asDefinitionImpl0(store)
}
/** Holds if `node` is an `OperandNode` that should map `node.asExpr()` to `e`. */
private predicate exprNodeShouldBeOperand(OperandNode node, Expr e, int n) {
not exprNodeShouldBeIndirectOperand(_, e, n) and
exists(Instruction def |
unique( | | getAUse(def)) = node.getOperand() and
e = getConvertedResultExpression(def, n)
)
}
/** Holds if `node` should be an `IndirectOperand` that maps `node.asIndirectExpr()` to `e`. */
private predicate indirectExprNodeShouldBeIndirectOperand(
IndirectOperand node, Expr e, int n, int indirectionIndex
) {
exists(Instruction def |
node.hasOperandAndIndirectionIndex(unique( | | getAUse(def)), indirectionIndex) and
e = getConvertedResultExpression(def, n)
)
}
/** Holds if `operand`'s definition is a `VariableAddressInstruction` whose variable is a temporary */
private predicate isIRTempVariable(Operand operand) {
operand.getDef().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable
}
/**
* Holds if `node` is an indirect operand whose operand is an argument, and
* the `n`'th expression associated with the operand is `e`.
*/
private predicate isIndirectOperandOfArgument(
IndirectOperand node, ArgumentOperand operand, Expr e, int n
) {
node.hasOperandAndIndirectionIndex(operand, 1) and
e = getConvertedResultExpression(operand.getDef(), n)
}
/**
* Holds if `opFrom` is an operand to a conversion, and `opTo` is the unique
* use of the conversion.
*/
private predicate isConversionStep(Operand opFrom, Operand opTo) {
exists(Instruction mid |
conversionFlow(opFrom, mid, false, false) and
opTo = unique( | | getAUse(mid))
)
}
/**
* Holds if an operand that satisfies `isIRTempVariable` flows to `op`
* through a (possibly empty) sequence of conversions.
*/
private predicate irTempOperandConversionFlows(Operand op) {
isIRTempVariable(op)
or
exists(Operand mid |
irTempOperandConversionFlows(mid) and
isConversionStep(mid, op)
)
}
/** Holds if `node` should be an `IndirectOperand` that maps `node.asExpr()` to `e`. */
private predicate exprNodeShouldBeIndirectOperand(IndirectOperand node, Expr e, int n) {
exists(ArgumentOperand operand |
// When an argument (qualifier or positional) is a prvalue and the
// parameter (qualifier or positional) is a (const) reference, IR
// construction introduces a temporary `IRVariable`. The `VariableAddress`
// instruction has the argument as its `getConvertedResultExpression`
// result. However, the instruction actually represents the _address_ of
// the argument. So to fix this mismatch, we have the indirection of the
// `VariableAddressInstruction` map to the expression.
isIndirectOperandOfArgument(node, operand, e, n) and
irTempOperandConversionFlows(operand)
)
}
private predicate exprNodeShouldBeIndirectOutNode(IndirectArgumentOutNode node, Expr e, int n) {
exists(CallInstruction call |
call.getStaticCallTarget() instanceof Constructor and
e = getConvertedResultExpression(call, n) and
call.getThisArgumentOperand() = node.getAddressOperand()
)
}
/** Holds if `node` should be an instruction node that maps `node.asExpr()` to `e`. */
private predicate exprNodeShouldBeInstruction(Node node, Expr e, int n) {
not exprNodeShouldBeOperand(_, e, n) and
not exprNodeShouldBeIndirectOutNode(_, e, n) and
not exprNodeShouldBeIndirectOperand(_, e, n) and
e = getConvertedResultExpression(node.asInstruction(), n)
}
/** Holds if `node` should be an `IndirectInstruction` that maps `node.asIndirectExpr()` to `e`. */
private predicate indirectExprNodeShouldBeIndirectInstruction(
IndirectInstruction node, Expr e, int n, int indirectionIndex
) {
not indirectExprNodeShouldBeIndirectOperand(_, e, n, indirectionIndex) and
exists(Instruction instr |
node.hasInstructionAndIndirectionIndex(instr, indirectionIndex) and
e = getConvertedResultExpression(instr, n)
)
}
abstract private class ExprNodeBase extends Node {
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
abstract Expr getConvertedExpr(int n);
/** Gets the non-conversion expression corresponding to this node, if any. */
final Expr getExpr(int n) { result = this.getConvertedExpr(n).getUnconverted() }
}
/**
* Holds if there exists a dataflow node whose `asExpr(n)` should evaluate
* to `e`.
*/
private predicate exprNodeShouldBe(Expr e, int n) {
exprNodeShouldBeInstruction(_, e, n) or
exprNodeShouldBeOperand(_, e, n) or
exprNodeShouldBeIndirectOutNode(_, e, n) or
exprNodeShouldBeIndirectOperand(_, e, n)
}
private class InstructionExprNode extends ExprNodeBase, InstructionNode {
InstructionExprNode() {
exists(Expr e, int n |
exprNodeShouldBeInstruction(this, e, n) and
not exists(Expr conv |
exprNodeShouldBe(conv, n + 1) and
conv.getUnconverted() = e.getUnconverted()
)
)
}
final override Expr getConvertedExpr(int n) { exprNodeShouldBeInstruction(this, result, n) }
}
private class OperandExprNode extends ExprNodeBase, OperandNode {
OperandExprNode() {
exists(Expr e, int n |
exprNodeShouldBeOperand(this, e, n) and
not exists(Expr conv |
exprNodeShouldBe(conv, n + 1) and
conv.getUnconverted() = e.getUnconverted()
)
)
}
final override Expr getConvertedExpr(int n) { exprNodeShouldBeOperand(this, result, n) }
}
abstract private class IndirectExprNodeBase extends Node {
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
abstract Expr getConvertedExpr(int n, int indirectionIndex);
/** Gets the non-conversion expression corresponding to this node, if any. */
final Expr getExpr(int n, int indirectionIndex) {
result = this.getConvertedExpr(n, indirectionIndex).getUnconverted()
}
}
/** A signature for converting an indirect node to an expression. */
private signature module IndirectNodeToIndirectExprSig {
/** The indirect node class to be converted to an expression */
class IndirectNode;
/**
* Holds if the indirect expression at indirection index `indirectionIndex`
* of `node` is `e`. The integer `n` specifies how many conversions has been
* applied to `node`.
*/
predicate indirectNodeHasIndirectExpr(IndirectNode node, Expr e, int n, int indirectionIndex);
}
/**
* A module that implements the logic for deciding whether an indirect node
* should be an `IndirectExprNode`.
*/
private module IndirectNodeToIndirectExpr<IndirectNodeToIndirectExprSig Sig> {
import Sig
/**
* This predicate shifts the indirection index by one when `conv` is a
* `ReferenceDereferenceExpr`.
*
* This is necessary because `ReferenceDereferenceExpr` is a conversion
* in the AST, but appears as a `LoadInstruction` in the IR.
*/
bindingset[e, indirectionIndex]
private predicate adjustForReference(
Expr e, int indirectionIndex, Expr conv, int adjustedIndirectionIndex
) {
conv.(ReferenceDereferenceExpr).getExpr() = e and
adjustedIndirectionIndex = indirectionIndex - 1
or
not conv instanceof ReferenceDereferenceExpr and
conv = e and
adjustedIndirectionIndex = indirectionIndex
}
/** Holds if `node` should be an `IndirectExprNode`. */
predicate charpred(IndirectNode node) {
exists(Expr e, int n, int indirectionIndex |
indirectNodeHasIndirectExpr(node, e, n, indirectionIndex) and
not exists(Expr conv, int adjustedIndirectionIndex |
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
indirectExprNodeShouldBe(conv, n + 1, adjustedIndirectionIndex)
)
)
}
}
private predicate indirectExprNodeShouldBe(Expr e, int n, int indirectionIndex) {
indirectExprNodeShouldBeIndirectOperand(_, e, n, indirectionIndex) or
indirectExprNodeShouldBeIndirectInstruction(_, e, n, indirectionIndex)
}
private module IndirectOperandIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
class IndirectNode = IndirectOperand;
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectOperand/4;
}
module IndirectOperandToIndirectExpr =
IndirectNodeToIndirectExpr<IndirectOperandIndirectExprNodeImpl>;
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
{
IndirectOperandIndirectExprNode() { IndirectOperandToIndirectExpr::charpred(this) }
final override Expr getConvertedExpr(int n, int index) {
IndirectOperandToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
}
}
private module IndirectInstructionIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
class IndirectNode = IndirectInstruction;
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectInstruction/4;
}
module IndirectInstructionToIndirectExpr =
IndirectNodeToIndirectExpr<IndirectInstructionIndirectExprNodeImpl>;
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
{
IndirectInstructionIndirectExprNode() { IndirectInstructionToIndirectExpr::charpred(this) }
final override Expr getConvertedExpr(int n, int index) {
IndirectInstructionToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
}
}
private class IndirectArgumentOutExprNode extends ExprNodeBase, IndirectArgumentOutNode {
IndirectArgumentOutExprNode() { exprNodeShouldBeIndirectOutNode(this, _, _) }
final override Expr getConvertedExpr(int n) { exprNodeShouldBeIndirectOutNode(this, result, n) }
}
private class IndirectOperandExprNode extends ExprNodeBase instanceof IndirectOperand {
IndirectOperandExprNode() { exprNodeShouldBeIndirectOperand(this, _, _) }
final override Expr getConvertedExpr(int n) { exprNodeShouldBeIndirectOperand(this, result, n) }
}
/**
* An expression, viewed as a node in a data flow graph.
*/
cached
class ExprNode extends Node instanceof ExprNodeBase {
/**
* INTERNAL: Do not use.
*/
cached
Expr getExpr(int n) { result = super.getExpr(n) }
/**
* Gets the non-conversion expression corresponding to this node, if any. If
* this node strictly (in the sense of `getConvertedExpr`) corresponds to a
* `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
* expression.
*/
cached
final Expr getExpr() { result = this.getExpr(_) }
/**
* INTERNAL: Do not use.
*/
cached
Expr getConvertedExpr(int n) { result = super.getConvertedExpr(n) }
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
cached
final Expr getConvertedExpr() { result = this.getConvertedExpr(_) }
}
/**
* An indirect expression, viewed as a node in a data flow graph.
*/
cached
class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
/**
* Gets the non-conversion expression corresponding to this node, if any. If
* this node strictly (in the sense of `getConvertedExpr`) corresponds to a
* `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
* expression.
*/
cached
final Expr getExpr(int indirectionIndex) { result = this.getExpr(_, indirectionIndex) }
/**
* INTERNAL: Do not use.
*/
cached
Expr getExpr(int n, int indirectionIndex) { result = super.getExpr(n, indirectionIndex) }
/**
* INTERNAL: Do not use.
*/
cached
Expr getConvertedExpr(int n, int indirectionIndex) {
result = super.getConvertedExpr(n, indirectionIndex)
}
/**
* Gets the expression corresponding to this node, if any. The returned
* expression may be a `Conversion`.
*/
cached
Expr getConvertedExpr(int indirectionIndex) {
result = this.getConvertedExpr(_, indirectionIndex)
}
}
}
import Cached

View File

@@ -657,19 +657,9 @@ class GlobalDefImpl extends DefImpl, TGlobalDefImpl {
*/
predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) {
adjacentDefReadExt(_, sv, bb1, i1, bb2, i2)
or
exists(PhiNode phi |
lastRefRedefExt(_, sv, bb1, i1, phi) and
phi.definesAt(sv, bb2, i2, _)
)
}
predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) {
exists(Phi phi |
phi.asPhi().definesAt(sv, bb, i, _) and
nodeTo = phi.getNode()
)
or
exists(UseImpl use |
use.hasIndexInBlock(bb, i, sv) and
nodeTo = use.getNode()
@@ -723,46 +713,26 @@ predicate nodeToDefOrUse(Node node, SourceVariable sv, IRBlock bb, int i, boolea
*/
private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
not exists(SourceVariable sv, IRBlock bb2, int i2 |
nodeToDefOrUse(nTo, sv, bb2, i2, _) and
useToNode(bb2, i2, sv, nTo) and
adjacentDefRead(bb2, i2, sv, _, _)
) and
(
exists(Operand op1, Operand op2, int indirectionIndex, Instruction instr |
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
hasOperandAndIndex(nTo, op2, pragma[only_bind_into](indirectionIndex)) and
instr = op2.getDef() and
conversionFlow(op1, instr, _, _)
)
or
exists(Operand op1, Operand op2, int indirectionIndex, Instruction instr |
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
hasOperandAndIndex(nTo, op2, indirectionIndex - 1) and
instr = op2.getDef() and
isDereference(instr, op1, _)
)
exists(Operand op1, Operand op2, int indirectionIndex, Instruction instr |
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
hasOperandAndIndex(nTo, op2, pragma[only_bind_into](indirectionIndex)) and
instr = op2.getDef() and
conversionFlow(op1, instr, _, _)
)
}
/**
* The reason for this predicate is a bit annoying:
* We cannot mark a `PointerArithmeticInstruction` that computes an offset based on some SSA
* variable `x` as a use of `x` since this creates taint-flow in the following example:
* ```c
* int x = array[source]
* sink(*array)
* ```
* This is because `source` would flow from the operand of `PointerArithmeticInstruction` to the
* result of the instruction, and into the `IndirectOperand` that represents the value of `*array`.
* Then, via use-use flow, flow will arrive at `*array` in `sink(*array)`.
*
* So this predicate recurses back along conversions and `PointerArithmeticInstruction`s to find the
* first use that has provides use-use flow, and uses that target as the target of the `nodeFrom`.
* Holds if `node` is a phi input node that should receive flow from the
* definition to (or use of) `sv` at `(bb1, i1)`.
*/
private predicate adjustForPointerArith(PostUpdateNode pun, SourceVariable sv, IRBlock bb2, int i2) {
exists(IRBlock bb1, int i1, Node adjusted |
indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and
nodeToDefOrUse(adjusted, sv, bb1, i1, _) and
adjacentDefRead(bb1, i1, sv, bb2, i2)
private predicate phiToNode(SsaPhiInputNode node, SourceVariable sv, IRBlock bb1, int i1) {
exists(PhiNode phi, IRBlock input |
phi.hasInputFromBlock(_, sv, bb1, i1, input) and
node.getPhiNode() = phi and
node.getBlock() = input
)
}
@@ -777,10 +747,14 @@ private predicate adjustForPointerArith(PostUpdateNode pun, SourceVariable sv, I
private predicate ssaFlowImpl(
IRBlock bb1, int i1, SourceVariable sv, Node nodeFrom, Node nodeTo, boolean uncertain
) {
exists(IRBlock bb2, int i2 |
nodeToDefOrUse(nodeFrom, sv, bb1, i1, uncertain) and
adjacentDefRead(bb1, i1, sv, bb2, i2) and
useToNode(bb2, i2, sv, nodeTo)
nodeToDefOrUse(nodeFrom, sv, bb1, i1, uncertain) and
(
exists(IRBlock bb2, int i2 |
adjacentDefRead(bb1, i1, sv, bb2, i2) and
useToNode(bb2, i2, sv, nodeTo)
)
or
phiToNode(nodeTo, sv, bb1, i1)
) and
nodeFrom != nodeTo
}
@@ -789,7 +763,7 @@ private predicate ssaFlowImpl(
private Node getAPriorDefinition(DefinitionExt next) {
exists(IRBlock bb, int i, SourceVariable sv |
lastRefRedefExt(_, pragma[only_bind_into](sv), pragma[only_bind_into](bb),
pragma[only_bind_into](i), next) and
pragma[only_bind_into](i), _, next) and
nodeToDefOrUse(result, sv, bb, i, _)
)
}
@@ -896,9 +870,31 @@ private predicate isArgumentOfCallable(DataFlowCall call, Node n) {
* Holds if there is use-use flow from `pun`'s pre-update node to `n`.
*/
private predicate postUpdateNodeToFirstUse(PostUpdateNode pun, Node n) {
exists(SourceVariable sv, IRBlock bb2, int i2 |
adjustForPointerArith(pun, sv, bb2, i2) and
useToNode(bb2, i2, sv, n)
// We cannot mark a `PointerArithmeticInstruction` that computes an offset
// based on some SSA
// variable `x` as a use of `x` since this creates taint-flow in the
// following example:
// ```c
// int x = array[source]
// sink(*array)
// ```
// This is because `source` would flow from the operand of `PointerArithmetic`
// instruction to the result of the instruction, and into the `IndirectOperand`
// that represents the value of `*array`. Then, via use-use flow, flow will
// arrive at `*array` in `sink(*array)`.
// So this predicate recurses back along conversions and `PointerArithmetic`
// instructions to find the first use that has provides use-use flow, and
// uses that target as the target of the `nodeFrom`.
exists(Node adjusted, IRBlock bb1, int i1, SourceVariable sv |
indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and
useToNode(bb1, i1, sv, adjusted)
|
exists(IRBlock bb2, int i2 |
adjacentDefRead(bb1, i1, sv, bb2, i2) and
useToNode(bb2, i2, sv, n)
)
or
phiToNode(n, sv, bb1, i1)
)
}
@@ -953,11 +949,16 @@ predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
/** Holds if `nodeTo` receives flow from the phi node `nodeFrom`. */
predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2 |
exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1 |
phi = nodeFrom.getPhiNode() and
phi.definesAt(sv, bb1, i1, _) and
adjacentDefRead(bb1, i1, sv, bb2, i2) and
useToNode(bb2, i2, sv, nodeTo)
phi.definesAt(sv, bb1, i1, _)
|
exists(IRBlock bb2, int i2 |
adjacentDefRead(bb1, i1, sv, bb2, i2) and
useToNode(bb2, i2, sv, nodeTo)
)
or
phiToNode(nodeTo, sv, bb1, i1)
)
}
@@ -1031,22 +1032,26 @@ module SsaCached {
* Holds if the node at index `i` in `bb` is a last reference to SSA definition
* `def`. The reference is last because it can reach another write `next`,
* without passing through another read or write.
*
* The path from node `i` in `bb` to `next` goes via basic block `input`,
* which is either a predecessor of the basic block of `next`, or `input` =
* `bb` in case `next` occurs in basic block `bb`.
*/
cached
predicate lastRefRedefExt(
DefinitionExt def, SourceVariable sv, IRBlock bb, int i, DefinitionExt next
DefinitionExt def, SourceVariable sv, IRBlock bb, int i, IRBlock input, DefinitionExt next
) {
SsaImpl::lastRefRedefExt(def, sv, bb, i, next)
SsaImpl::lastRefRedefExt(def, sv, bb, i, input, next)
}
cached
Definition phiHasInputFromBlock(PhiNode phi, IRBlock bb) {
SsaImpl::phiHasInputFromBlock(phi, result, bb)
Definition phiHasInputFromBlockExt(PhiNode phi, IRBlock bb) {
SsaImpl::phiHasInputFromBlockExt(phi, result, bb)
}
cached
predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) {
SsaImpl::ssaDefReachesRead(v, def, bb, i)
predicate ssaDefReachesReadExt(SourceVariable v, DefinitionExt def, IRBlock bb, int i) {
SsaImpl::ssaDefReachesReadExt(v, def, bb, i)
}
predicate variableRead = SsaInput::variableRead/4;
@@ -1198,11 +1203,11 @@ class Phi extends TPhi, SsaDef {
final override Location getLocation() { result = phi.getBasicBlock().getLocation() }
override string toString() { result = "Phi" }
override string toString() { result = phi.toString() }
SsaPhiNode getNode() { result.getPhiNode() = phi }
SsaPhiInputNode getNode(IRBlock block) { result.getPhiNode() = phi and result.getBlock() = block }
predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlock(phi, bb) }
predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlockExt(phi, bb) }
final Definition getAnInput() { this.hasInputFromBlock(result, _) }
}
@@ -1228,13 +1233,21 @@ class PhiNode extends SsaImpl::DefinitionExt {
*/
predicate isPhiRead() { this instanceof SsaImpl::PhiReadNode }
/** Holds if `inp` is an input to this phi node along the edge originating in `bb`. */
predicate hasInputFromBlock(Definition inp, IRBlock bb) {
inp = SsaCached::phiHasInputFromBlock(this, bb)
/**
* Holds if the node at index `i` in `bb` is a last reference to SSA
* definition `def` of `sv`. The reference is last because it can reach
* this phi node, without passing through another read or write.
*
* The path from node `i` in `bb` to this phi node goes via basic block
* `input`, which is either a predecessor of the basic block of this phi
* node, or `input` = `bb` in case this phi node occurs in basic block `bb`.
*/
predicate hasInputFromBlock(DefinitionExt def, SourceVariable sv, IRBlock bb, int i, IRBlock input) {
SsaCached::lastRefRedefExt(def, sv, bb, i, input, this)
}
/** Gets a definition that is an input to this phi node. */
final Definition getAnInput() { this.hasInputFromBlock(result, _) }
final Definition getAnInput() { this.hasInputFromBlock(result, _, _, _, _) }
}
/** An static single assignment (SSA) definition. */
@@ -1249,6 +1262,15 @@ class DefinitionExt extends SsaImpl::DefinitionExt {
result = this.getAPhiInputOrPriorDefinition*() and
not result instanceof PhiNode
}
/** Gets a node that represents a read of this SSA definition. */
Node getARead() {
exists(SourceVariable sv, IRBlock bb, int i | SsaCached::ssaDefReachesReadExt(sv, this, bb, i) |
useToNode(bb, i, sv, result)
or
phiToNode(result, sv, bb, i)
)
}
}
class Definition = SsaImpl::Definition;

View File

@@ -1,3 +1,3 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
import semmle.code.cpp.ir.implementation.raw.IR
import semmle.code.cpp.ir.internal.Overlap
import semmle.code.cpp.ir.internal.IRCppLanguage as Language

View File

@@ -3208,9 +3208,20 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
/**
* Gets the rnk'th (0-indexed) child for which a `TranslatedElement` exists.
*
* We use this predicate to filter out `TypeName` expressions that sometimes
* occur in builtin operations since the IR doesn't have an instruction to
* represent a reference to a type.
*/
private TranslatedElement getRankedChild(int rnk) {
result = rank[rnk + 1](int id, TranslatedElement te | te = this.getChild(id) | te order by id)
}
final override Instruction getFirstInstruction(EdgeKind kind) {
if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction(kind)
if exists(this.getRankedChild(0))
then result = this.getRankedChild(0).getFirstInstruction(kind)
else (
kind instanceof GotoEdge and result = this.getInstruction(OnlyInstructionTag())
)
@@ -3230,11 +3241,11 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
}
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
exists(int id | child = this.getChild(id) |
result = this.getChild(id + 1).getFirstInstruction(kind)
exists(int id | child = this.getRankedChild(id) |
result = this.getRankedChild(id + 1).getFirstInstruction(kind)
or
kind instanceof GotoEdge and
not exists(this.getChild(id + 1)) and
not exists(this.getRankedChild(id + 1)) and
result = this.getInstruction(OnlyInstructionTag())
)
}
@@ -3249,7 +3260,7 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
tag = OnlyInstructionTag() and
exists(int index |
operandTag = positionalArgumentOperand(index) and
result = this.getChild(index).(TranslatedExpr).getResult()
result = this.getRankedChild(index).(TranslatedExpr).getResult()
)
}

View File

@@ -1,3 +1,3 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR
import semmle.code.cpp.ir.internal.Overlap
import semmle.code.cpp.ir.internal.IRCppLanguage as Language

View File

@@ -7,119 +7,6 @@
import semmle.code.cpp.models.interfaces.Allocation
import semmle.code.cpp.models.interfaces.Taint
/**
* An allocation function (such as `malloc`) that has an argument for the size
* in bytes.
*/
private class MallocAllocationFunction extends AllocationFunction {
int sizeArg;
MallocAllocationFunction() {
// --- C library allocation
this.hasGlobalOrStdOrBslName("malloc") and // malloc(size)
sizeArg = 0
or
this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"MmAllocateContiguousMemory", // MmAllocateContiguousMemory(size, maxaddress)
"MmAllocateContiguousNodeMemory", // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer)
"MmAllocateContiguousMemorySpecifyCache", // MmAllocateContiguousMemorySpecifyCache(size, minaddress, maxaddress, bound, type)
"MmAllocateContiguousMemorySpecifyCacheNode", // MmAllocateContiguousMemorySpecifyCacheNode(size, minaddress, maxaddress, bound, type, prefer)
"MmAllocateNonCachedMemory", // MmAllocateNonCachedMemory(size)
"MmAllocateMappingAddress", // MmAllocateMappingAddress(size, tag)
// --- Windows COM allocation
"CoTaskMemAlloc", // CoTaskMemAlloc(size)
// --- Solaris/BSD kernel memory allocator
"kmem_alloc", // kmem_alloc(size, flags)
"kmem_zalloc", // kmem_zalloc(size, flags)
// --- OpenSSL memory allocation
"CRYPTO_malloc", // CRYPTO_malloc(size_t num, const char *file, int line)
"CRYPTO_zalloc", // CRYPTO_zalloc(size_t num, const char *file, int line)
"CRYPTO_secure_malloc", // CRYPTO_secure_malloc(size_t num, const char *file, int line)
"CRYPTO_secure_zalloc", // CRYPTO_secure_zalloc(size_t num, const char *file, int line)
"g_malloc", // g_malloc (n_bytes);
"g_try_malloc" // g_try_malloc(n_bytes);
]) and
sizeArg = 0
or
this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"ExAllocatePool", // ExAllocatePool(type, size)
"ExAllocatePool2", // ExAllocatePool2(flags, size, tag)
"ExAllocatePool3", // ExAllocatePool3(flags, size, tag, extparams, extparamscount)
"ExAllocatePoolWithTag", // ExAllocatePool(type, size, tag)
"ExAllocatePoolWithTagPriority", // ExAllocatePoolWithTagPriority(type, size, tag, priority)
"ExAllocatePoolWithQuota", // ExAllocatePoolWithQuota(type, size)
"ExAllocatePoolWithQuotaTag", // ExAllocatePoolWithQuotaTag(type, size, tag)
"ExAllocatePoolZero", // ExAllocatePoolZero(type, size, tag)
"IoAllocateMdl", // IoAllocateMdl(address, size, flag, flag, irp)
"IoAllocateErrorLogEntry", // IoAllocateErrorLogEntry(object, size)
// --- Windows Global / Local legacy allocation
"LocalAlloc", // LocalAlloc(flags, size)
"GlobalAlloc", // GlobalAlloc(flags, size)
// --- Windows System Services allocation
"VirtualAlloc" // VirtualAlloc(address, size, type, flag)
]) and
sizeArg = 1
or
this.hasGlobalName("HeapAlloc") and // HeapAlloc(heap, flags, size)
sizeArg = 2
or
this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"MmAllocatePagesForMdl", // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size)
"MmAllocatePagesForMdlEx", // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags)
"MmAllocateNodePagesForMdlEx" // MmAllocateNodePagesForMdlEx(minaddress, maxaddress, skip, size, type, prefer, flags)
]) and
sizeArg = 3
}
override int getSizeArg() { result = sizeArg }
}
/**
* An allocation function (such as `alloca`) that does not require a
* corresponding free (and has an argument for the size in bytes).
*/
private class AllocaAllocationFunction extends AllocationFunction {
int sizeArg;
AllocaAllocationFunction() {
this.hasGlobalName([
// --- stack allocation
"alloca", // // alloca(size)
"__builtin_alloca", // __builtin_alloca(size)
"_alloca", // _alloca(size)
"_malloca" // _malloca(size)
]) and
sizeArg = 0
}
override int getSizeArg() { result = sizeArg }
override predicate requiresDealloc() { none() }
}
/**
* An allocation function (such as `calloc`) that has an argument for the size
* and another argument for the size of those units (in bytes).
*/
private class CallocAllocationFunction extends AllocationFunction {
int sizeArg;
int multArg;
CallocAllocationFunction() {
// --- C library allocation
this.hasGlobalOrStdOrBslName("calloc") and // calloc(num, size)
sizeArg = 1 and
multArg = 0
}
override int getSizeArg() { result = sizeArg }
override int getSizeMult() { result = multArg }
}
/**
* An allocation function (such as `realloc`) that has an argument for the size
* in bytes, and an argument for an existing pointer that is to be reallocated.
@@ -373,6 +260,63 @@ private class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
override predicate requiresDealloc() { not exists(this.getPlacementPointer()) }
}
/**
* Holds if `f` is an allocation function according to the
* extensible `allocationFunctionModel` predicate.
*/
private predicate isAllocationFunctionFromModel(
Function f, string namespace, string type, string name
) {
exists(boolean subtypes | allocationFunctionModel(namespace, type, subtypes, name, _, _, _, _) |
if type = ""
then f.hasQualifiedName(namespace, "", name)
else
exists(Class c |
c.hasQualifiedName(namespace, type) and f.hasQualifiedName(namespace, _, name)
|
if subtypes = true
then f = c.getADerivedClass*().getAMemberFunction()
else f = c.getAMemberFunction()
)
)
}
/**
* An allocation function modeled via the extensible `allocationFunctionModel` predicate.
*/
private class AllocationFunctionFromModel extends AllocationFunction {
string namespace;
string type;
string name;
AllocationFunctionFromModel() { isAllocationFunctionFromModel(this, namespace, type, name) }
final override int getSizeArg() {
exists(string sizeArg |
allocationFunctionModel(namespace, type, _, name, sizeArg, _, _, _) and
result = sizeArg.toInt()
)
}
final override int getSizeMult() {
exists(string sizeMult |
allocationFunctionModel(namespace, type, _, name, _, sizeMult, _, _) and
result = sizeMult.toInt()
)
}
final override int getReallocPtrArg() {
exists(string reallocPtrArg |
allocationFunctionModel(namespace, type, _, name, _, _, reallocPtrArg, _) and
result = reallocPtrArg.toInt()
)
}
final override predicate requiresDealloc() {
allocationFunctionModel(namespace, type, _, name, _, _, _, true)
}
}
private module HeuristicAllocation {
/** A class that maps an `AllocationExpr` to an `HeuristicAllocationExpr`. */
private class HeuristicAllocationModeled extends HeuristicAllocationExpr instanceof AllocationExpr

View File

@@ -7,61 +7,42 @@
import semmle.code.cpp.models.interfaces.Deallocation
/**
* A deallocation function such as `free`.
* Holds if `f` is an deallocation function according to the
* extensible `deallocationFunctionModel` predicate.
*/
private class StandardDeallocationFunction extends DeallocationFunction {
int freedArg;
private predicate isDeallocationFunctionFromModel(
Function f, string namespace, string type, string name
) {
exists(boolean subtypes | deallocationFunctionModel(namespace, type, subtypes, name, _) |
if type = ""
then f.hasQualifiedName(namespace, "", name)
else
exists(Class c |
c.hasQualifiedName(namespace, type) and f.hasQualifiedName(namespace, _, name)
|
if subtypes = true
then f = c.getADerivedClass*().getAMemberFunction()
else f = c.getAMemberFunction()
)
)
}
StandardDeallocationFunction() {
this.hasGlobalOrStdOrBslName([
// --- C library allocation
"free", "realloc"
]) and
freedArg = 0
or
this.hasGlobalName([
// --- OpenSSL memory deallocation
"CRYPTO_free", "CRYPTO_secure_free",
// --- glib memory deallocation
"g_free"
]) and
freedArg = 0
or
this.hasGlobalOrStdName([
// --- Windows Memory Management for Windows Drivers
"ExFreePool", "ExFreePoolWithTag", "ExDeleteTimer", "IoFreeIrp", "IoFreeMdl",
"IoFreeErrorLogEntry", "IoFreeWorkItem", "MmFreeContiguousMemory",
"MmFreeContiguousMemorySpecifyCache", "MmFreeNonCachedMemory", "MmFreeMappingAddress",
"MmFreePagesFromMdl", "MmUnmapReservedMapping", "MmUnmapLockedPages",
"NdisFreeGenericObject", "NdisFreeMemory", "NdisFreeMemoryWithTag", "NdisFreeMdl",
"NdisFreeNetBufferListPool", "NdisFreeNetBufferPool",
// --- Windows Global / Local legacy allocation
"LocalFree", "GlobalFree", "LocalReAlloc", "GlobalReAlloc",
// --- Windows System Services allocation
"VirtualFree",
// --- Windows COM allocation
"CoTaskMemFree", "CoTaskMemRealloc",
// --- Windows Automation
"SysFreeString",
// --- Solaris/BSD kernel memory allocator
"kmem_free"
]) and
freedArg = 0
or
this.hasGlobalOrStdName([
// --- Windows Memory Management for Windows Drivers
"ExFreeToLookasideListEx", "ExFreeToPagedLookasideList", "ExFreeToNPagedLookasideList",
"NdisFreeMemoryWithTagPriority", "StorPortFreeMdl", "StorPortFreePool",
// --- NetBSD pool manager
"pool_put", "pool_cache_put"
]) and
freedArg = 1
or
this.hasGlobalOrStdName(["HeapFree", "HeapReAlloc"]) and
freedArg = 2
/**
* A deallocation function modeled via the extensible `deallocationFunctionModel` predicate.
*/
private class DeallocationFunctionFromModel extends DeallocationFunction {
string namespace;
string type;
string name;
DeallocationFunctionFromModel() { isDeallocationFunctionFromModel(this, namespace, type, name) }
final override int getFreedArg() {
exists(string freedArg |
deallocationFunctionModel(namespace, type, _, name, freedArg) and
result = freedArg.toInt()
)
}
override int getFreedArg() { result = freedArg }
}
/**

View File

@@ -89,6 +89,14 @@ abstract class AllocationFunction extends Function {
predicate requiresDealloc() { any() }
}
/**
* Holds if an external allocation model exists for the given parameters.
*/
extensible predicate allocationFunctionModel(
string namespace, string type, boolean subtypes, string name, string sizeArg, string multArg,
string reallocPtrArg, boolean requiresDealloc
);
/**
* An `operator new` or `operator new[]` function that may be associated with
* `new` or `new[]` expressions. Note that `new` and `new[]` are not function

View File

@@ -34,6 +34,13 @@ abstract class DeallocationFunction extends Function {
int getFreedArg() { none() }
}
/**
* Holds if an external deallocation model exists for the given parameters.
*/
extensible predicate deallocationFunctionModel(
string namespace, string type, boolean subtypes, string name, string freedArg
);
/**
* An `operator delete` or `operator delete[]` function that may be associated
* with `delete` or `delete[]` expressions. Note that `delete` and `delete[]`

View File

@@ -95,7 +95,7 @@ module FlowFromFree<FlowFromFreeParamSig P> {
e = any(StoreInstruction store).getDestinationAddress().getUnconvertedResultExpression()
)
or
n.asExpr() instanceof ArrayExpr
[n.asExpr(), n.asIndirectExpr()] instanceof ArrayExpr
}
}

View File

@@ -1,3 +1,9 @@
## 1.0.1
### Minor Analysis Improvements
* The `cpp/dangerous-function-overflow` no longer produces a false positive alert when the `gets` function does not have exactly one parameter.
## 1.0.0
### Breaking Changes

View File

@@ -209,6 +209,7 @@ class LoopWithAlloca extends Stmt {
DataFlow::localFlow(result, DataFlow::exprNode(va)) and
// Phi nodes will be preceded by nodes that represent actual definitions
not result instanceof DataFlow::SsaPhiNode and
not result instanceof DataFlow::SsaPhiInputNode and
// A source is outside the loop if it's not inside the loop
not exists(Expr e | e = getExpr(result) | this = getAnEnclosingLoopOfExpr(e))
)

View File

@@ -215,13 +215,18 @@ predicate noThrowInTryBlock(NewOrNewArrayExpr newExpr, BadAllocCatchBlock catchB
*/
predicate nullCheckInThrowingNew(NewOrNewArrayExpr newExpr, GuardCondition guard) {
newExpr.getAllocator() instanceof ThrowingAllocator and
(
// Handles null comparisons.
guard.ensuresEq(globalValueNumber(newExpr).getAnExpr(), any(NullValue null), _, _, _)
or
// Handles `if(ptr)` and `if(!ptr)` cases.
guard = globalValueNumber(newExpr).getAnExpr()
)
// There can be many guard conditions that compares `newExpr` againgst 0.
// For example, for `if(!p)` both `p` and `!p` are guard conditions. To not
// produce duplicates results we pick the "first" guard condition according
// to some arbitrary ordering (i.e., location information). This means `!p` is the
// element that we use to construct the alert.
guard =
min(GuardCondition gc, int startline, int startcolumn, int endline, int endcolumn |
gc.comparesEq(globalValueNumber(newExpr).getAnExpr(), 0, _, _) and
gc.getLocation().hasLocationInfo(_, startline, startcolumn, endline, endcolumn)
|
gc order by startline, startcolumn, endline, endcolumn
)
}
from NewOrNewArrayExpr newExpr, Element element, string msg, string elementString

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
## 1.0.1
### Minor Analysis Improvements
* The `cpp/dangerous-function-overflow` no longer produces a false positive alert when the `gets` function does not have exactly one parameter.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.0.0
lastReleaseVersion: 1.0.1

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.0.1-dev
version: 1.0.2-dev
groups:
- cpp
- queries

View File

@@ -3,4 +3,4 @@
#include "b.h"
static int has_angle_b = __has_include(<b.h>);
// semmle-extractor-options: -I${testdir}/dir2 -iquote ${testdir}/dir1 --edg --clang
// semmle-extractor-options: -I${testdir}/dir2 -iquote ${testdir}/dir1 --clang

View File

@@ -1 +1 @@
semmle-extractor-options: --edg --microsoft
semmle-extractor-options: --microsoft

View File

@@ -15,13 +15,13 @@ newArrayExprs
| allocators.cpp:69:3:69:18 | new[] | int[] | int | void* operator new[](size_t, float) | 4 | 4 | | n | |
| allocators.cpp:70:3:70:15 | new[] | String[] | String | void* operator new[](unsigned long) | 8 | 8 | | n | |
| allocators.cpp:71:3:71:20 | new[] | Overaligned[] | Overaligned | void* operator new[](unsigned long, std::align_val_t) | 256 | 128 | aligned | n | |
| allocators.cpp:72:3:72:16 | new[] | String[10] | String | void* operator new[](unsigned long) | 8 | 8 | | | |
| allocators.cpp:72:3:72:16 | new[] | String[10] | String | void* operator new[](unsigned long) | 8 | 8 | | 10 | |
| allocators.cpp:108:3:108:19 | new[] | FailedInit[] | FailedInit | void* FailedInit::operator new[](size_t) | 1 | 1 | | n | |
| allocators.cpp:110:3:110:37 | new[] | FailedInitOveraligned[10] | FailedInitOveraligned | void* FailedInitOveraligned::operator new[](size_t, std::align_val_t, float) | 128 | 128 | aligned | | |
| allocators.cpp:132:3:132:17 | new[] | int[1] | int | void* operator new[](std::size_t, void*) | 4 | 4 | | | buf |
| allocators.cpp:136:3:136:26 | new[] | int[2] | int | void* operator new[](std::size_t, std::nothrow_t const&) | 4 | 4 | | | |
| allocators.cpp:110:3:110:37 | new[] | FailedInitOveraligned[10] | FailedInitOveraligned | void* FailedInitOveraligned::operator new[](size_t, std::align_val_t, float) | 128 | 128 | aligned | 10 | |
| allocators.cpp:132:3:132:17 | new[] | int[1] | int | void* operator new[](std::size_t, void*) | 4 | 4 | | 1 | buf |
| allocators.cpp:136:3:136:26 | new[] | int[2] | int | void* operator new[](std::size_t, std::nothrow_t const&) | 4 | 4 | | 2 | |
| allocators.cpp:142:13:142:27 | new[] | char[][10] | char[10] | void* operator new[](unsigned long) | 10 | 1 | | x | |
| allocators.cpp:143:13:143:28 | new[] | char[20][20] | char[20] | void* operator new[](unsigned long) | 20 | 1 | | | |
| allocators.cpp:143:13:143:28 | new[] | char[20][20] | char[20] | void* operator new[](unsigned long) | 20 | 1 | | 20 | |
| allocators.cpp:144:13:144:31 | new[] | char[][30][30] | char[30][30] | void* operator new[](unsigned long) | 900 | 1 | | x | |
newExprDeallocators
| allocators.cpp:52:3:52:14 | new | String | void operator delete(void*, unsigned long) | 8 | 8 | sized |
@@ -72,17 +72,17 @@ allocationExprs
| allocators.cpp:69:3:69:18 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
| allocators.cpp:70:3:70:15 | new[] | getAllocatedElementType = String, getSizeExpr = n, getSizeMult = 8, requiresDealloc |
| allocators.cpp:71:3:71:20 | new[] | getAllocatedElementType = Overaligned, getSizeExpr = n, getSizeMult = 256, requiresDealloc |
| allocators.cpp:72:3:72:16 | new[] | getAllocatedElementType = String, getSizeBytes = 80, requiresDealloc |
| allocators.cpp:72:3:72:16 | new[] | getAllocatedElementType = String, getSizeBytes = 80, getSizeExpr = 10, getSizeMult = 8, requiresDealloc |
| allocators.cpp:107:3:107:18 | new | getAllocatedElementType = FailedInit, getSizeBytes = 1, requiresDealloc |
| allocators.cpp:108:3:108:19 | new[] | getAllocatedElementType = FailedInit, getSizeExpr = n, getSizeMult = 1, requiresDealloc |
| allocators.cpp:109:3:109:35 | new | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 128, requiresDealloc |
| allocators.cpp:110:3:110:37 | new[] | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 1280, requiresDealloc |
| allocators.cpp:110:3:110:37 | new[] | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 1280, getSizeExpr = 10, getSizeMult = 128, requiresDealloc |
| allocators.cpp:129:3:129:21 | new | getAllocatedElementType = int, getSizeBytes = 4 |
| allocators.cpp:132:3:132:17 | new[] | getAllocatedElementType = int, getSizeBytes = 4 |
| allocators.cpp:132:3:132:17 | new[] | getAllocatedElementType = int, getSizeBytes = 4, getSizeExpr = 1, getSizeMult = 4 |
| allocators.cpp:135:3:135:26 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
| allocators.cpp:136:3:136:26 | new[] | getAllocatedElementType = int, getSizeBytes = 8, requiresDealloc |
| allocators.cpp:136:3:136:26 | new[] | getAllocatedElementType = int, getSizeBytes = 8, getSizeExpr = 2, getSizeMult = 4, requiresDealloc |
| allocators.cpp:142:13:142:27 | new[] | getAllocatedElementType = char[10], getSizeExpr = x, getSizeMult = 10, requiresDealloc |
| allocators.cpp:143:13:143:28 | new[] | getAllocatedElementType = char[20], getSizeBytes = 400, requiresDealloc |
| allocators.cpp:143:13:143:28 | new[] | getAllocatedElementType = char[20], getSizeBytes = 400, getSizeExpr = 20, getSizeMult = 20, requiresDealloc |
| allocators.cpp:144:13:144:31 | new[] | getAllocatedElementType = char[30][30], getSizeExpr = x, getSizeMult = 900, requiresDealloc |
| allocators.cpp:149:8:149:19 | call to operator new | getSizeBytes = 4, getSizeExpr = sizeof(int), getSizeMult = 1, requiresDealloc |
| allocators.cpp:157:50:157:55 | call to malloc | getAllocatedElementType = const volatile int, getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |

View File

@@ -15,8 +15,6 @@
| arguments.c | 15 | --edg |
| arguments.c | 16 | __CODEQL_TEST__ |
| arguments.c | 17 | --gcc |
| arguments.c | 18 | --predefined_macros |
| arguments.c | 19 | <tools>/qltest/predefined_macros |
| arguments.c | 20 | -w |
| arguments.c | 21 | -Werror |
| arguments.c | 22 | arguments.c |
| arguments.c | 18 | -w |
| arguments.c | 19 | -Werror |
| arguments.c | 20 | arguments.c |

View File

@@ -4,8 +4,5 @@ from Compilation c, int i, string s
// Skip the extractor name; it'll vary depending on platform
where
i > 0 and
s =
c.getArgument(i)
.replaceAll("\\", "/")
.regexpReplaceAll(".*(/qltest/predefined_macros)", "<tools>$1")
s = c.getArgument(i).replaceAll("\\", "/")
select c.getAFileCompiled().toString(), i, s

View File

@@ -1 +1 @@
semmle-extractor-options: --edg --clang
semmle-extractor-options: --clang

View File

@@ -1,4 +1,8 @@
| declspec.cpp:4:23:4:43 | Use fatal() instead | declspec.cpp:4:59:4:62 | exit | declspec.cpp:4:12:4:21 | deprecated | Use fatal() instead |
| routine_attributes2.cpp:5:6:5:11 | hidden | routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.cpp:5:6:5:11 | visibility | hidden |
| routine_attributes2.cpp:5:6:5:11 | hidden | routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.cpp:5:6:5:11 | visibility | hidden |
| routine_attributes2.h:3:6:3:11 | hidden | routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.h:3:6:3:11 | visibility | hidden |
| routine_attributes2.h:3:6:3:11 | hidden | routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.h:3:6:3:11 | visibility | hidden |
| routine_attributes.c:3:53:3:59 | dummy | routine_attributes.c:3:12:3:24 | named_weakref | routine_attributes.c:3:44:3:50 | weakref | dummy |
| routine_attributes.c:4:62:4:68 | dummy | routine_attributes.c:4:12:4:26 | aliased_weakref | routine_attributes.c:4:55:4:59 | alias | dummy |
| routine_attributes.c:6:49:6:55 | dummy | routine_attributes.c:6:12:6:22 | plain_alias | routine_attributes.c:6:42:6:46 | alias | dummy |

View File

@@ -18,6 +18,10 @@
| header_export.cpp:14:16:14:26 | myFunction4 | header_export.cpp:14:1:14:9 | dllexport |
| header_export.cpp:18:6:18:16 | myFunction5 | header.h:10:2:10:10 | dllexport |
| header_export.cpp:18:6:18:16 | myFunction5 | header.h:10:2:10:10 | dllimport |
| routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.cpp:5:6:5:11 | visibility |
| routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.cpp:5:6:5:11 | visibility |
| routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.h:3:6:3:11 | visibility |
| routine_attributes2.cpp:5:13:5:21 | a_routine | routine_attributes2.h:3:6:3:11 | visibility |
| routine_attributes.c:3:12:3:24 | named_weakref | routine_attributes.c:3:44:3:50 | weakref |
| routine_attributes.c:4:12:4:26 | aliased_weakref | routine_attributes.c:4:46:4:52 | weakref |
| routine_attributes.c:4:12:4:26 | aliased_weakref | routine_attributes.c:4:55:4:59 | alias |

View File

@@ -0,0 +1,7 @@
#define HIDDEN __attribute__((visibility("hidden")))
#include "routine_attributes2.h"
void HIDDEN a_routine() {
return;
}

View File

@@ -0,0 +1,3 @@
#pragma once
void HIDDEN a_routine();

View File

@@ -0,0 +1,3 @@
#define HIDDEN __attribute__((visibility("hidden")))
#include "routine_attributes2.h"

View File

@@ -1,3 +1,6 @@
| type_attributes2.cpp:5:14:5:20 | a_class | type_attributes2.cpp:5:7:5:12 | visibility | type_attributes2.cpp:5:7:5:12 | hidden |
| type_attributes2.cpp:5:14:5:20 | a_class | type_attributes2.h:3:7:3:12 | visibility | type_attributes2.h:3:7:3:12 | hidden |
| type_attributes2.cpp:5:14:5:20 | a_class | type_attributes2.h:3:7:3:12 | visibility | type_attributes2.h:3:7:3:12 | hidden |
| type_attributes_ms.cpp:4:67:4:75 | IDispatch | type_attributes_ms.cpp:4:19:4:22 | uuid | type_attributes_ms.cpp:4:24:4:63 | {00020400-0000-0000-c000-000000000046} |
| type_attributes_ms.cpp:5:30:5:33 | Str1 | type_attributes_ms.cpp:5:12:5:16 | align | type_attributes_ms.cpp:5:18:5:19 | 32 |
| type_attributes_ms.cpp:6:55:6:62 | IUnknown | type_attributes_ms.cpp:6:2:6:2 | uuid | type_attributes_ms.cpp:6:2:6:2 | 00000000-0000-0000-c000-000000000046 |

View File

@@ -1,4 +1,7 @@
| file://:0:0:0:0 | short __attribute((__may_alias__)) | type_attributes.c:25:30:25:42 | may_alias |
| type_attributes2.cpp:5:14:5:20 | a_class | type_attributes2.cpp:5:7:5:12 | visibility |
| type_attributes2.cpp:5:14:5:20 | a_class | type_attributes2.h:3:7:3:12 | visibility |
| type_attributes2.cpp:5:14:5:20 | a_class | type_attributes2.h:3:7:3:12 | visibility |
| type_attributes.c:5:36:5:51 | my_packed_struct | type_attributes.c:5:23:5:32 | packed |
| type_attributes.c:10:54:10:54 | (unnamed class/struct/union) | type_attributes.c:10:30:10:50 | transparent_union |
| type_attributes.c:16:54:16:54 | (unnamed class/struct/union) | type_attributes.c:16:30:16:50 | transparent_union |

View File

@@ -0,0 +1,6 @@
#define HIDDEN __attribute__((visibility("hidden")))
#include "type_attributes2.h"
class HIDDEN a_class {
};

View File

@@ -0,0 +1,3 @@
#pragma once
class HIDDEN a_class;

View File

@@ -0,0 +1,3 @@
#define HIDDEN __attribute__((visibility("hidden")))
#include "type_attributes2.h"

View File

@@ -6,6 +6,10 @@
| ms_var_attributes.cpp:12:42:12:46 | field | ms_var_attributes.cpp:12:14:12:21 | property |
| ms_var_attributes.cpp:20:34:20:37 | pBuf | ms_var_attributes.cpp:20:12:20:12 | SAL_volatile |
| ms_var_attributes.h:5:22:5:27 | myInt3 | ms_var_attributes.h:5:1:5:9 | dllexport |
| var_attributes2.cpp:5:12:5:21 | a_variable | var_attributes2.cpp:5:5:5:10 | visibility |
| var_attributes2.cpp:5:12:5:21 | a_variable | var_attributes2.cpp:5:5:5:10 | visibility |
| var_attributes2.cpp:5:12:5:21 | a_variable | var_attributes2.h:3:12:3:17 | visibility |
| var_attributes2.cpp:5:12:5:21 | a_variable | var_attributes2.h:3:12:3:17 | visibility |
| var_attributes.c:1:12:1:19 | weak_var | var_attributes.c:1:36:1:39 | weak |
| var_attributes.c:2:12:2:22 | weakref_var | var_attributes.c:2:39:2:45 | weakref |
| var_attributes.c:3:12:3:19 | used_var | var_attributes.c:3:36:3:39 | used |

View File

@@ -0,0 +1,5 @@
#define HIDDEN __attribute__((visibility("hidden")))
#include "var_attributes2.h"
int HIDDEN a_variable;

View File

@@ -0,0 +1,3 @@
#pragma once
extern int HIDDEN a_variable;

View File

@@ -0,0 +1,3 @@
#define HIDDEN __attribute__((visibility("hidden")))
#include "var_attributes2.h"

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: --edg --clang
// semmle-extractor-options: --clang
int x = 0;

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: --edg --clang --edg --c++11 --edg --nullptr
// semmle-extractor-options: --clang --edg --c++11 --edg --nullptr
static int has_nullptr_f = __has_feature(cxx_nullptr);
static int has_nullptr_e = __has_extension(cxx_nullptr);

View File

@@ -1 +1 @@
semmle-extractor-options: --edg --clang
semmle-extractor-options: --clang

View File

@@ -1,7 +1,7 @@
// For the canonical behaviour, run: clang -E -w test.cpp
#define __builtin_TRAP __builtin_trap
#define BAR "bar.h"
// semmle-extractor-options: --edg --clang --expect_errors
// semmle-extractor-options: --clang --expect_errors
#if defined(__has_include)
static int has_include = 1;
#else

View File

@@ -1 +1 @@
semmle-extractor-options: --edg --clang --edg --ms_extensions
semmle-extractor-options: --clang --edg --ms_extensions

View File

@@ -74,6 +74,8 @@ astGuardsCompare
| 34 | j >= 10+0 when ... < ... is false |
| 42 | 10 < j+1 when ... < ... is false |
| 42 | 10 >= j+1 when ... < ... is true |
| 42 | call to getABool != 0 when call to getABool is true |
| 42 | call to getABool == 0 when call to getABool is false |
| 42 | j < 10+0 when ... < ... is true |
| 42 | j >= 10+0 when ... < ... is false |
| 44 | 0 < z+0 when ... > ... is true |
@@ -537,6 +539,8 @@ astGuardsEnsure_const
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 |
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 |
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 0 | 53 | 53 |
irGuards
| test.c:7:9:7:13 | CompareGT: ... > ... |
| test.c:17:8:17:12 | CompareLT: ... < ... |
@@ -613,6 +617,8 @@ irGuardsCompare
| 34 | j >= 10+0 when CompareLT: ... < ... is false |
| 42 | 10 < j+1 when CompareLT: ... < ... is false |
| 42 | 10 >= j+1 when CompareLT: ... < ... is true |
| 42 | call to getABool != 0 when Call: call to getABool is true |
| 42 | call to getABool == 0 when Call: call to getABool is false |
| 42 | j < 10 when CompareLT: ... < ... is true |
| 42 | j < 10+0 when CompareLT: ... < ... is true |
| 42 | j >= 10 when CompareLT: ... < ... is false |
@@ -1081,3 +1087,5 @@ irGuardsEnsure_const
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 32 | 32 |
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | != | 0 | 44 | 44 |
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | == | 0 | 53 | 53 |

View File

@@ -42,3 +42,10 @@
| test.cpp:99:6:99:6 | f |
| test.cpp:105:6:105:14 | ... != ... |
| test.cpp:111:6:111:14 | ... != ... |
| test.cpp:122:9:122:9 | b |
| test.cpp:125:13:125:20 | ! ... |
| test.cpp:125:14:125:17 | call to safe |
| test.cpp:131:6:131:21 | call to __builtin_expect |
| test.cpp:135:6:135:21 | call to __builtin_expect |
| test.cpp:141:6:141:21 | call to __builtin_expect |
| test.cpp:145:6:145:21 | call to __builtin_expect |

View File

@@ -44,6 +44,8 @@
| 34 | j >= 10+0 when ... < ... is false |
| 42 | 10 < j+1 when ... < ... is false |
| 42 | 10 >= j+1 when ... < ... is true |
| 42 | call to getABool != 0 when call to getABool is true |
| 42 | call to getABool == 0 when call to getABool is false |
| 42 | j < 10 when ... < ... is true |
| 42 | j < 10+0 when ... < ... is true |
| 42 | j >= 10 when ... < ... is false |
@@ -149,16 +151,59 @@
| 111 | 0.0 == i+0 when ... != ... is false |
| 111 | i != 0.0+0 when ... != ... is true |
| 111 | i == 0.0+0 when ... != ... is false |
| 122 | b != 0 when b is true |
| 122 | b == 0 when b is false |
| 125 | ! ... != 0 when ! ... is true |
| 125 | ! ... == 0 when ! ... is false |
| 125 | call to safe != 0 when ! ... is false |
| 125 | call to safe != 0 when call to safe is true |
| 125 | call to safe == 0 when call to safe is false |
| 126 | 1 != 0 when 1 is true |
| 126 | 1 != 0 when ... && ... is true |
| 126 | 1 == 0 when 1 is false |
| 126 | call to test3_condition != 0 when ... && ... is true |
| 126 | call to test3_condition != 0 when call to test3_condition is true |
| 126 | call to test3_condition == 0 when call to test3_condition is false |
| 131 | ... + ... != a+0 when call to __builtin_expect is false |
| 131 | ... + ... == a+0 when call to __builtin_expect is true |
| 131 | a != ... + ...+0 when call to __builtin_expect is false |
| 131 | a != b+42 when call to __builtin_expect is false |
| 131 | a == ... + ...+0 when call to __builtin_expect is true |
| 131 | a == b+42 when call to __builtin_expect is true |
| 131 | b != 0 when b is true |
| 131 | b != a+-42 when call to __builtin_expect is false |
| 131 | b == 0 when b is false |
| 131 | b == a+-42 when call to __builtin_expect is true |
| 131 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 131 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 135 | ... + ... != a+0 when call to __builtin_expect is true |
| 135 | ... + ... == a+0 when call to __builtin_expect is false |
| 135 | a != ... + ...+0 when call to __builtin_expect is true |
| 135 | a != b+42 when call to __builtin_expect is true |
| 135 | a == ... + ...+0 when call to __builtin_expect is false |
| 135 | a == b+42 when call to __builtin_expect is false |
| 135 | b != a+-42 when call to __builtin_expect is true |
| 135 | b == a+-42 when call to __builtin_expect is false |
| 135 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 135 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 137 | 0 != 0 when 0 is true |
| 137 | 0 == 0 when 0 is false |
| 141 | 42 != a+0 when call to __builtin_expect is false |
| 141 | 42 == a+0 when call to __builtin_expect is true |
| 141 | a != 42 when call to __builtin_expect is false |
| 141 | a != 42+0 when call to __builtin_expect is false |
| 141 | a == 42 when call to __builtin_expect is true |
| 141 | a == 42+0 when call to __builtin_expect is true |
| 141 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 141 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 145 | 42 != a+0 when call to __builtin_expect is true |
| 145 | 42 == a+0 when call to __builtin_expect is false |
| 145 | a != 42 when call to __builtin_expect is true |
| 145 | a != 42+0 when call to __builtin_expect is true |
| 145 | a == 42 when call to __builtin_expect is false |
| 145 | a == 42+0 when call to __builtin_expect is false |
| 145 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 145 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 146 | ! ... != 0 when ! ... is true |
| 146 | ! ... == 0 when ! ... is false |
| 146 | x != 0 when ! ... is false |

View File

@@ -100,3 +100,11 @@
| test.cpp:99:6:99:6 | f | true | 99 | 100 |
| test.cpp:105:6:105:14 | ... != ... | true | 105 | 106 |
| test.cpp:111:6:111:14 | ... != ... | true | 111 | 112 |
| test.cpp:122:9:122:9 | b | true | 123 | 125 |
| test.cpp:122:9:122:9 | b | true | 125 | 125 |
| test.cpp:125:13:125:20 | ! ... | true | 125 | 125 |
| test.cpp:125:14:125:17 | call to safe | false | 125 | 125 |
| test.cpp:131:6:131:21 | call to __builtin_expect | true | 131 | 132 |
| test.cpp:135:6:135:21 | call to __builtin_expect | true | 135 | 136 |
| test.cpp:141:6:141:21 | call to __builtin_expect | true | 141 | 142 |
| test.cpp:145:6:145:21 | call to __builtin_expect | true | 145 | 146 |

View File

@@ -159,6 +159,18 @@ binary
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | 105 | 106 |
| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:6 | i | != | test.cpp:111:11:111:14 | 0.0 | 0 | 111 | 112 |
| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:11:111:14 | 0.0 | != | test.cpp:111:6:111:6 | i | 0 | 111 | 112 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:23 | a | == | test.cpp:131:28:131:28 | b | 42 | 131 | 132 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:23 | a | == | test.cpp:131:28:131:33 | ... + ... | 0 | 131 | 132 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:28:131:28 | b | == | test.cpp:131:23:131:23 | a | -42 | 131 | 132 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:28:131:33 | ... + ... | == | test.cpp:131:23:131:23 | a | 0 | 131 | 132 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:23 | a | != | test.cpp:135:28:135:28 | b | 42 | 135 | 136 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:23 | a | != | test.cpp:135:28:135:33 | ... + ... | 0 | 135 | 136 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:28:135:28 | b | != | test.cpp:135:23:135:23 | a | -42 | 135 | 136 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:28:135:33 | ... + ... | != | test.cpp:135:23:135:23 | a | 0 | 135 | 136 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:23 | a | == | test.cpp:141:28:141:29 | 42 | 0 | 141 | 142 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:28:141:29 | 42 | == | test.cpp:141:23:141:23 | a | 0 | 141 | 142 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | test.cpp:145:28:145:29 | 42 | 0 | 145 | 146 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:28:145:29 | 42 | != | test.cpp:145:23:145:23 | a | 0 | 145 | 146 |
unary
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | 10 | 11 |
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | 7 | 9 |
@@ -257,6 +269,8 @@ unary
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 |
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 |
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 0 | 53 | 53 |
| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | 62 | 64 |
| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | 65 | 66 |
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 11 | 75 | 77 |
@@ -264,3 +278,13 @@ unary
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | 75 | 77 |
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | 78 | 79 |
| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | != | 0 | 93 | 94 |
| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | 123 | 125 |
| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | 125 | 125 |
| test.cpp:125:13:125:20 | ! ... | test.cpp:125:13:125:20 | ! ... | != | 0 | 125 | 125 |
| test.cpp:125:14:125:17 | call to safe | test.cpp:125:14:125:17 | call to safe | == | 0 | 125 | 125 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:6:131:21 | call to __builtin_expect | != | 0 | 131 | 132 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:6:135:21 | call to __builtin_expect | != | 0 | 135 | 136 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:6:141:21 | call to __builtin_expect | != | 0 | 141 | 142 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:23 | a | == | 42 | 141 | 142 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | != | 0 | 145 | 146 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | 42 | 145 | 146 |

View File

@@ -112,3 +112,37 @@ void int_float_comparison(int i) {
use(i);
}
}
int source();
bool safe(int);
void test(bool b)
{
int x;
if (b)
{
x = source();
if (!safe(x)) return;
}
use(x);
}
void binary_test_builtin_expected(int a, int b) {
if(__builtin_expect(a == b + 42, 0)) {
use(a);
}
if(__builtin_expect(a != b + 42, 0)) {
use(a);
}
}
void unary_test_builtin_expected(int a) {
if(__builtin_expect(a == 42, 0)) {
use(a);
}
if(__builtin_expect(a != 42, 0)) {
use(a);
}
}

View File

@@ -1,6 +1,6 @@
WARNING: Module DataFlow has been deprecated and may be removed in future (additionalEdges.ql:31,6-14)
WARNING: Module DataFlow has been deprecated and may be removed in future (additionalEdges.ql:31,31-39)
WARNING: Module DataFlow has been deprecated and may be removed in future (additionalEdges.ql:32,7-15)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (additionalEdges.ql:31,6-14)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (additionalEdges.ql:31,31-39)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (additionalEdges.ql:32,7-15)
| tryExcept.c:7:7:7:7 | x | tryExcept.c:14:10:14:10 | x |
| tryExcept.c:7:13:7:14 | 0 | tryExcept.c:10:9:10:9 | y |
| tryExcept.c:10:9:10:9 | y | tryExcept.c:10:5:10:9 | ... = ... |

View File

@@ -1,5 +1,5 @@
WARNING: Module DataFlow has been deprecated and may be removed in future (standardEdges.ql:4,6-14)
WARNING: Module DataFlow has been deprecated and may be removed in future (standardEdges.ql:4,31-39)
WARNING: Module DataFlow has been deprecated and may be removed in future (standardEdges.ql:5,7-15)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (standardEdges.ql:4,6-14)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (standardEdges.ql:4,31-39)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (standardEdges.ql:5,7-15)
| tryExcept.c:7:13:7:14 | 0 | tryExcept.c:10:9:10:9 | y |
| tryExcept.c:10:9:10:9 | y | tryExcept.c:10:5:10:9 | ... = ... |

View File

@@ -75,4 +75,54 @@ void bg_indirect_expr() {
if (guarded(buf)) {
sink(buf);
}
}
void test_guard_and_reassign() {
int x = source();
if(!guarded(x)) {
x = 0;
}
sink(x); // $ SPURIOUS: ast
}
void test_phi_read_guard(bool b) {
int x = source();
if(b) {
if(!guarded(x))
return;
}
else {
if(!guarded(x))
return;
}
sink(x); // $ SPURIOUS: ast
}
bool unsafe(int);
void test_guard_and_reassign_2() {
int x = source();
if(unsafe(x)) {
x = 0;
}
sink(x); // $ SPURIOUS: ast
}
void test_phi_read_guard_2(bool b) {
int x = source();
if(b) {
if(unsafe(x))
return;
}
else {
if(unsafe(x))
return;
}
sink(x); // $ SPURIOUS: ast
}

View File

@@ -7,10 +7,17 @@ module AstTest {
* S in `if (guarded(x)) S`.
*/
// This is tested in `BarrierGuard.cpp`.
predicate testBarrierGuard(GuardCondition g, Expr checked, boolean isTrue) {
g.(FunctionCall).getTarget().getName() = "guarded" and
checked = g.(FunctionCall).getArgument(0) and
isTrue = true
predicate testBarrierGuard(GuardCondition g, Expr checked, boolean branch) {
exists(Call call, boolean b |
checked = call.getArgument(0) and
g.comparesEq(call, 0, b, any(BooleanValue bv | bv.getValue() = branch))
|
call.getTarget().hasName("guarded") and
b = false
or
call.getTarget().hasName("unsafe") and
b = true
)
}
/** Common data flow configuration to be used by tests. */
@@ -102,12 +109,16 @@ module IRTest {
* S in `if (guarded(x)) S`.
*/
// This is tested in `BarrierGuard.cpp`.
predicate testBarrierGuard(IRGuardCondition g, Expr checked, boolean isTrue) {
exists(Call call |
call = g.getUnconvertedResultExpression() and
call.getTarget().hasName("guarded") and
checked = call.getArgument(0) and
isTrue = true
predicate testBarrierGuard(IRGuardCondition g, Expr checked, boolean branch) {
exists(CallInstruction call, boolean b |
checked = call.getArgument(0).getUnconvertedResultExpression() and
g.comparesEq(call.getAUse(), 0, b, any(BooleanValue bv | bv.getValue() = branch))
|
call.getStaticCallTarget().hasName("guarded") and
b = false
or
call.getStaticCallTarget().hasName("unsafe") and
b = true
)
}
@@ -140,6 +151,9 @@ module IRTest {
or
call.getTarget().getName() = "indirect_sink" and
sink.asIndirectExpr() = e
or
call.getTarget().getName() = "indirect_sink_const_ref" and
sink.asIndirectExpr() = e
)
}

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: --edg --clang
// semmle-extractor-options: --clang
int source();
void sink(int); void sink(const int *); void sink(int **); void indirect_sink(...);
@@ -52,3 +52,9 @@ void following_pointers( // $ ast-def=sourceStruct1_ptr ir-def=*cleanArray1 ir-d
sink(stackArray); // $ ast,ir
indirect_sink(stackArray); // $ ast ir=50:25 ir=50:35 ir=51:19
}
void test_bitcast() {
unsigned long x = source();
double d = __builtin_bit_cast(double, x);
sink(d); // $ ir MISSING: ast
}

View File

@@ -1,3 +1,3 @@
WARNING: Module DataFlow has been deprecated and may be removed in future (has-parameter-flow-out.ql:5,18-61)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (has-parameter-flow-out.ql:5,18-61)
testFailures
failures

View File

@@ -69,45 +69,61 @@
| test.cpp:8:8:8:9 | t1 | test.cpp:9:8:9:9 | t1 |
| test.cpp:9:8:9:9 | t1 | test.cpp:11:7:11:8 | t1 |
| test.cpp:9:8:9:9 | t1 | test.cpp:11:7:11:8 | t1 |
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | Phi input |
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | Phi input |
| test.cpp:10:8:10:9 | t2 | test.cpp:13:10:13:11 | t2 |
| test.cpp:10:8:10:9 | t2 | test.cpp:15:3:15:6 | Phi |
| test.cpp:10:8:10:9 | t2 | test.cpp:15:3:15:6 | Phi |
| test.cpp:11:7:11:8 | Phi input | test.cpp:15:3:15:6 | SSA phi read(t2) |
| test.cpp:11:7:11:8 | Phi input | test.cpp:15:3:15:6 | SSA phi(*t2) |
| test.cpp:11:7:11:8 | t1 | test.cpp:21:8:21:9 | t1 |
| test.cpp:12:5:12:10 | ... = ... | test.cpp:13:10:13:11 | t2 |
| test.cpp:12:10:12:10 | 0 | test.cpp:12:5:12:10 | ... = ... |
| test.cpp:13:10:13:11 | t2 | test.cpp:15:3:15:6 | Phi |
| test.cpp:13:10:13:11 | t2 | test.cpp:15:3:15:6 | Phi |
| test.cpp:15:3:15:6 | Phi | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:3:15:6 | Phi | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:19:23:19 | Phi |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:19:23:19 | Phi |
| test.cpp:13:5:13:8 | Phi input | test.cpp:15:3:15:6 | SSA phi read(t2) |
| test.cpp:13:5:13:8 | Phi input | test.cpp:15:3:15:6 | SSA phi(*t2) |
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | Phi input |
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | Phi input |
| test.cpp:15:3:15:6 | SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:3:15:6 | SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | Phi input |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | Phi input |
| test.cpp:17:3:17:8 | ... = ... | test.cpp:21:8:21:9 | t1 |
| test.cpp:17:8:17:8 | 0 | test.cpp:17:3:17:8 | ... = ... |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | Phi |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | Phi |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | Phi input |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | Phi input |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | 0 |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:19:23:19 | Phi |
| test.cpp:23:19:23:19 | Phi | test.cpp:23:19:23:19 | i |
| test.cpp:23:19:23:19 | Phi | test.cpp:23:19:23:19 | i |
| test.cpp:23:19:23:19 | Phi | test.cpp:23:23:23:24 | t1 |
| test.cpp:23:19:23:19 | Phi | test.cpp:23:23:23:24 | t1 |
| test.cpp:23:19:23:19 | Phi | test.cpp:24:10:24:11 | t2 |
| test.cpp:23:19:23:19 | Phi | test.cpp:24:10:24:11 | t2 |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | Phi input |
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(*t2) |
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(i) |
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t1) |
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t2) |
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi(*i) |
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi(*t1) |
| test.cpp:23:19:23:19 | SSA phi read(*t2) | test.cpp:24:10:24:11 | t2 |
| test.cpp:23:19:23:19 | SSA phi read(i) | test.cpp:23:19:23:19 | i |
| test.cpp:23:19:23:19 | SSA phi read(t1) | test.cpp:23:23:23:24 | t1 |
| test.cpp:23:19:23:19 | SSA phi read(t2) | test.cpp:24:10:24:11 | t2 |
| test.cpp:23:19:23:19 | SSA phi(*i) | test.cpp:23:19:23:19 | i |
| test.cpp:23:19:23:19 | SSA phi(*t1) | test.cpp:23:23:23:24 | t1 |
| test.cpp:23:19:23:19 | i | test.cpp:23:27:23:27 | i |
| test.cpp:23:19:23:19 | i | test.cpp:23:27:23:27 | i |
| test.cpp:23:23:23:24 | t1 | test.cpp:23:19:23:19 | Phi |
| test.cpp:23:23:23:24 | t1 | test.cpp:23:27:23:29 | Phi input |
| test.cpp:23:23:23:24 | t1 | test.cpp:26:8:26:9 | t1 |
| test.cpp:23:23:23:24 | t1 | test.cpp:26:8:26:9 | t1 |
| test.cpp:23:27:23:27 | *i | test.cpp:23:27:23:27 | *i |
| test.cpp:23:27:23:27 | *i | test.cpp:23:27:23:27 | i |
| test.cpp:23:27:23:27 | i | test.cpp:23:19:23:19 | Phi |
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:27 | i |
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:27 | i |
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:19:23:19 | Phi |
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:29 | Phi input |
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:27:23:29 | ... ++ |
| test.cpp:24:5:24:11 | ... = ... | test.cpp:23:19:23:19 | Phi |
| test.cpp:24:10:24:11 | t2 | test.cpp:23:19:23:19 | Phi |
| test.cpp:24:10:24:11 | t2 | test.cpp:23:19:23:19 | Phi |
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:27:23:29 | Phi input |
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(*t2) |
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(i) |
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t1) |
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t2) |
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi(*i) |
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi(*t1) |
| test.cpp:24:5:24:11 | ... = ... | test.cpp:23:27:23:29 | Phi input |
| test.cpp:24:10:24:11 | t2 | test.cpp:23:27:23:29 | Phi input |
| test.cpp:24:10:24:11 | t2 | test.cpp:23:27:23:29 | Phi input |
| test.cpp:24:10:24:11 | t2 | test.cpp:24:5:24:11 | ... = ... |
| test.cpp:382:48:382:54 | source1 | test.cpp:384:16:384:23 | *& ... |
| test.cpp:383:12:383:13 | 0 | test.cpp:383:12:383:13 | 0 |

View File

@@ -1,6 +1,6 @@
WARNING: Module DataFlow has been deprecated and may be removed in future (localFlow.ql:4,6-14)
WARNING: Module DataFlow has been deprecated and may be removed in future (localFlow.ql:4,31-39)
WARNING: Module DataFlow has been deprecated and may be removed in future (localFlow.ql:6,3-11)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (localFlow.ql:4,6-14)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (localFlow.ql:4,31-39)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (localFlow.ql:6,3-11)
| example.c:15:37:15:37 | b | example.c:15:37:15:37 | b |
| example.c:15:37:15:37 | b | example.c:19:6:19:6 | b |
| example.c:15:44:15:46 | pos | example.c:24:24:24:26 | pos |

View File

@@ -1,3 +1,3 @@
WARNING: Module DataFlow has been deprecated and may be removed in future (test-number-of-outnodes.ql:5,18-61)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (test-number-of-outnodes.ql:5,18-61)
failures
testFailures

View File

@@ -1,5 +1,5 @@
WARNING: Module DataFlow has been deprecated and may be removed in future (test-source-sink.ql:3,25-42)
WARNING: Module DataFlow has been deprecated and may be removed in future (test-source-sink.ql:3,57-74)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (test-source-sink.ql:3,25-42)
WARNING: module 'DataFlow' has been deprecated and may be removed in future (test-source-sink.ql:3,57-74)
astFlow
| BarrierGuard.cpp:5:19:5:24 | source | BarrierGuard.cpp:9:10:9:15 | source |
| BarrierGuard.cpp:13:17:13:22 | source | BarrierGuard.cpp:15:10:15:15 | source |
@@ -12,6 +12,10 @@ astFlow
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:62:14:62:14 | x |
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:64:14:64:14 | x |
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:66:14:66:14 | x |
| BarrierGuard.cpp:81:11:81:16 | call to source | BarrierGuard.cpp:86:8:86:8 | x |
| BarrierGuard.cpp:90:11:90:16 | call to source | BarrierGuard.cpp:101:8:101:8 | x |
| BarrierGuard.cpp:107:11:107:16 | call to source | BarrierGuard.cpp:112:8:112:8 | x |
| BarrierGuard.cpp:116:11:116:16 | call to source | BarrierGuard.cpp:127:8:127:8 | x |
| acrossLinkTargets.cpp:19:27:19:32 | call to source | acrossLinkTargets.cpp:12:8:12:8 | x |
| clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:18:8:18:19 | sourceArray1 |
| clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:22:8:22:20 | & ... |
@@ -153,6 +157,7 @@ irFlow
| clang.cpp:50:25:50:30 | call to source | clang.cpp:53:17:53:26 | *stackArray |
| clang.cpp:50:35:50:40 | call to source | clang.cpp:53:17:53:26 | *stackArray |
| clang.cpp:51:19:51:24 | call to source | clang.cpp:53:17:53:26 | *stackArray |
| clang.cpp:57:21:57:28 | call to source | clang.cpp:59:8:59:8 | d |
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:35:16:35:25 | call to notSource1 |
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:43:15:43:24 | call to notSource1 |
| dispatch.cpp:10:37:10:42 | call to source | dispatch.cpp:36:16:36:25 | call to notSource2 |
@@ -308,6 +313,7 @@ irFlow
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1027:19:1027:28 | *translated |
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1031:19:1031:28 | *translated |
| test.cpp:1045:14:1045:19 | call to source | test.cpp:1046:7:1046:10 | * ... |
| test.cpp:1081:27:1081:34 | call to source | test.cpp:1081:27:1081:34 | call to source |
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |

View File

@@ -1073,3 +1073,10 @@ void single_object_in_both_cases(bool b, int x, int y) {
*p = 0;
sink(*p); // clean
}
template<typename T>
void indirect_sink_const_ref(const T&);
void test_temp_with_conversion_from_materialization() {
indirect_sink_const_ref(source()); // $ ir MISSING: ast
}

View File

@@ -0,0 +1,107 @@
// --- stub library headers ---
namespace std {
typedef unsigned long size_t;
#define SIZE_MAX 0xFFFFFFFF
template <class T> class allocator {
};
template<class charT> struct char_traits {
};
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_string {
public:
basic_string(const charT* s, const Allocator& a = Allocator());
};
typedef basic_string<char> string;
};
namespace boost {
namespace system {
class error_code {
public:
operator bool() const;
};
};
namespace asio {
template<typename Protocol/*, typename Executor*/>
class basic_stream_socket /*: public basic_socket<Protocol, Executor>*/ {
};
namespace ip {
class tcp {
public:
typedef basic_stream_socket<tcp> socket;
};
};
template<typename Allocator = std::allocator<char>> class basic_streambuf {
public:
basic_streambuf(
std::size_t maximum_size = SIZE_MAX,
const Allocator &allocator = Allocator());
};
typedef basic_streambuf<> streambuf;
class mutable_buffer {
};
template<typename Elem, typename Traits, typename Allocator>
mutable_buffer buffer(std::basic_string<Elem, Traits, Allocator> & data);
template<typename SyncReadStream, typename Allocator> std::size_t read_until(
SyncReadStream &s,
asio::basic_streambuf<Allocator> &b,
char delim,
boost::system::error_code &ec);
template<typename SyncWriteStream, typename ConstBufferSequence> std::size_t write(
SyncWriteStream &s,
const ConstBufferSequence &buffers,
boost::system::error_code &ec,
int constraint = 0); // simplified
};
};
// --- test code ---
char *source();
void sink(char *);
void sink(std::string);
void sink(boost::asio::streambuf);
void sink(boost::asio::mutable_buffer);
char *getenv(const char *name);
int send(int, const void*, int, int);
void test(boost::asio::ip::tcp::socket &socket) {
boost::asio::streambuf recv_buffer;
boost::system::error_code error;
boost::asio::read_until(socket, recv_buffer, '\0', error);
if (error) {
// ...
}
sink(recv_buffer); // $ ir
boost::asio::write(socket, recv_buffer, error); // $ ir
// ---
std::string send_str = std::string(source());
sink(send_str); // $ ir
boost::asio::mutable_buffer send_buffer = boost::asio::buffer(send_str);
sink(send_buffer); // $ ir
boost::asio::write(socket, send_buffer, error); // $ ir
if (error) {
// ...
}
}

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,16 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: sourceModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
- ["", "", False, "ymlSource", "", "", "ReturnValue", "local", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: sinkModel
data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
- ["", "", False, "ymlSink", "", "", "Argument[0]", "test-sink", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["", "", False, "ymlStep", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]

View File

@@ -0,0 +1,34 @@
import TestUtilities.dataflow.FlowTestCommon
import cpp
import semmle.code.cpp.security.FlowSources
module IRTest {
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.TaintTracking
/** Common data flow configuration to be used by tests. */
module TestAllocationConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// external flow source node
sourceNode(source, _)
or
// test source function
source.asExpr().(FunctionCall).getTarget().getName() = "source"
}
predicate isSink(DataFlow::Node sink) {
// external flow sink node
sinkNode(sink, _)
or
// test sink function
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument()
)
}
}
module IRFlow = TaintTracking::Global<TestAllocationConfig>;
}
import MakeTest<IRFlowTest<IRTest::IRFlow>>

View File

@@ -0,0 +1,5 @@
| asio_streams.cpp:93:29:93:39 | *recv_buffer | remote-sink |
| asio_streams.cpp:103:29:103:39 | *send_buffer | remote-sink |
| test.cpp:9:10:9:10 | 0 | test-sink |
| test.cpp:11:10:11:10 | x | test-sink |
| test.cpp:15:10:15:10 | y | test-sink |

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: sinkModel
data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
- ["", "", False, "ymlSink", "", "", "Argument[0]", "test-sink", "manual"]

View File

@@ -0,0 +1,7 @@
import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.dataflow.ExternalFlow
from DataFlow::Node node, string kind
where sinkNode(node, kind)
select node, kind

View File

@@ -0,0 +1,2 @@
| asio_streams.cpp:87:34:87:44 | read_until output argument | remote |
| test.cpp:7:10:7:18 | call to ymlSource | local |

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: sourceModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
- ["", "", False, "ymlSource", "", "", "ReturnValue", "local", "manual"]

View File

@@ -0,0 +1,7 @@
import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.dataflow.ExternalFlow
from DataFlow::Node node, string kind
where sourceNode(node, kind)
select node, kind

View File

@@ -0,0 +1,2 @@
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer |
| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep |

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