Compare commits

...

270 Commits

Author SHA1 Message Date
Ian Lynagh
c354b544e4 Java: Add expanded arguments 2023-03-22 15:44:07 +00:00
Chris Smowton
288e9206c7 Merge remote-tracking branch 'origin/rc/3.9' into smowton/admin/merge-rc39-into-main 2023-03-21 14:36:43 +00:00
Chris Smowton
834511bd78 Merge pull request #12617 from github/fc-3.9-mergeback
Mergeback from rc/3.9 to main for small docs change
2023-03-21 14:36:20 +00:00
Edward Minnix III
b102ddac30 Merge pull request #12542 from egregius313/egregius313/refactor-more-queries-to-dataflow-module-api
Java: Refactor more queries to the new DataFlow module API (part 2)
2023-03-21 10:35:29 -04:00
Felicity Chapman
92a31608a2 Merge branch 'rc/3.9' into fc-3.9-mergeback 2023-03-21 14:16:51 +00:00
Jeroen Ketema
574b2201cb Merge pull request #12608 from jketema/configsig
C++: Use `DataFlow::ConfigSig` in more places
2023-03-21 14:37:32 +01:00
Tom Hvitved
5260d9815a Merge pull request #12582 from hvitved/ruby/element-of-type-content-set
Ruby: Introduce `ContentSet::isElementOfType[OrUnknown]/1`
2023-03-21 13:41:15 +01:00
Rasmus Wriedt Larsen
caa25f78d9 Merge pull request #12607 from RasmusWL/fix-dataflow-consistency-output
Python: Accept dataflow-consistency test changes
2023-03-21 13:20:29 +01:00
Mathias Vorreiter Pedersen
98dc73c6dd Merge pull request #12611 from MathiasVP/buffer-access-should-be-evaluated
C++: Exclude unevaluated accesses in `BufferAccess`
2023-03-21 12:10:37 +00:00
Asger F
6d665da4dc Merge pull request #12570 from github/post-release-prep/codeql-cli-2.12.5
Post-release preparation for codeql-cli-2.12.5
2023-03-21 13:06:25 +01:00
Chris Smowton
219031f62b Merge pull request #12609 from smowton/smowton/admin/maven-wrapper-http-test
Java: maven-http-repository test: add Maven wrapper
2023-03-21 11:14:19 +00:00
Mathias Vorreiter Pedersen
2ce0d2b7ee C++: Accept more test changes. 2023-03-21 10:07:23 +00:00
Mathias Vorreiter Pedersen
eab43973b7 C++: Add change note. 2023-03-21 10:00:11 +00:00
yoff
4e6b93e239 Merge branch 'main' into fix-dataflow-consistency-output 2023-03-21 10:57:36 +01:00
Mathias Vorreiter Pedersen
40cc2e7891 C++: Also exclude unevaluated buffers in 'OverflowStatic'. 2023-03-21 09:53:39 +00:00
Mathias Vorreiter Pedersen
4d2a1ea149 C++: Also add a FP test to 'OverflowStatic'. 2023-03-21 09:50:47 +00:00
Mathias Vorreiter Pedersen
8623d8eb8e C++: Exclude unevaluated expressions from BufferAccess. 2023-03-21 09:48:09 +00:00
Mathias Vorreiter Pedersen
b37bb660c5 C++: Add FP caused by a BufferAccess inside an unevalauted context. 2023-03-21 09:37:18 +00:00
Chris Smowton
2876b4aa5d maven-httpo-repository: add Maven wrapper
Maven 3.9.1 changes the format of the error message this test is looking for (though it still matches the target regex). Use the Maven wrapper to avoid such sensitivity to the precise version present in the environment.
2023-03-21 09:25:33 +00:00
Tony Torralba
956f991b8d Merge pull request #12603 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-03-21 10:11:51 +01:00
Rasmus Wriedt Larsen
346086524b Python: Accept dataflow-consistency test changes
To PRs must have had a conflict when merged separately
2023-03-21 10:09:01 +01:00
Tony Torralba
1f991807d4 Merge pull request #12366 from github/java/update-mad-decls-after-triage-2023-03-02T12-08-59
Java: Update MaD Declarations after Triage
2023-03-21 09:40:03 +01:00
Jeroen Ketema
2fdfa0808a C++: Refactor experimental queries to use DataFlow::ConfigSig 2023-03-21 09:16:59 +01:00
Jeroen Ketema
1f75c3836e C++: Refactor dataflow examples to use DataFlow::ConfigSig 2023-03-21 09:16:58 +01:00
Jeroen Ketema
4e752369c5 Merge pull request #12598 from jketema/default-config
C++: Adjust the internals of default taint tracking to use `DataFlow::ConfigSig`
2023-03-21 08:59:27 +01:00
Erik Krogh Kristensen
cc46d7fef3 Merge pull request #12605 from github/dependabot/cargo/ql/serde-1.0.158
Bump serde from 1.0.157 to 1.0.158 in /ql
2023-03-21 08:20:13 +01:00
dependabot[bot]
7420e90a46 Bump serde from 1.0.157 to 1.0.158 in /ql
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.157 to 1.0.158.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.157...v1.0.158)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 04:06:18 +00:00
github-actions[bot]
6598cc44ee Add changed framework coverage reports 2023-03-21 00:15:33 +00:00
Jeroen Ketema
7cdd2b69c9 C++: Adjust the internals of default taint tracking to use DataFlow::ConfigSig 2023-03-20 18:58:16 +01:00
AlexDenisov
43b3f379e9 Merge pull request #12596 from github/redsun82/swift-do-not-print-labels-in-function-types
Swift: remove labels from function type printing
2023-03-20 18:01:02 +01:00
Ed Minnix
b64ca5dcaa Remove "private" marker from configurations 2023-03-20 12:26:54 -04:00
Ed Minnix
c7816ea180 Conform Config modules to naming convention 2023-03-20 12:26:54 -04:00
Ed Minnix
8856730843 Refactor CWE-614/InsecureCookie 2023-03-20 12:26:54 -04:00
Ed Minnix
de6959c688 Refactor CWE-209/StackTraceExposure 2023-03-20 12:26:54 -04:00
Ed Minnix
73a17536f5 Refactor CWE-129 queries 2023-03-20 12:26:54 -04:00
Ed Minnix
ae57807359 Refactor CWE-089 Sql queries 2023-03-20 12:26:54 -04:00
Ed Minnix
e6e974a752 Refactor CWE-079/SqlConcatenated 2023-03-20 12:26:54 -04:00
Ed Minnix
c1ee2dce61 Refactor CWE-078/ExecTaintedLocal 2023-03-20 12:26:54 -04:00
Edward Minnix III
ac58299d9e Merge pull request #12541 from egregius313/egregius313/refactor-queries-to-new-dataflow-api
Java: Refactor more queries to the new DataFlow module API
2023-03-20 12:24:26 -04:00
Tony Torralba
1258812428 Fix Argument[this] 2023-03-20 17:13:44 +01:00
Tony Torralba
f685b93379 Add change note 2023-03-20 17:09:48 +01:00
Tony Torralba
a66b7ed54a Fix incorrect model, add missing model 2023-03-20 17:09:48 +01:00
Stephan Brandauer
0cab45e4b9 update old data to current standard (stream creation arg is a sink) 2023-03-20 17:09:48 +01:00
Stephan Brandauer
8802fbdfe7 Update java/ql/lib/ext/java.nio.file.model.yml
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2023-03-20 17:09:48 +01:00
Stephan Brandauer
bc227179c7 Update java/ql/lib/ext/org.geogebra.web.full.main.model.yml
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2023-03-20 17:09:48 +01:00
Tony Torralba
bc99a44f3a Apply suggestions from code review 2023-03-20 17:09:48 +01:00
Stephan Brandauer
12bb0d98c0 move toFile back to its original location 2023-03-20 17:09:48 +01:00
Stephan Brandauer
4761c3a328 remove duplicates 2023-03-20 17:09:48 +01:00
Stephan Brandauer
bd21dc9460 remove nonexploitable sinks 2023-03-20 17:09:48 +01:00
Stephan Brandauer
b7ce0c2d96 fix: taint flow of ctor goes to Argument[-1], instead of ReturnValue 2023-03-20 17:09:48 +01:00
Stephan Brandauer
2236db43ec sort the changed MaD declarations 2023-03-20 17:09:46 +01:00
Stephan Brandauer
74e261738f remove predicate 2023-03-20 17:06:40 +01:00
Stephan Brandauer
ec1762e015 Update MaD Declarations after Triage 2023-03-20 17:06:37 +01:00
Tony Torralba
fa60fa0ae2 Merge pull request #12572 from github/java/update-mad-decls-after-triage-2023-03-17T15-01-35
Java: Update MaD Declarations after Triage
2023-03-20 17:02:27 +01:00
Paolo Tranquilli
aaea976cf2 Swift: remove labels from function type printing 2023-03-20 16:43:34 +01:00
Anders Schack-Mulligen
3876e4335f Merge pull request #12420 from kaspersv/kaspersv/dataflow-remove-alias-preds
Dataflow: Remove revFlowAlias and revFlowApAlias predicates
2023-03-20 16:30:15 +01:00
Alex Ford
be163cfc38 Merge pull request #12311 from maikypedia/maikypedia/ruby-ssti
Ruby: Add Server Side Template Injection query
2023-03-20 15:26:27 +00:00
Michael Nebel
17b3383043 Merge pull request #12556 from michaelnebel/java/argumentthis
Java: Argument[-1] -> Argument[this]
2023-03-20 15:59:59 +01:00
Erik Krogh Kristensen
a9d40d39d9 Merge pull request #12550 from erik-krogh/useNumberUtil
Java/Python: use Number.qll to parse hex numbers in regex parsing
2023-03-20 15:50:31 +01:00
Erik Krogh Kristensen
0f813ce2e8 Merge pull request #12543 from erik-krogh/reg-perf
ReDoS: restrict the edges considered in polynomial-redos for complex regular expressions
2023-03-20 15:48:35 +01:00
Jeroen Ketema
c56c1cbb62 Merge pull request #12588 from jketema/boost-config
C++: Refactor `BoostorgAsio` to use `DataFlow::ConfigSig`
2023-03-20 15:31:35 +01:00
yoff
6639e5a97b Merge pull request #12590 from yoff/python/patch-uninitialized-local
Python: Patch uninitialized local query
2023-03-20 15:11:14 +01:00
yoff
17c9ba9872 Merge pull request #12464 from yoff/python/add-test-captured-in-collection
python: add test for captured variables in lists
2023-03-20 15:01:58 +01:00
Rasmus Lerchedahl Petersen
ed15cce31f python: add change note 2023-03-20 14:22:58 +01:00
Chuan-kai Lin
8c738b77a3 Merge pull request #12574 from cklin/document-upgrade-query-predicates
Document upgrade query predicates
2023-03-20 06:16:34 -07:00
Rasmus Lerchedahl Petersen
b042c60ca3 python: remove outdated comment 2023-03-20 14:13:48 +01:00
Stephan Brandauer
39726a54ec fix suggestion 2023-03-20 14:12:46 +01:00
Rasmus Lerchedahl Petersen
72e97918e9 python: format 2023-03-20 14:11:10 +01:00
Jeroen Ketema
bbe95367d6 C++: Simplify SslContextCallMake 2023-03-20 14:00:03 +01:00
Geoffrey White
a19579d21b Merge pull request #12587 from geoffw0/finishbitwise
Swift: Remove special case for bitwise operations
2023-03-20 12:59:31 +00:00
Jeroen Ketema
2968c12e12 Merge pull request #12583 from jketema/move-print
C++: Move SsaConsistency to its own file
2023-03-20 13:41:29 +01:00
Jeroen Ketema
9997326804 C++: Refactor BoostorgAsio to use DataFlow::ConfigSig 2023-03-20 13:37:18 +01:00
Rasmus Lerchedahl Petersen
5f438e433d python: exclude nonlocals from query 2023-03-20 13:34:39 +01:00
Kasper Svendsen
1d2f1b6ae6 Address comments 2023-03-20 13:34:14 +01:00
Ed Minnix
83b0d073f0 Fix typo in QLDoc 2023-03-20 08:11:01 -04:00
Ed Minnix
1c661fd3ac Add missing QLDocs 2023-03-20 08:10:07 -04:00
Kasper Svendsen
e0e3a1d621 Dataflow: remove revFlowApAlias trick 2023-03-20 13:04:13 +01:00
Rasmus Lerchedahl Petersen
9b7a20f4ad python: add example showing FP 2023-03-20 13:03:26 +01:00
Ed Minnix
84fd5f7ee0 Fix naming of ZipSlip configuration 2023-03-20 07:55:23 -04:00
Ed Minnix
60a4a79537 Make the Config module of public Flow modules public
This is to make things easier for the CodeML/ATM team once these
configurations are moved from `src/` to `lib/`.
2023-03-20 07:47:55 -04:00
Edward Minnix III
9aa83d78e1 Merge pull request #12575 from egregius313/egregius313/ql/dataflow-naming-convention-check
QL: add a check to enforce naming convention for new `DataFlow::ConfigSig` modules
2023-03-20 07:26:01 -04:00
Edward Minnix III
1c06afffe5 Merge pull request #12578 from egregius313/egregius313/conform-dataflow-configs-to-config-naming-convention
Conform dataflow config modules to follow `*Config` naming convention
2023-03-20 07:25:10 -04:00
Geoffrey White
166902bfa0 Swift: Remove the special case for bitwise operations in the XXE query (but upgrade that bit of the query to taint flow as appears to be intended). 2023-03-20 11:18:17 +00:00
erik-krogh
ef498020c2 PY: dont depend on codeql/util in src/ now that its added to lib/ 2023-03-20 12:11:06 +01:00
Geoffrey White
1f8a165611 Swift: Add a couple of extra test cases. 2023-03-20 10:58:58 +00:00
Paolo Tranquilli
029d924e6d Merge pull request #12580 from github/redsun82/swift-more-precise-successfully-extracted-query
Swift: make `SuccessfullyExtractedFiles.ql` more precise
2023-03-20 11:05:54 +01:00
Erik Krogh Kristensen
2270d6fa61 fix typo
Co-authored-by: Taus <tausbn@github.com>
2023-03-20 10:56:30 +01:00
Alex Ford
4b1171ce64 Merge branch 'main' into maikypedia/ruby-ssti 2023-03-20 09:55:53 +00:00
Tony Torralba
27fc14236f Add change note 2023-03-20 10:48:56 +01:00
Tony Torralba
bff8bbfe33 Apply suggestions from code review 2023-03-20 10:43:46 +01:00
Jeroen Ketema
91b069603d C++: Move SsaConsistency to its own file
This removes the import of the `Print` library in places that are used in
production and not just debugging.
2023-03-20 10:31:33 +01:00
Michael Nebel
01ade878ea Java: Update test comments to use this instead of -1. 2023-03-20 10:14:20 +01:00
Michael Nebel
ba711ab849 Java: Update expected test-output (different sorting). 2023-03-20 10:14:20 +01:00
Michael Nebel
ae12510d8d Java: Add change-note. 2023-03-20 10:14:20 +01:00
Michael Nebel
9039a468cb Java: Update models that uses -1 in a range. 2023-03-20 10:14:20 +01:00
Michael Nebel
e86f1e4961 Java: Replace Argument[-1] with Argument[this]. 2023-03-20 10:14:20 +01:00
Tom Hvitved
a9ef3f95a2 Ruby: Introduce ContentSet::isElementOfType[OrUnknown]/1 2023-03-20 10:03:15 +01:00
Michael Nebel
e78af3e66c C#: Introduce Argument and Parameter index validation for models. 2023-03-20 09:38:40 +01:00
Michael Nebel
37484a415f Sync files. 2023-03-20 09:38:40 +01:00
Michael Nebel
0ec56203f9 Java: Introduce index validation. 2023-03-20 09:38:40 +01:00
Michael Nebel
9a3c2d3fbe Java: Update summary parsing to use this instead of -1 and adjust the model generator. 2023-03-20 09:38:40 +01:00
Michael Nebel
abd9f673e1 Java: Update the java internal documentation for models. 2023-03-20 09:38:39 +01:00
Michael Nebel
352bb5a29a C#: Update internal documentation for this parameter in models. 2023-03-20 09:38:39 +01:00
Tony Torralba
8457d45edc Merge pull request #12577 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-03-20 09:26:18 +01:00
Kasper Svendsen
9630feb5e4 Dataflow: Remove revFlowAlias trick 2023-03-20 09:04:35 +01:00
Erik Krogh Kristensen
540542ceb5 Merge pull request #12518 from erik-krogh/more-express-sources
JS: recognize more express URL related sources
2023-03-20 08:49:11 +01:00
Erik Krogh Kristensen
af98ceb3c3 Merge pull request #11478 from erik-krogh/more-shell-taint
Rb: more taint-steps for shell-command-construction
2023-03-20 08:41:22 +01:00
Paolo Tranquilli
a131966066 Swift: make SuccessfullyExtractedFiles.ql more precise
This is done by adding a `isSuccessfullyExtracted` predicate that is
filled for primary files at the very end of the extractor invocation if
the frontend was performed successfully. If for example the extractor
crashes this will therefore not be filled.

The upgrade script is written so that `SuccessfullyExtractedFiles.ql`
on an upgraded script will give exactly the same results as before it.
2023-03-20 08:34:34 +01:00
Erik Krogh Kristensen
5f14af5db0 Merge pull request #12579 from github/dependabot/cargo/ql/serde-1.0.157
Bump serde from 1.0.156 to 1.0.157 in /ql
2023-03-20 08:02:23 +01:00
dependabot[bot]
9b3b6632fc Bump serde from 1.0.156 to 1.0.157 in /ql
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.156 to 1.0.157.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.156...v1.0.157)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 04:09:27 +00:00
github-actions[bot]
0d36a5a733 Add changed framework coverage reports 2023-03-20 00:17:11 +00:00
Ed Minnix
c852d3a541 Rename configurations from "Conf" to "Config" 2023-03-19 17:55:53 -04:00
Ed Minnix
2d5944fb0e Refactor DataFlow configurations to use "Config" naming convention 2023-03-19 17:44:07 -04:00
Ed Minnix
d743b31ab6 Fix typo in QLdoc 2023-03-19 13:45:46 -04:00
Mathias Vorreiter Pedersen
b0f803759c Merge pull request #11928 from rdmarsh2/rdmarsh2/stageify-range-analysis 2023-03-18 12:42:49 +00:00
Ed Minnix
00267637eb Implementation of check for DataFlow naming convention 2023-03-17 15:47:15 -04:00
Ed Minnix
7eb3fd2ff7 Conform queries to Config naming convention 2023-03-17 15:17:18 -04:00
Ed Minnix
d317de14c9 XXE Configuration Deprecation messages 2023-03-17 15:17:18 -04:00
Ed Minnix
310af99843 Refactor Security.CWE.CWE-807.TaintedPermissionsCheck 2023-03-17 15:17:18 -04:00
Ed Minnix
a9561a97c3 Refactor Security.CWE.CWE-643.XPathInjection 2023-03-17 15:17:18 -04:00
Ed Minnix
271d50ba99 Refactor Security.CWE.CWE-611 Xxe queries 2023-03-17 15:17:18 -04:00
Ed Minnix
80012b190d Refactor Security.CWE.CWE-601.UrlRedirect 2023-03-17 15:17:18 -04:00
Ed Minnix
481d1f9b15 Refactor Security.CWE.CWE-297.UnsafeHostnameVerification 2023-03-17 15:17:18 -04:00
Ed Minnix
7bd7ecd9e6 Refactor Security.CWE.CWE-190 Arithmetic queries 2023-03-17 15:17:18 -04:00
Ed Minnix
4a202b430f Security.CWE.CWE-200.AndroidWebViewSettingsAllowsContentAccess 2023-03-17 15:17:18 -04:00
Ed Minnix
d34dbbc96f Refactor Security.CWE.CWE-134.ExternallyControlledFormatString 2023-03-17 15:17:18 -04:00
Ed Minnix
ac223ea57f Refactor Security.CWE.CWE-094.InsecureBeanValidation 2023-03-17 15:17:18 -04:00
Ed Minnix
7aecefc4aa Refactor Security.CWE.CWE-090.LdapInjectionLib 2023-03-17 15:17:18 -04:00
Ed Minnix
07fdcf2d04 Refactor Security.CWE.CWE-022.ZipSlip 2023-03-17 15:17:18 -04:00
Ed Minnix
e60e1a2ba9 Refactor Security.CWE.CWE-022.TaintedPathLocal 2023-03-17 15:17:18 -04:00
Chuan-kai Lin
4dd7dbc73b Document upgrade query predicates 2023-03-17 11:06:39 -07:00
Stephan Brandauer
dce81cf0ae Merge pull request #12463 from github/java/update-mad-decls-after-triage-2023-03-09T10-41-58
Java: Add MaD declarations after triage
2023-03-17 17:02:42 +01:00
Robert Marsh
1e8404c954 C++: Remove fixed TODO
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2023-03-17 11:27:13 -04:00
Stephan Brandauer
8f565f5023 Update MaD Declarations after Triage 2023-03-17 16:01:36 +01:00
Robert Marsh
726f99975e C++: remove direct IR dependency in range analysis 2023-03-17 10:50:02 -04:00
github-actions[bot]
981e171525 Post-release preparation for codeql-cli-2.12.5 2023-03-17 13:27:00 +00:00
AlexDenisov
208ae192e4 Merge pull request #12567 from github/alexdenisov/swift-extracted-files
Swift: add a query showing successfully extracted files
2023-03-17 13:50:42 +01:00
Paolo Tranquilli
86b61d712c Merge pull request #12565 from github/redsun82/swift-remove-labels-from-function-type
Swift: remove parameter labels from function types
2023-03-17 13:49:37 +01:00
Asger F
d537f86324 Merge pull request #12555 from asgerf/js/block-modes
JS: Include weak block modes as sink in weak crypto algorithm
2023-03-17 13:23:23 +01:00
Henry Mercer
9d05d94f49 Merge pull request #12568 from github/rc/3.9
Merge `rc/3.9` back to `main`
2023-03-17 12:14:31 +00:00
Alex Ford
e84b08409c Ruby: test fixes 2023-03-17 12:08:38 +00:00
Erik Krogh Kristensen
ac85b6e74f Merge pull request #12011 from erik-krogh/ts50
JS: Add support for TypeScript 5.0
2023-03-17 13:03:47 +01:00
Chris Smowton
0cadf4d94a Merge pull request #12558 from smowton/smowton/fix/flow-to-external-api-write-only-methods
Go: exclude `net/http.Header.Set` and `.Del` from `go/untrusted-data-to-external-api`
2023-03-17 11:52:48 +00:00
Alex Ford
c12a85b07b Ruby: autoformat 2023-03-17 11:49:10 +00:00
Ian Lynagh
b8fb4b9b0f Merge pull request #12521 from igfoo/igfoo/printast_sig
Java: PrintAst: Improve the ranking of callables
2023-03-17 11:43:40 +00:00
Alex Ford
76ed56d2b6 Ruby: typo 2023-03-17 11:40:59 +00:00
Alex Ford
ee6288173f Ruby: remove extra opening p tag 2023-03-17 11:38:49 +00:00
Alex Ford
60f313863a Merge branch 'main' into maikypedia/ruby-ssti 2023-03-17 11:31:49 +00:00
Alex Denisov
7c15527300 Swift: add a query showing successfully extracted files 2023-03-17 11:27:03 +01:00
Asger F
940e492766 Merge pull request #12551 from github/release-prep/2.12.5
Release preparation for version 2.12.5
2023-03-17 11:23:25 +01:00
Mathias Vorreiter Pedersen
1aecc64327 C++: Autoformat. 2023-03-17 09:37:46 +00:00
Michael Nebel
282b5d4836 Merge pull request #12538 from michaelnebel/emptypredworkaround
DataFlow: Workaround empty predicate usage in IPA branch.
2023-03-17 10:29:19 +01:00
Paolo Tranquilli
f2dff092dc Swift: remove parameter labels from function types
As discussed [in this accepted proposal][1], parameter labels do not
take part any more in making up a function type, so we need to not
extract them any more to avoid DB inconsistencies.

These were unused in the library, which makes the upgrade and downgrade
scripts have full compatibility.

[1]: 9c53790a13/proposals/0111-remove-arg-label-type-significance.md
2023-03-17 10:22:02 +01:00
Tom Hvitved
d2647850d2 Merge pull request #12564 from hvitved/ruby/remove-redundant-super-prefixes
Ruby: Remove some redundant `super` type qualifiers
2023-03-17 10:13:45 +01:00
Tom Hvitved
d146d816a9 Ruby: Fix semantic merge conflict 2023-03-17 09:59:44 +01:00
Tom Hvitved
e69e90db4a Ruby: Remove some redundant super type qualifiers 2023-03-17 09:32:13 +01:00
Tom Hvitved
75746cbacc Merge pull request #12549 from hvitved/ruby/ssa-write-access
Ruby: `Ssa::WriteDefinition::getWriteAccess` should return a CFG node
2023-03-17 09:31:14 +01:00
Tom Hvitved
ee01e9ab35 Merge pull request #12554 from hvitved/ruby/clear-text-logging-hashes
Ruby: Rely on built-in hash-flow in clear text storage query
2023-03-17 09:21:11 +01:00
Harry Maclean
2c63dbad67 Merge pull request #11954 from hmac/sinatra
Ruby: Model Sinatra
2023-03-17 10:46:52 +13:00
erik-krogh
f1094cd3d6 bump to stable release 2023-03-16 22:38:54 +01:00
erik-krogh
f3c7aed1f9 bump to RC 2023-03-16 22:37:58 +01:00
erik-krogh
e00c41c6e2 add change-note and bump version 2023-03-16 22:37:56 +01:00
erik-krogh
a63739915d add test confirming support for const type parameters 2023-03-16 22:37:35 +01:00
erik-krogh
2c1c41d8a3 add test confirming end-to-end support for well-typed decorators with the new TS 5.0 type ClassMethodDecoratorContext 2023-03-16 22:37:35 +01:00
erik-krogh
d47659b48e upgrade to TypeScript 5.0 beta, and unbreak things that broke 2023-03-16 22:37:35 +01:00
Maiky
37e42bb05b Missing markdown extension 2023-03-16 20:45:35 +01:00
Mathias Vorreiter Pedersen
ebab6ecc30 Merge pull request #12559 from MathiasVP/test9-range-check 2023-03-16 19:18:38 +00:00
Geoffrey White
880f948763 Merge pull request #12560 from geoffw0/testcustominterp
Swift: Add taint test for custom string interpolation.
2023-03-16 17:44:37 +00:00
Mathias Vorreiter Pedersen
406d02253d C++: Add 'range(x)' call demonstrating missing bounds. 2023-03-16 17:08:53 +00:00
Geoffrey White
3a04e42ae0 Swift: Add taint test for string interpolation. 2023-03-16 17:04:46 +00:00
Chris Smowton
3e9924fcd2 Add change note 2023-03-16 15:35:00 +00:00
Chris Smowton
647bd44666 Go: exclude net/http.Header.Set and .Del from go/untrusted-data-to-external-api
These functions (and doubtless many others) are write-only with respect to their receiver argument, so it doesn't really make sense to flag externally-controlled data flowing there.
2023-03-16 15:31:35 +00:00
Ian Lynagh
f9bb0df6a2 Kotlin: Update expected PrintAst output 2023-03-16 15:20:07 +00:00
Ian Lynagh
13c2ef8c20 Java: PrintAst: Improve the ranking or callables
We now look not only at how many parameters each callable has, but what
its full signature is. This allows us to give a consistent order to
    Test(Throwable) { ... }
    Test(String) { ... }
2023-03-16 15:20:07 +00:00
Maiky
a229f7a832 Solve merge conflict and add a change note 2023-03-16 16:15:02 +01:00
Tom Hvitved
f35fb13723 Add change note 2023-03-16 15:18:47 +01:00
Tom Hvitved
9d3863eccc Ruby: Rely on built-in hash-flow in clear text storage query 2023-03-16 14:55:06 +01:00
Asger F
bce1f29a7e JS: Add change note 2023-03-16 14:55:00 +01:00
Asger F
86a06bde72 JS: Flag crypto operations with weak block mode 2023-03-16 14:52:52 +01:00
Asger F
e907d685f4 JS: Add crypto test with AES-ECB 2023-03-16 14:52:18 +01:00
Tom Hvitved
ae10e6e08f Ruby: Add a test that shows FP/FN for clear text logging query 2023-03-16 14:38:45 +01:00
Jeroen Ketema
66b03dbd1d Apply suggestions from code review 2023-03-16 14:29:16 +01:00
Jeroen Ketema
e7079b35bc Apply suggestions from code review 2023-03-16 14:28:17 +01:00
erik-krogh
880632f536 use Number.qll to parse hex numbers in regex parsing for Python/Java 2023-03-16 14:25:53 +01:00
Michael Nebel
3fea9e4d0b Sync files. 2023-03-16 14:12:29 +01:00
Michael Nebel
2e86bbd6cd Java: Introduce helper predicate to avoid empty predicate in IPA branch. 2023-03-16 14:11:53 +01:00
github-actions[bot]
fe4d27e8cc Release preparation for version 2.12.5 2023-03-16 12:58:50 +00:00
Michael Nebel
a9e5b34ad6 Merge pull request #12200 from michaelnebel/csharp/viablestatic
C#: Support for virtual dispatch for operators.
2023-03-16 13:36:00 +01:00
erik-krogh
f718d78a9a avoid redundant sources 2023-03-16 13:34:01 +01:00
Mathias Vorreiter Pedersen
d02a50a504 Merge pull request #10817 from github/mathiasvp/replace-ast-with-ir-use-usedataflow
C++: Replace AST with IR use-use dataflow
2023-03-16 12:31:01 +00:00
erik-krogh
b208988675 Py: add test for problematic regex 2023-03-16 12:21:00 +01:00
erik-krogh
54ec047433 ReDoS: put an artificial limitation on the analysis in polynomial-redos for large regular expressions 2023-03-16 12:20:53 +01:00
Tom Hvitved
1d0b3d4112 Ruby: Ssa::WriteDefinition::getWriteAccess should return a CFG node 2023-03-16 11:28:24 +01:00
Chris Smowton
3ff60e076c Merge pull request #12548 from github/dependabot/github_actions/actions/setup-go-4
Bump actions/setup-go from 3 to 4
2023-03-16 10:21:51 +00:00
erik-krogh
8bc8342c7c Py:don't parse regular expressions in system-code 2023-03-16 10:41:30 +01:00
Erik Krogh Kristensen
be8f04a997 Merge pull request #12525 from github/dependabot/cargo/ql/serde-1.0.156
Bump serde from 1.0.155 to 1.0.156 in /ql
2023-03-16 10:36:11 +01:00
Erik Krogh Kristensen
48f889b055 Merge pull request #12496 from github/dependabot/cargo/ql/chrono-0.4.24
Bump chrono from 0.4.23 to 0.4.24 in /ql
2023-03-16 10:35:59 +01:00
dependabot[bot]
e999d33332 Bump actions/setup-go from 3 to 4
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3 to 4.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-16 04:00:39 +00:00
Robert Marsh
45fdf69461 C++: add SemLocation so SemBound is copy-shareable 2023-03-15 10:38:47 -04:00
Tony Torralba
5bc606753e org.openjdk.jmh.runner.options tests 2023-03-15 14:47:27 +01:00
Tony Torralba
3b4980ba2f org.kohsuke.stapler.model tests 2023-03-15 14:36:45 +01:00
Tony Torralba
c5a1905302 Fix stubs 2023-03-15 12:43:45 +01:00
Tony Torralba
341590f9ad org.kohsuke.stapler.framework.io tests 2023-03-15 11:43:52 +01:00
Tony Torralba
e0c852c0b8 Fix stubs and test expectations 2023-03-15 11:33:02 +01:00
erik-krogh
cc3efcd35e also restrict allowImplicitRead in unsafe-code-construction 2023-03-15 11:11:20 +01:00
erik-krogh
2133d1a5ab Merge branch 'main' into more-shell-taint 2023-03-15 10:54:30 +01:00
erik-krogh
a72436f6f1 recognize more express URL related sources 2023-03-15 10:14:31 +01:00
dependabot[bot]
f811436cff Bump serde from 1.0.155 to 1.0.156 in /ql
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.155 to 1.0.156.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.155...v1.0.156)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 04:05:38 +00:00
Robert Marsh
623e39031c C++: fix ModulusAnalysis test 2023-03-14 16:46:09 -04:00
Tony Torralba
fe1cc405eb org.kohsuke.stapler.framework.adjunct tests 2023-03-14 18:21:38 +01:00
Tony Torralba
44f239f4a4 Fix org.kohsuke.stapler.framework.adjunct models 2023-03-14 18:21:19 +01:00
Tony Torralba
cbc0ba6ac6 org.apache.tools.zip tests 2023-03-14 17:41:20 +01:00
Tony Torralba
7455c27086 org.apache.tools.ant.taskdefs tests 2023-03-14 17:28:35 +01:00
Tony Torralba
6aa9726223 org.apache.tools.ant tests 2023-03-14 17:20:31 +01:00
Tony Torralba
db9e305a56 org.apache.commons.jelly tests 2023-03-14 17:04:14 +01:00
Robert Marsh
267c341965 C++: exclude ZeroBounds in relative stage 2023-03-14 10:41:50 -04:00
Tony Torralba
31667b4478 org.apache.commons.io tests 2023-03-14 12:50:09 +01:00
Tony Torralba
720cf0ab7a org.apache.commons.compress.archivers.tar tests 2023-03-14 12:31:26 +01:00
Tony Torralba
3db95f3ac9 javax.xml.transform.stream tests 2023-03-14 12:28:04 +01:00
Tony Torralba
d54abddab1 java.nio.file tests 2023-03-14 12:22:56 +01:00
Tony Torralba
2e7ad99059 Fix java.nio.file models 2023-03-14 11:51:44 +01:00
Tony Torralba
452b9d11db java.net tests 2023-03-14 11:43:23 +01:00
Tony Torralba
cad5cd4037 java.io tests 2023-03-14 11:21:33 +01:00
Tony Torralba
db83fe6f42 Fix incorrect java.io models 2023-03-14 11:21:17 +01:00
Tony Torralba
8cc2686a2f netty.resolver tests 2023-03-14 11:09:26 +01:00
Tony Torralba
1b85e8b706 hudson.remoting tests 2023-03-14 11:00:27 +01:00
Stephan Brandauer
ccf7d9beec Update MaD Declarations after Triage 2023-03-14 10:32:19 +01:00
erik-krogh
984a589954 don't depend on the callgraph in KernelArraySummary 2023-03-14 09:20:24 +01:00
erik-krogh
4307889b1f specialize allowImplicitRead in unsafe-shell-command-construction to fix performance 2023-03-14 08:42:11 +01:00
Robert Marsh
b4b7507fe4 C++: autoformat 2023-03-13 15:45:48 -04:00
erik-krogh
8b99e8af88 fix bad join by removing bad recursion 2023-03-13 17:34:11 +01:00
erik-krogh
25a6d496d9 Merge branch 'main' into HEAD 2023-03-13 17:33:06 +01:00
Michael Nebel
41b2273dee C#: Update expected test output. 2023-03-13 15:15:03 +01:00
Michael Nebel
e2479940d2 C#: Overridable operator support in dispatch. 2023-03-13 15:15:03 +01:00
dependabot[bot]
df45ba0476 Bump chrono from 0.4.23 to 0.4.24 in /ql
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.23 to 0.4.24.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.23...v0.4.24)

---
updated-dependencies:
- dependency-name: chrono
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 12:25:21 +00:00
Michael Nebel
8398ee43b3 C#: Update test comment and expected test output. 2023-03-13 10:09:03 +01:00
Michael Nebel
a964f536e8 C#: Fix issue with dispatch to implementations of virtual interface members. 2023-03-13 10:09:03 +01:00
Michael Nebel
278f90e5fa C#: Update expected test output. 2023-03-13 10:09:03 +01:00
Michael Nebel
cfe2a76431 C#: Add viable callable test cases for statics in interfaces. 2023-03-13 10:09:03 +01:00
Harry Maclean
3734a544bc Ruby: Add change note 2023-03-13 21:38:45 +13:00
Harry Maclean
e80ff4efba Ruby: Fix tests and qldoc 2023-03-13 20:32:37 +13:00
Harry Maclean
071517c74b Ruby: Clean up Sinatra modeling 2023-03-13 19:25:56 +13:00
Harry Maclean
bfe42a656c Ruby: QL4QL fix 2023-03-13 19:04:46 +13:00
Harry Maclean
384e7c7a80 Jump step for sinatra callbacks 2023-03-13 19:03:32 +13:00
Harry Maclean
e65d7224db Ruby: tests, patterns, fix erb flow 2023-03-13 19:03:32 +13:00
Harry Maclean
eada3b91df Ruby: track flow from sinatra routes to erb files 2023-03-13 19:03:32 +13:00
Harry Maclean
c82b4638c6 Ruby: Import Sinatra modeling by default 2023-03-13 19:03:32 +13:00
Harry Maclean
a1fab31bfc Ruby: Model Sinatra
Adds some very basic modeling of Sinatra applications.
We recognise the `params` call in Sinatra routes as an HTTP request
input access.
2023-03-13 19:03:32 +13:00
Robert Marsh
d4e3f7f738 C++: fix missing bounds in new range analysis 2023-03-10 14:23:08 -05:00
Rasmus Lerchedahl Petersen
bbb43a53e5 python: add test for captured variables
this illustrates that the function implementing
the comprehension does not capture `mod_local`.

We could handle this case specially, by having
a different implementation for `for`, but the
wider issue would remain.
2023-03-09 11:44:58 +01:00
Robert Marsh
b941d54f1f C++ Move RangeAnalysis to work around shadowing 2023-03-08 11:32:37 -05:00
Robert Marsh
50fac3060c C++: split RA into constant and relative phases 2023-03-08 11:32:36 -05:00
Maiky
5a9a90d00b Move query to experimental 2023-03-08 11:50:04 +01:00
Maiky
d9d63bbdc6 Change ERB to Erb 2023-03-08 10:41:24 +01:00
Maiky
3e1808d92e Apply suggestions from code review
Co-authored-by: Alex Ford <alexrford@users.noreply.github.com>
2023-03-08 10:30:43 +01:00
Maiky
cd49175fae Update ruby/ql/src/queries/security/cwe-094/TemplateInjection.qhelp
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2023-03-08 10:27:57 +01:00
Maiky
cbb031ee14 Update ruby/ql/src/queries/security/cwe-094/TemplateInjection.qhelp
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2023-03-08 10:27:39 +01:00
erik-krogh
6cd4cd332d remove redundant imports 2023-03-01 16:25:01 +01:00
erik-krogh
31336b09c4 add summary for the Array method on Kernel 2023-03-01 12:53:13 +01:00
erik-krogh
36b33765a5 use allowImplicitRead instead of a taint-step from elements to the array 2023-02-28 16:09:52 +01:00
erik-krogh
b0797a2559 Merge branch 'main' into more-shell-taint 2023-02-27 18:27:09 +01:00
Maikypedia
44997d6b5f Change query id 2023-02-25 15:51:04 +01:00
Maikypedia
61fe3704c0 Remove unused imports 2023-02-25 15:43:48 +01:00
Maikypedia
dd1f7cc1d2 Remove missed file 2023-02-25 15:35:16 +01:00
Maikypedia
ff50513441 Add initial query for Ruby SSTI 2023-02-25 15:33:23 +01:00
erik-krogh
17f7ba2a8f rewrite the taint-step for join() to a flowsummary 2023-02-15 12:34:59 +01:00
erik-krogh
d2bd70dc33 Merge branch 'main' into more-shell-taint 2023-02-15 11:35:58 +01:00
erik-krogh
c2e8206090 add more array taint steps that taint the entire array 2023-01-30 21:14:27 +01:00
erik-krogh
962465f77a add array-taint-steps to unsafe-shell-command-construction 2023-01-30 16:56:03 +01:00
erik-krogh
a4c42aa14b more custom array steps from unsafe-code-construction to a utility predicate 2023-01-30 16:46:13 +01:00
990 changed files with 44418 additions and 11399 deletions

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: Set up Go 1.20 - name: Set up Go 1.20
uses: actions/setup-go@v3 uses: actions/setup-go@v4
with: with:
go-version: 1.20.0 go-version: 1.20.0
id: go id: go
@@ -48,7 +48,7 @@ jobs:
runs-on: windows-latest-xl runs-on: windows-latest-xl
steps: steps:
- name: Set up Go 1.20 - name: Set up Go 1.20
uses: actions/setup-go@v3 uses: actions/setup-go@v4
with: with:
go-version: 1.20.0 go-version: 1.20.0
id: go id: go

View File

@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
- name: Set up Go 1.20 - name: Set up Go 1.20
uses: actions/setup-go@v3 uses: actions/setup-go@v4
with: with:
go-version: 1.20.0 go-version: 1.20.0
id: go id: go

View File

@@ -279,6 +279,11 @@
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll", "cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockImports.qll" "cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockImports.qll"
], ],
"C++ IR IRConsistencyImports": [
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConsistencyImports.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRConsistencyImports.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRConsistencyImports.qll"
],
"C++ IR IRFunctionImports": [ "C++ IR IRFunctionImports": [
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRFunctionImports.qll", "cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRFunctionImports.qll",
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll", "cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll",

View File

@@ -1,3 +1,46 @@
## 0.6.0
### Breaking Changes
* The `semmle.code.cpp.commons.Buffer` and `semmle.code.cpp.commons.NullTermination` libraries no longer expose `semmle.code.cpp.dataflow.DataFlow`. Please import `semmle.code.cpp.dataflow.DataFlow` directly.
### Deprecated APIs
* The `WriteConfig` taint tracking configuration has been deprecated. Please use `WriteFlow`.
### New Features
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.
### Major Analysis Improvements
* A new C/C++ dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) has been added.
The new library behaves much more like the dataflow library of other CodeQL supported
languages by following use-use dataflow paths instead of def-use dataflow paths.
The new library also better supports dataflow through indirections, and new predicates
such as `Node::asIndirectExpr` have been added to facilitate working with indirections.
The `semmle.code.cpp.ir.dataflow.DataFlow` library is now identical to the new
`semmle.code.cpp.dataflow.new.DataFlow` library.
* The main data flow and taint tracking APIs have been changed. The old APIs
remain in place for now and translate to the new through a
backwards-compatible wrapper. If multiple configurations are in scope
simultaneously, then this may affect results slightly. The new API is quite
similar to the old, but makes use of a configuration module instead of a
configuration class.
### Minor Analysis Improvements
* Deleted the deprecated `hasGeneratedCopyConstructor` and `hasGeneratedCopyAssignmentOperator` predicates from the `Folder` class.
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getMustlockFunction`, `getTrylockFunction`, `getLockFunction`, and `getUnlockFunction` predicates from the `MutexType` class.
* Deleted the deprecated `getPosInBasicBlock` predicate from the `SubBasicBlock` class.
* Deleted the deprecated `getExpr` predicate from the `PointerDereferenceExpr` class.
* Deleted the deprecated `getUseInstruction` and `getDefinitionInstruction` predicates from the `Operand` class.
* Deleted the deprecated `isInParameter`, `isInParameterPointer`, and `isInQualifier` predicates from the `FunctionInput` class.
* Deleted the deprecated `isOutParameterPointer`, `isOutQualifier`, `isOutReturnValue`, and `isOutReturnPointer` predicate from the `FunctionOutput` class.
* Deleted the deprecated 3-argument `isGuardPhi` predicate from the `RangeSsaDefinition` class.
## 0.5.4 ## 0.5.4
No user-facing changes. No user-facing changes.

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* The internal `SsaConsistency` module has been moved from `SSAConstruction` to `SSAConsitency`, and the deprecated `SSAConsistency` module has been removed.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* The `semmle.code.cpp.commons.Buffer` and `semmle.code.cpp.commons.NullTermination` libraries no longer expose `semmle.code.cpp.dataflow.DataFlow`. Please import `semmle.code.cpp.dataflow.DataFlow` directly.

View File

@@ -1,9 +0,0 @@
---
category: majorAnalysis
---
* The main data flow and taint tracking APIs have been changed. The old APIs
remain in place for now and translate to the new through a
backwards-compatible wrapper. If multiple configurations are in scope
simultaneously, then this may affect results slightly. The new API is quite
similar to the old, but makes use of a configuration module instead of a
configuration class.

View File

@@ -1,12 +0,0 @@
---
category: minorAnalysis
---
* Deleted the deprecated `hasGeneratedCopyConstructor` and `hasGeneratedCopyAssignmentOperator` predicates from the `Folder` class.
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getMustlockFunction`, `getTrylockFunction`, `getLockFunction`, and `getUnlockFunction` predicates from the `MutexType` class.
* Deleted the deprecated `getPosInBasicBlock` predicate from the `SubBasicBlock` class.
* Deleted the deprecated `getExpr` predicate from the `PointerDereferenceExpr` class.
* Deleted the deprecated `getUseInstruction` and `getDefinitionInstruction` predicates from the `Operand` class.
* Deleted the deprecated `isInParameter`, `isInParameterPointer`, and `isInQualifier` predicates from the `FunctionInput` class.
* Deleted the deprecated `isOutParameterPointer`, `isOutQualifier`, `isOutReturnValue`, and `isOutReturnPointer` predicate from the `FunctionOutput` class.
* Deleted the deprecated 3-argument `isGuardPhi` predicate from the `RangeSsaDefinition` class.

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* The `WriteConfig` taint tracking configuration has been deprecated. Please use `WriteFlow`.

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.

View File

@@ -1,11 +0,0 @@
---
category: majorAnalysis
---
* A new C/C++ dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) has been added.
The new library behaves much more like the dataflow library of other CodeQL supported
languages by following use-use dataflow paths instead of def-use dataflow paths.
The new library also better supports dataflow through indirections, and new predicates
such as `Node::asIndirectExpr` have been added to facilitate working with indirections.
The `semmle.code.cpp.ir.dataflow.DataFlow` library is now identical to the new
`semmle.code.cpp.dataflow.new.DataFlow` library.

View File

@@ -0,0 +1,4 @@
---
category: deprecated
---
* The `SslContextCallAbstractConfig`, `SslContextCallConfig`, `SslContextCallBannedProtocolConfig`, `SslContextCallTls12ProtocolConfig`, `SslContextCallTls13ProtocolConfig`, `SslContextCallTlsProtocolConfig`, `SslContextFlowsToSetOptionConfig`, `SslOptionConfig` dataflow configurations from `BoostorgAsio` have been deprecated. Please use `SslContextCallConfigSig`, `SslContextCallMake`, `SslContextCallFlow`, `SslContextCallBannedProtocolFlow`, `SslContextCallTls12ProtocolFlow`, `SslContextCallTls13ProtocolFlow`, `SslContextCallTlsProtocolFlow`, `SslContextFlowsToSetOptionFlow`.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `BufferAccess` library (`semmle.code.cpp.security.BufferAccess`) no longer matches buffer accesses inside unevaluated contexts (such as inside `sizeof` or `decltype` expressions). As a result, queries using this library may see fewer false positives.

View File

@@ -0,0 +1,42 @@
## 0.6.0
### Breaking Changes
* The `semmle.code.cpp.commons.Buffer` and `semmle.code.cpp.commons.NullTermination` libraries no longer expose `semmle.code.cpp.dataflow.DataFlow`. Please import `semmle.code.cpp.dataflow.DataFlow` directly.
### Deprecated APIs
* The `WriteConfig` taint tracking configuration has been deprecated. Please use `WriteFlow`.
### New Features
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.
### Major Analysis Improvements
* A new C/C++ dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) has been added.
The new library behaves much more like the dataflow library of other CodeQL supported
languages by following use-use dataflow paths instead of def-use dataflow paths.
The new library also better supports dataflow through indirections, and new predicates
such as `Node::asIndirectExpr` have been added to facilitate working with indirections.
The `semmle.code.cpp.ir.dataflow.DataFlow` library is now identical to the new
`semmle.code.cpp.dataflow.new.DataFlow` library.
* The main data flow and taint tracking APIs have been changed. The old APIs
remain in place for now and translate to the new through a
backwards-compatible wrapper. If multiple configurations are in scope
simultaneously, then this may affect results slightly. The new API is quite
similar to the old, but makes use of a configuration module instead of a
configuration class.
### Minor Analysis Improvements
* Deleted the deprecated `hasGeneratedCopyConstructor` and `hasGeneratedCopyAssignmentOperator` predicates from the `Folder` class.
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getMustlockFunction`, `getTrylockFunction`, `getLockFunction`, and `getUnlockFunction` predicates from the `MutexType` class.
* Deleted the deprecated `getPosInBasicBlock` predicate from the `SubBasicBlock` class.
* Deleted the deprecated `getExpr` predicate from the `PointerDereferenceExpr` class.
* Deleted the deprecated `getUseInstruction` and `getDefinitionInstruction` predicates from the `Operand` class.
* Deleted the deprecated `isInParameter`, `isInParameterPointer`, and `isInQualifier` predicates from the `FunctionInput` class.
* Deleted the deprecated `isOutParameterPointer`, `isOutQualifier`, `isOutReturnValue`, and `isOutReturnPointer` predicate from the `FunctionOutput` class.
* Deleted the deprecated 3-argument `isGuardPhi` predicate from the `RangeSsaDefinition` class.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.5.4 lastReleaseVersion: 0.6.0

View File

@@ -5,6 +5,7 @@
private import SemanticExpr private import SemanticExpr
private import SemanticExprSpecific::SemanticExprConfig as Specific private import SemanticExprSpecific::SemanticExprConfig as Specific
private import SemanticSSA private import SemanticSSA
private import SemanticLocation
/** /**
* A valid base for an expression bound. * A valid base for an expression bound.
@@ -14,6 +15,8 @@ private import SemanticSSA
class SemBound instanceof Specific::Bound { class SemBound instanceof Specific::Bound {
final string toString() { result = super.toString() } final string toString() { result = super.toString() }
final SemLocation getLocation() { result = super.getLocation() }
final SemExpr getExpr(int delta) { result = Specific::getBoundExpr(this, delta) } final SemExpr getExpr(int delta) { result = Specific::getBoundExpr(this, delta) }
} }

View File

@@ -0,0 +1,23 @@
private import semmle.code.cpp.Location
class SemLocation instanceof Location {
/**
* Gets a textual representation of this element.
*
* The format is "file://filePath:startLine:startColumn:endLine:endColumn".
*/
string toString() { result = super.toString() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}

View File

@@ -0,0 +1,29 @@
private import RangeAnalysisStage
module IntDelta implements DeltaSig {
class Delta = int;
bindingset[d]
bindingset[result]
float toFloat(Delta d) { result = d }
bindingset[d]
bindingset[result]
int toInt(Delta d) { result = d }
bindingset[n]
bindingset[result]
Delta fromInt(int n) { result = n }
bindingset[f]
Delta fromFloat(float f) {
result =
min(float diff, float res |
diff = (res - f) and res = f.ceil()
or
diff = (f - res) and res = f.floor()
|
res order by diff
)
}
}

View File

@@ -1,24 +1,2 @@
private import RangeAnalysisStage import RangeAnalysisImpl
private import RangeAnalysisSpecific import experimental.semmle.code.cpp.semantic.SemanticBound
private import experimental.semmle.code.cpp.semantic.analysis.FloatDelta
private import RangeUtils
private import experimental.semmle.code.cpp.semantic.SemanticBound as SemanticBound
module Bounds implements BoundSig<FloatDelta> {
class SemBound instanceof SemanticBound::SemBound {
string toString() { result = super.toString() }
SemExpr getExpr(float delta) { result = super.getExpr(delta) }
}
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
private module CppRangeAnalysis =
RangeStage<FloatDelta, Bounds, CppLangImpl, RangeUtil<FloatDelta, CppLangImpl>>;
import CppRangeAnalysis

View File

@@ -0,0 +1,107 @@
private import RangeAnalysisStage
private import RangeAnalysisSpecific
private import experimental.semmle.code.cpp.semantic.analysis.FloatDelta
private import RangeUtils
private import experimental.semmle.code.cpp.semantic.SemanticBound as SemanticBound
private import experimental.semmle.code.cpp.semantic.SemanticLocation
private import experimental.semmle.code.cpp.semantic.SemanticSSA
module ConstantBounds implements BoundSig<FloatDelta> {
class SemBound instanceof SemanticBound::SemBound {
SemBound() {
this instanceof SemanticBound::SemZeroBound
or
this.(SemanticBound::SemSsaBound).getAVariable() instanceof SemSsaPhiNode
}
string toString() { result = super.toString() }
SemLocation getLocation() { result = super.getLocation() }
SemExpr getExpr(float delta) { result = super.getExpr(delta) }
}
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
private module RelativeBounds implements BoundSig<FloatDelta> {
class SemBound instanceof SemanticBound::SemBound {
SemBound() { not this instanceof SemanticBound::SemZeroBound }
string toString() { result = super.toString() }
SemLocation getLocation() { result = super.getLocation() }
SemExpr getExpr(float delta) { result = super.getExpr(delta) }
}
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
private module ConstantStage =
RangeStage<FloatDelta, ConstantBounds, CppLangImpl, RangeUtil<FloatDelta, CppLangImpl>>;
private module RelativeStage =
RangeStage<FloatDelta, RelativeBounds, CppLangImpl, RangeUtil<FloatDelta, CppLangImpl>>;
private newtype TSemReason =
TSemNoReason() or
TSemCondReason(SemGuard guard) {
guard = any(ConstantStage::SemCondReason reason).getCond()
or
guard = any(RelativeStage::SemCondReason reason).getCond()
}
/**
* A reason for an inferred bound. This can either be `CondReason` if the bound
* is due to a specific condition, or `NoReason` if the bound is inferred
* without going through a bounding condition.
*/
abstract class SemReason extends TSemReason {
/** Gets a textual representation of this reason. */
abstract string toString();
}
/**
* A reason for an inferred bound that indicates that the bound is inferred
* without going through a bounding condition.
*/
class SemNoReason extends SemReason, TSemNoReason {
override string toString() { result = "NoReason" }
}
/** A reason for an inferred bound pointing to a condition. */
class SemCondReason extends SemReason, TSemCondReason {
/** Gets the condition that is the reason for the bound. */
SemGuard getCond() { this = TSemCondReason(result) }
override string toString() { result = getCond().toString() }
}
private ConstantStage::SemReason constantReason(SemReason reason) {
result instanceof ConstantStage::SemNoReason and reason instanceof SemNoReason
or
result.(ConstantStage::SemCondReason).getCond() = reason.(SemCondReason).getCond()
}
private RelativeStage::SemReason relativeReason(SemReason reason) {
result instanceof RelativeStage::SemNoReason and reason instanceof SemNoReason
or
result.(RelativeStage::SemCondReason).getCond() = reason.(SemCondReason).getCond()
}
predicate semBounded(
SemExpr e, SemanticBound::SemBound b, float delta, boolean upper, SemReason reason
) {
ConstantStage::semBounded(e, b, delta, upper, constantReason(reason))
or
RelativeStage::semBounded(e, b, delta, upper, relativeReason(reason))
}

View File

@@ -73,6 +73,7 @@ import experimental.semmle.code.cpp.semantic.SemanticCFG
import experimental.semmle.code.cpp.semantic.SemanticType import experimental.semmle.code.cpp.semantic.SemanticType
import experimental.semmle.code.cpp.semantic.SemanticOpcode import experimental.semmle.code.cpp.semantic.SemanticOpcode
private import ConstantAnalysis private import ConstantAnalysis
import experimental.semmle.code.cpp.semantic.SemanticLocation
/** /**
* Holds if `typ` is a small integral type with the given lower and upper bounds. * Holds if `typ` is a small integral type with the given lower and upper bounds.
@@ -228,6 +229,10 @@ signature module UtilSig<DeltaSig DeltaParam> {
signature module BoundSig<DeltaSig D> { signature module BoundSig<DeltaSig D> {
class SemBound { class SemBound {
string toString();
SemLocation getLocation();
SemExpr getExpr(D::Delta delta); SemExpr getExpr(D::Delta delta);
} }

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all name: codeql/cpp-all
version: 0.5.5-dev version: 0.6.1-dev
groups: cpp groups: cpp
dbscheme: semmlecode.cpp.dbscheme dbscheme: semmlecode.cpp.dbscheme
extractor: cpp extractor: cpp

View File

@@ -418,6 +418,10 @@ module Impl<FullStateConfigSig Config> {
) )
} }
private predicate sourceCallCtx(CallContext cc) {
if hasSourceCallCtx() then cc instanceof CallContextSomeCall else cc instanceof CallContextAny
}
private predicate hasSinkCallCtx() { private predicate hasSinkCallCtx() {
exists(FlowFeature feature | feature = Config::getAFeature() | exists(FlowFeature feature | feature = Config::getAFeature() |
feature instanceof FeatureHasSinkCallContext or feature instanceof FeatureHasSinkCallContext or
@@ -1141,19 +1145,13 @@ module Impl<FullStateConfigSig Config> {
import Param import Param
/* Begin: Stage logic. */ /* Begin: Stage logic. */
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
private predicate revFlowApAlias(NodeEx node, ApApprox apa) {
PrevStage::revFlowAp(node, apa)
}
pragma[nomagic] pragma[nomagic]
private predicate flowIntoCallApa( private predicate flowIntoCallApa(
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa
) { ) {
flowIntoCall(call, arg, p, allowsFieldFlow) and flowIntoCall(call, arg, p, allowsFieldFlow) and
PrevStage::revFlowAp(p, pragma[only_bind_into](apa)) and PrevStage::revFlowAp(p, pragma[only_bind_into](apa)) and
revFlowApAlias(arg, pragma[only_bind_into](apa)) PrevStage::revFlowAp(arg, pragma[only_bind_into](apa))
} }
pragma[nomagic] pragma[nomagic]
@@ -1163,7 +1161,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
flowOutOfCall(call, ret, kind, out, allowsFieldFlow) and flowOutOfCall(call, ret, kind, out, allowsFieldFlow) and
PrevStage::revFlowAp(out, pragma[only_bind_into](apa)) and PrevStage::revFlowAp(out, pragma[only_bind_into](apa)) and
revFlowApAlias(ret, pragma[only_bind_into](apa)) PrevStage::revFlowAp(ret, pragma[only_bind_into](apa))
} }
pragma[nomagic] pragma[nomagic]
@@ -1691,16 +1689,6 @@ module Impl<FullStateConfigSig Config> {
pragma[nomagic] pragma[nomagic]
predicate revFlowAp(NodeEx node, Ap ap) { revFlow(node, _, _, _, ap) } predicate revFlowAp(NodeEx node, Ap ap) { revFlow(node, _, _, _, ap) }
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
additional predicate revFlowAlias(NodeEx node) { revFlow(node, _, _, _, _) }
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap) {
revFlow(node, state, ap)
}
private predicate fwdConsCand(TypedContent tc, Ap ap) { storeStepFwd(_, ap, tc, _, _) } private predicate fwdConsCand(TypedContent tc, Ap ap) { storeStepFwd(_, ap, tc, _, _) }
private predicate revConsCand(TypedContent tc, Ap ap) { storeStepCand(_, ap, tc, _, _) } private predicate revConsCand(TypedContent tc, Ap ap) { storeStepCand(_, ap, tc, _, _) }
@@ -1974,7 +1962,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow) and flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow) and
Stage2::revFlow(node2) and Stage2::revFlow(node2) and
Stage2::revFlowAlias(node1) Stage2::revFlow(node1)
} }
pragma[nomagic] pragma[nomagic]
@@ -1983,7 +1971,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow) and flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow) and
Stage2::revFlow(node2) and Stage2::revFlow(node2) and
Stage2::revFlowAlias(node1) Stage2::revFlow(node1)
} }
private module LocalFlowBigStep { private module LocalFlowBigStep {
@@ -2065,11 +2053,11 @@ module Impl<FullStateConfigSig Config> {
additionalLocalFlowStepNodeCand1(node1, node2) and additionalLocalFlowStepNodeCand1(node1, node2) and
state1 = state2 and state1 = state2 and
Stage2::revFlow(node1, pragma[only_bind_into](state1), false) and Stage2::revFlow(node1, pragma[only_bind_into](state1), false) and
Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), false) Stage2::revFlow(node2, pragma[only_bind_into](state2), false)
or or
additionalLocalStateStep(node1, state1, node2, state2) and additionalLocalStateStep(node1, state1, node2, state2) and
Stage2::revFlow(node1, state1, false) and Stage2::revFlow(node1, state1, false) and
Stage2::revFlowAlias(node2, state2, false) Stage2::revFlow(node2, state2, false)
} }
/** /**
@@ -2262,7 +2250,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), _) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) and
exists(lcc) exists(lcc)
} }
@@ -2273,7 +2261,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2284,7 +2272,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2586,7 +2574,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), lcc) and localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), lcc) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _) PrevStage::revFlow(node2, pragma[only_bind_into](state2), _)
} }
pragma[nomagic] pragma[nomagic]
@@ -2596,7 +2584,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2607,7 +2595,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2804,11 +2792,7 @@ module Impl<FullStateConfigSig Config> {
// A PathNode is introduced by a source ... // A PathNode is introduced by a source ...
Stage5::revFlow(node, state) and Stage5::revFlow(node, state) and
sourceNode(node, state) and sourceNode(node, state) and
( sourceCallCtx(cc) and
if hasSourceCallCtx()
then cc instanceof CallContextSomeCall
else cc instanceof CallContextAny
) and
sc instanceof SummaryCtxNone and sc instanceof SummaryCtxNone and
ap = TAccessPathNil(node.getDataFlowType()) ap = TAccessPathNil(node.getDataFlowType())
or or
@@ -3214,11 +3198,7 @@ module Impl<FullStateConfigSig Config> {
override predicate isSource() { override predicate isSource() {
sourceNode(node, state) and sourceNode(node, state) and
( sourceCallCtx(cc) and
if hasSourceCallCtx()
then cc instanceof CallContextSomeCall
else cc instanceof CallContextAny
) and
sc instanceof SummaryCtxNone and sc instanceof SummaryCtxNone and
ap = TAccessPathNil(node.getDataFlowType()) ap = TAccessPathNil(node.getDataFlowType())
} }

View File

@@ -418,6 +418,10 @@ module Impl<FullStateConfigSig Config> {
) )
} }
private predicate sourceCallCtx(CallContext cc) {
if hasSourceCallCtx() then cc instanceof CallContextSomeCall else cc instanceof CallContextAny
}
private predicate hasSinkCallCtx() { private predicate hasSinkCallCtx() {
exists(FlowFeature feature | feature = Config::getAFeature() | exists(FlowFeature feature | feature = Config::getAFeature() |
feature instanceof FeatureHasSinkCallContext or feature instanceof FeatureHasSinkCallContext or
@@ -1141,19 +1145,13 @@ module Impl<FullStateConfigSig Config> {
import Param import Param
/* Begin: Stage logic. */ /* Begin: Stage logic. */
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
private predicate revFlowApAlias(NodeEx node, ApApprox apa) {
PrevStage::revFlowAp(node, apa)
}
pragma[nomagic] pragma[nomagic]
private predicate flowIntoCallApa( private predicate flowIntoCallApa(
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa
) { ) {
flowIntoCall(call, arg, p, allowsFieldFlow) and flowIntoCall(call, arg, p, allowsFieldFlow) and
PrevStage::revFlowAp(p, pragma[only_bind_into](apa)) and PrevStage::revFlowAp(p, pragma[only_bind_into](apa)) and
revFlowApAlias(arg, pragma[only_bind_into](apa)) PrevStage::revFlowAp(arg, pragma[only_bind_into](apa))
} }
pragma[nomagic] pragma[nomagic]
@@ -1163,7 +1161,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
flowOutOfCall(call, ret, kind, out, allowsFieldFlow) and flowOutOfCall(call, ret, kind, out, allowsFieldFlow) and
PrevStage::revFlowAp(out, pragma[only_bind_into](apa)) and PrevStage::revFlowAp(out, pragma[only_bind_into](apa)) and
revFlowApAlias(ret, pragma[only_bind_into](apa)) PrevStage::revFlowAp(ret, pragma[only_bind_into](apa))
} }
pragma[nomagic] pragma[nomagic]
@@ -1691,16 +1689,6 @@ module Impl<FullStateConfigSig Config> {
pragma[nomagic] pragma[nomagic]
predicate revFlowAp(NodeEx node, Ap ap) { revFlow(node, _, _, _, ap) } predicate revFlowAp(NodeEx node, Ap ap) { revFlow(node, _, _, _, ap) }
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
additional predicate revFlowAlias(NodeEx node) { revFlow(node, _, _, _, _) }
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap) {
revFlow(node, state, ap)
}
private predicate fwdConsCand(TypedContent tc, Ap ap) { storeStepFwd(_, ap, tc, _, _) } private predicate fwdConsCand(TypedContent tc, Ap ap) { storeStepFwd(_, ap, tc, _, _) }
private predicate revConsCand(TypedContent tc, Ap ap) { storeStepCand(_, ap, tc, _, _) } private predicate revConsCand(TypedContent tc, Ap ap) { storeStepCand(_, ap, tc, _, _) }
@@ -1974,7 +1962,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow) and flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow) and
Stage2::revFlow(node2) and Stage2::revFlow(node2) and
Stage2::revFlowAlias(node1) Stage2::revFlow(node1)
} }
pragma[nomagic] pragma[nomagic]
@@ -1983,7 +1971,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow) and flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow) and
Stage2::revFlow(node2) and Stage2::revFlow(node2) and
Stage2::revFlowAlias(node1) Stage2::revFlow(node1)
} }
private module LocalFlowBigStep { private module LocalFlowBigStep {
@@ -2065,11 +2053,11 @@ module Impl<FullStateConfigSig Config> {
additionalLocalFlowStepNodeCand1(node1, node2) and additionalLocalFlowStepNodeCand1(node1, node2) and
state1 = state2 and state1 = state2 and
Stage2::revFlow(node1, pragma[only_bind_into](state1), false) and Stage2::revFlow(node1, pragma[only_bind_into](state1), false) and
Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), false) Stage2::revFlow(node2, pragma[only_bind_into](state2), false)
or or
additionalLocalStateStep(node1, state1, node2, state2) and additionalLocalStateStep(node1, state1, node2, state2) and
Stage2::revFlow(node1, state1, false) and Stage2::revFlow(node1, state1, false) and
Stage2::revFlowAlias(node2, state2, false) Stage2::revFlow(node2, state2, false)
} }
/** /**
@@ -2262,7 +2250,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), _) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) and
exists(lcc) exists(lcc)
} }
@@ -2273,7 +2261,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2284,7 +2272,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2586,7 +2574,7 @@ module Impl<FullStateConfigSig Config> {
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), lcc) and localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), lcc) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _) PrevStage::revFlow(node2, pragma[only_bind_into](state2), _)
} }
pragma[nomagic] pragma[nomagic]
@@ -2596,7 +2584,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2607,7 +2595,7 @@ module Impl<FullStateConfigSig Config> {
exists(FlowState state | exists(FlowState state |
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _) PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
) )
} }
@@ -2804,11 +2792,7 @@ module Impl<FullStateConfigSig Config> {
// A PathNode is introduced by a source ... // A PathNode is introduced by a source ...
Stage5::revFlow(node, state) and Stage5::revFlow(node, state) and
sourceNode(node, state) and sourceNode(node, state) and
( sourceCallCtx(cc) and
if hasSourceCallCtx()
then cc instanceof CallContextSomeCall
else cc instanceof CallContextAny
) and
sc instanceof SummaryCtxNone and sc instanceof SummaryCtxNone and
ap = TAccessPathNil(node.getDataFlowType()) ap = TAccessPathNil(node.getDataFlowType())
or or
@@ -3214,11 +3198,7 @@ module Impl<FullStateConfigSig Config> {
override predicate isSource() { override predicate isSource() {
sourceNode(node, state) and sourceNode(node, state) and
( sourceCallCtx(cc) and
if hasSourceCallCtx()
then cc instanceof CallContextSomeCall
else cc instanceof CallContextAny
) and
sc instanceof SummaryCtxNone and sc instanceof SummaryCtxNone and
ap = TAccessPathNil(node.getDataFlowType()) ap = TAccessPathNil(node.getDataFlowType())
} }

View File

@@ -9,7 +9,6 @@ import cpp
import semmle.code.cpp.security.Security import semmle.code.cpp.security.Security
private import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.DataFlow3
private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.ResolveCall private import semmle.code.cpp.ir.dataflow.ResolveCall
private import semmle.code.cpp.controlflow.IRGuards private import semmle.code.cpp.controlflow.IRGuards
@@ -90,65 +89,64 @@ private predicate conflatePointerAndPointee(DataFlow::Node nodeFrom, DataFlow::N
) )
} }
private class DefaultTaintTrackingCfg extends TaintTracking::Configuration { private module DefaultTaintTrackingConfig implements DataFlow::ConfigSig {
DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" } predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) }
override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) }
override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
conflatePointerAndPointee(nodeFrom, nodeTo) conflatePointerAndPointee(nodeFrom, nodeTo)
} }
} }
private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration { private module DefaultTaintTrackingFlow = TaintTracking::Make<DefaultTaintTrackingConfig>;
ToGlobalVarTaintTrackingCfg() { this = "GlobalVarTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } private module ToGlobalVarTaintTrackingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) }
override predicate isSink(DataFlow::Node sink) { predicate isSink(DataFlow::Node sink) { sink.asVariable() instanceof GlobalOrNamespaceVariable }
sink.asVariable() instanceof GlobalOrNamespaceVariable
}
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable)) writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))
or or
readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable)) readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable))
} }
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
} }
private class FromGlobalVarTaintTrackingCfg extends TaintTracking2::Configuration { private module ToGlobalVarTaintTrackingFlow = TaintTracking::Make<ToGlobalVarTaintTrackingConfig>;
FromGlobalVarTaintTrackingCfg() { this = "FromGlobalVarTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) { private module FromGlobalVarTaintTrackingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// This set of sources should be reasonably small, which is good for // This set of sources should be reasonably small, which is good for
// performance since the set of sinks is very large. // performance since the set of sinks is very large.
exists(ToGlobalVarTaintTrackingCfg otherCfg | otherCfg.hasFlowTo(source)) ToGlobalVarTaintTrackingFlow::hasFlowTo(source)
} }
override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) }
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
// Additional step for flow out of variables. There is no flow _into_ // Additional step for flow out of variables. There is no flow _into_
// variables in this configuration, so this step only serves to take flow // variables in this configuration, so this step only serves to take flow
// out of a variable that's a source. // out of a variable that's a source.
readsVariable(n2.asInstruction(), n1.asVariable()) readsVariable(n2.asInstruction(), n1.asVariable())
} }
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
} }
private module FromGlobalVarTaintTrackingFlow =
TaintTracking::Make<FromGlobalVarTaintTrackingConfig>;
private predicate readsVariable(LoadInstruction load, Variable var) { private predicate readsVariable(LoadInstruction load, Variable var) {
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
} }
@@ -332,8 +330,8 @@ private import Cached
*/ */
cached cached
predicate tainted(Expr source, Element tainted) { predicate tainted(Expr source, Element tainted) {
exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink | exists(DataFlow::Node sink |
cfg.hasFlow(getNodeForSource(source), sink) and DefaultTaintTrackingFlow::hasFlow(getNodeForSource(source), sink) and
tainted = adjustedSink(sink) tainted = adjustedSink(sink)
) )
} }
@@ -359,12 +357,11 @@ predicate taintedIncludingGlobalVars(Expr source, Element tainted, string global
globalVar = "" globalVar = ""
or or
exists( exists(
ToGlobalVarTaintTrackingCfg toCfg, FromGlobalVarTaintTrackingCfg fromCfg,
DataFlow::VariableNode variableNode, GlobalOrNamespaceVariable global, DataFlow::Node sink DataFlow::VariableNode variableNode, GlobalOrNamespaceVariable global, DataFlow::Node sink
| |
global = variableNode.getVariable() and global = variableNode.getVariable() and
toCfg.hasFlow(getNodeForSource(source), variableNode) and ToGlobalVarTaintTrackingFlow::hasFlow(getNodeForSource(source), variableNode) and
fromCfg.hasFlow(variableNode, sink) and FromGlobalVarTaintTrackingFlow::hasFlow(variableNode, sink) and
tainted = adjustedSink(sink) and tainted = adjustedSink(sink) and
global = globalVarFromId(globalVar) global = globalVarFromId(globalVar)
) )
@@ -422,20 +419,18 @@ module TaintedWithPath {
string toString() { result = "TaintTrackingConfiguration" } string toString() { result = "TaintTrackingConfiguration" }
} }
private class AdjustedConfiguration extends TaintTracking3::Configuration { private module AdjustedConfig implements DataFlow::ConfigSig {
AdjustedConfiguration() { this = "AdjustedConfiguration" } predicate isSource(DataFlow::Node source) {
override predicate isSource(DataFlow::Node source) {
exists(TaintTrackingConfiguration cfg, Expr e | exists(TaintTrackingConfiguration cfg, Expr e |
cfg.isSource(e) and source = getNodeForExpr(e) cfg.isSource(e) and source = getNodeForExpr(e)
) )
} }
override predicate isSink(DataFlow::Node sink) { predicate isSink(DataFlow::Node sink) {
exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink))) exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink)))
} }
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
conflatePointerAndPointee(n1, n2) conflatePointerAndPointee(n1, n2)
or or
// Steps into and out of global variables // Steps into and out of global variables
@@ -448,13 +443,15 @@ module TaintedWithPath {
additionalTaintStep(n1, n2) additionalTaintStep(n1, n2)
} }
override predicate isSanitizer(DataFlow::Node node) { predicate isBarrier(DataFlow::Node node) {
exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e)) exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e))
} }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
} }
private module AdjustedFlow = TaintTracking::Make<AdjustedConfig>;
/* /*
* A sink `Element` may map to multiple `DataFlowX::PathNode`s via (the * A sink `Element` may map to multiple `DataFlowX::PathNode`s via (the
* inverse of) `adjustedSink`. For example, an `Expr` maps to all its * inverse of) `adjustedSink`. For example, an `Expr` maps to all its
@@ -470,12 +467,12 @@ module TaintedWithPath {
*/ */
private newtype TPathNode = private newtype TPathNode =
TWrapPathNode(DataFlow3::PathNode n) or TWrapPathNode(AdjustedFlow::PathNode n) or
// There's a single newtype constructor for both sources and sinks since // There's a single newtype constructor for both sources and sinks since
// that makes it easiest to deal with the case where source = sink. // that makes it easiest to deal with the case where source = sink.
TEndpointPathNode(Element e) { TEndpointPathNode(Element e) {
exists(AdjustedConfiguration cfg, DataFlow3::Node sourceNode, DataFlow3::Node sinkNode | exists(DataFlow::Node sourceNode, DataFlow::Node sinkNode |
cfg.hasFlow(sourceNode, sinkNode) AdjustedFlow::hasFlow(sourceNode, sinkNode)
| |
sourceNode = getNodeForExpr(e) and sourceNode = getNodeForExpr(e) and
exists(TaintTrackingConfiguration ttCfg | ttCfg.isSource(e)) exists(TaintTrackingConfiguration ttCfg | ttCfg.isSource(e))
@@ -524,7 +521,7 @@ module TaintedWithPath {
} }
private class WrapPathNode extends PathNode, TWrapPathNode { private class WrapPathNode extends PathNode, TWrapPathNode {
DataFlow3::PathNode inner() { this = TWrapPathNode(result) } AdjustedFlow::PathNode inner() { this = TWrapPathNode(result) }
override string toString() { result = this.inner().toString() } override string toString() { result = this.inner().toString() }
@@ -561,25 +558,25 @@ module TaintedWithPath {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { query predicate edges(PathNode a, PathNode b) {
DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), b.(WrapPathNode).inner()) AdjustedFlow::PathGraph::edges(a.(WrapPathNode).inner(), b.(WrapPathNode).inner())
or or
// To avoid showing trivial-looking steps, we _replace_ the last node instead // To avoid showing trivial-looking steps, we _replace_ the last node instead
// of adding an edge out of it. // of adding an edge out of it.
exists(WrapPathNode sinkNode | exists(WrapPathNode sinkNode |
DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), sinkNode.inner()) and AdjustedFlow::PathGraph::edges(a.(WrapPathNode).inner(), sinkNode.inner()) and
b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
) )
or or
// Same for the first node // Same for the first node
exists(WrapPathNode sourceNode | exists(WrapPathNode sourceNode |
DataFlow3::PathGraph::edges(sourceNode.inner(), b.(WrapPathNode).inner()) and AdjustedFlow::PathGraph::edges(sourceNode.inner(), b.(WrapPathNode).inner()) and
sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner())
) )
or or
// Finally, handle the case where the path goes directly from a source to a // Finally, handle the case where the path goes directly from a source to a
// sink, meaning that they both need to be translated. // sink, meaning that they both need to be translated.
exists(WrapPathNode sinkNode, WrapPathNode sourceNode | exists(WrapPathNode sinkNode, WrapPathNode sourceNode |
DataFlow3::PathGraph::edges(sourceNode.inner(), sinkNode.inner()) and AdjustedFlow::PathGraph::edges(sourceNode.inner(), sinkNode.inner()) and
sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) and sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) and
b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
) )
@@ -590,20 +587,20 @@ module TaintedWithPath {
* from `par` to `ret` within it, in the graph of data flow path explanations. * from `par` to `ret` within it, in the graph of data flow path explanations.
*/ */
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), AdjustedFlow::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) ret.(WrapPathNode).inner(), out.(WrapPathNode).inner())
or or
// To avoid showing trivial-looking steps, we _replace_ the last node instead // To avoid showing trivial-looking steps, we _replace_ the last node instead
// of adding an edge out of it. // of adding an edge out of it.
exists(WrapPathNode sinkNode | exists(WrapPathNode sinkNode |
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), AdjustedFlow::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), sinkNode.inner()) and ret.(WrapPathNode).inner(), sinkNode.inner()) and
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
) )
or or
// Same for the first node // Same for the first node
exists(WrapPathNode sourceNode | exists(WrapPathNode sourceNode |
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), AdjustedFlow::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner())
) )
@@ -611,7 +608,7 @@ module TaintedWithPath {
// Finally, handle the case where the path goes directly from a source to a // Finally, handle the case where the path goes directly from a source to a
// sink, meaning that they both need to be translated. // sink, meaning that they both need to be translated.
exists(WrapPathNode sinkNode, WrapPathNode sourceNode | exists(WrapPathNode sinkNode, WrapPathNode sourceNode |
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), AdjustedFlow::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), sinkNode.inner()) and ret.(WrapPathNode).inner(), sinkNode.inner()) and
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
@@ -634,10 +631,10 @@ module TaintedWithPath {
* the computation. * the computation.
*/ */
predicate taintedWithPath(Expr source, Element tainted, PathNode sourceNode, PathNode sinkNode) { predicate taintedWithPath(Expr source, Element tainted, PathNode sourceNode, PathNode sinkNode) {
exists(AdjustedConfiguration cfg, DataFlow3::Node flowSource, DataFlow3::Node flowSink | exists(DataFlow::Node flowSource, DataFlow::Node flowSink |
source = sourceNode.(InitialPathNode).inner() and source = sourceNode.(InitialPathNode).inner() and
flowSource = getNodeForExpr(source) and flowSource = getNodeForExpr(source) and
cfg.hasFlow(flowSource, flowSink) and AdjustedFlow::hasFlow(flowSource, flowSink) and
tainted = adjustedSink(flowSink) and tainted = adjustedSink(flowSink) and
tainted = sinkNode.(FinalPathNode).inner() tainted = sinkNode.(FinalPathNode).inner()
) )
@@ -660,8 +657,8 @@ module TaintedWithPath {
* through a global variable. * through a global variable.
*/ */
predicate taintedWithoutGlobals(Element tainted) { predicate taintedWithoutGlobals(Element tainted) {
exists(AdjustedConfiguration cfg, PathNode sourceNode, FinalPathNode sinkNode | exists(PathNode sourceNode, FinalPathNode sinkNode |
cfg.isSource(sourceNode.(WrapPathNode).inner().getNode()) and AdjustedConfig::isSource(sourceNode.(WrapPathNode).inner().getNode()) and
edgesWithoutGlobals+(sourceNode, sinkNode) and edgesWithoutGlobals+(sourceNode, sinkNode) and
tainted = sinkNode.inner() tainted = sinkNode.inner()
) )

View File

@@ -1,6 +1,7 @@
private import IR private import IR
import InstructionConsistency // module is below import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll import IRTypeConsistency // module is in IRType.qll
import internal.IRConsistencyImports
module InstructionConsistency { module InstructionConsistency {
private import internal.InstructionImports as Imports private import internal.InstructionImports as Imports
@@ -28,7 +29,7 @@ module InstructionConsistency {
PresentIRFunction() { this = TPresentIRFunction(irFunc) } PresentIRFunction() { this = TPresentIRFunction(irFunc) }
override string toString() { override string toString() {
result = concat(Language::getIdentityString(irFunc.getFunction()), "; ") result = concat(LanguageDebug::getIdentityString(irFunc.getFunction()), "; ")
} }
override Language::Location getLocation() { override Language::Location getLocation() {

View File

@@ -149,7 +149,9 @@ private class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction
override Language::Location getLocation() { result = irFunc.getLocation() } override Language::Location getLocation() { result = irFunc.getLocation() }
override string getLabel() { result = Language::getIdentityString(irFunc.getFunction()) } override string getLabel() {
result = Imports::LanguageDebug::getIdentityString(irFunc.getFunction())
}
override int getOrder() { override int getOrder() {
this = this =

View File

@@ -1,7 +1,7 @@
import AliasAnalysis import AliasAnalysis
import semmle.code.cpp.Location
import semmle.code.cpp.ir.internal.Overlap import semmle.code.cpp.ir.internal.Overlap
private import semmle.code.cpp.ir.internal.IRCppLanguage as Language private import semmle.code.cpp.ir.internal.IRCppLanguage as Language
private import semmle.code.cpp.Print
private import semmle.code.cpp.ir.implementation.unaliased_ssa.IR private import semmle.code.cpp.ir.implementation.unaliased_ssa.IR
private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as OldSsa private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as OldSsa
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints private import semmle.code.cpp.ir.internal.IntegerConstant as Ints

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -1 +1,2 @@
import semmle.code.cpp.ir.IRConfiguration as IRConfiguration import semmle.code.cpp.ir.IRConfiguration as IRConfiguration
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -1,2 +1,55 @@
private import SSAConstruction as Ssa import SsaConsistency
import Ssa::SsaConsistency import SSAConsistencyImports
module SsaConsistency {
/**
* Holds if a `MemoryOperand` has more than one `MemoryLocation` assigned by alias analysis.
*/
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {
exists(int locationCount |
locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
locationCount > 1 and
func = operand.getEnclosingIRFunction() and
funcText = LanguageDebug::getIdentityString(func.getFunction()) and
message =
operand.getUse().toString() + " " + "Operand has " + locationCount.toString() +
" memory accesses in function '$@': " +
strictconcat(Alias::getOperandMemoryLocation(operand).toString(), ", ")
)
}
/**
* Holds if a `MemoryLocation` does not have an associated `VirtualVariable`.
*/
query predicate missingVirtualVariableForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
not exists(location.getVirtualVariable()) and
func = location.getIRFunction() and
funcText = LanguageDebug::getIdentityString(func.getFunction()) and
message = "Memory location has no virtual variable in function '$@'."
}
/**
* Holds if a `MemoryLocation` is a member of more than one `VirtualVariable`.
*/
query predicate multipleVirtualVariablesForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
exists(int vvarCount |
vvarCount = strictcount(location.getVirtualVariable()) and
vvarCount > 1 and
func = location.getIRFunction() and
funcText = LanguageDebug::getIdentityString(func.getFunction()) and
message =
"Memory location has " + vvarCount.toString() + " virtual variables in function '$@': (" +
concat(Alias::VirtualVariable vvar |
vvar = location.getVirtualVariable()
|
vvar.toString(), ", "
) + ")."
)
}
}

View File

@@ -0,0 +1,3 @@
import semmle.code.cpp.ir.implementation.raw.IR as OldIR
import AliasedSSA as Alias
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -996,7 +996,7 @@ deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1;
/** /**
* Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the * Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the
* `DebugSSA` module, which is then imported by PrintSSA. * `DebugSsa` module, which is then imported by PrintSSA.
*/ */
module DebugSsa { module DebugSsa {
import PhiInsertion import PhiInsertion
@@ -1063,62 +1063,6 @@ private module CachedForDebugging {
int maxValue() { result = 2147483647 } int maxValue() { result = 2147483647 }
} }
module SsaConsistency {
/**
* Holds if a `MemoryOperand` has more than one `MemoryLocation` assigned by alias analysis.
*/
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {
exists(int locationCount |
locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
locationCount > 1 and
func = operand.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message =
operand.getUse().toString() + " " + "Operand has " + locationCount.toString() +
" memory accesses in function '$@': " +
strictconcat(Alias::getOperandMemoryLocation(operand).toString(), ", ")
)
}
/**
* Holds if a `MemoryLocation` does not have an associated `VirtualVariable`.
*/
query predicate missingVirtualVariableForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
not exists(location.getVirtualVariable()) and
func = location.getIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message = "Memory location has no virtual variable in function '$@'."
}
/**
* Holds if a `MemoryLocation` is a member of more than one `VirtualVariable`.
*/
query predicate multipleVirtualVariablesForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
exists(int vvarCount |
vvarCount = strictcount(location.getVirtualVariable()) and
vvarCount > 1 and
func = location.getIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message =
"Memory location has " + vvarCount.toString() + " virtual variables in function '$@': (" +
concat(Alias::VirtualVariable vvar |
vvar = location.getVirtualVariable()
|
vvar.toString(), ", "
) + ")."
)
}
}
/** DEPRECATED: Alias for SsaConsistency */
deprecated module SSAConsistency = SsaConsistency;
/** /**
* Provides the portion of the parameterized IR interface that is used to construct the SSA stages * Provides the portion of the parameterized IR interface that is used to construct the SSA stages
* of the IR. The raw stage of the IR does not expose these predicates. * of the IR. The raw stage of the IR does not expose these predicates.

View File

@@ -1,6 +1,7 @@
private import IR private import IR
import InstructionConsistency // module is below import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll import IRTypeConsistency // module is in IRType.qll
import internal.IRConsistencyImports
module InstructionConsistency { module InstructionConsistency {
private import internal.InstructionImports as Imports private import internal.InstructionImports as Imports
@@ -28,7 +29,7 @@ module InstructionConsistency {
PresentIRFunction() { this = TPresentIRFunction(irFunc) } PresentIRFunction() { this = TPresentIRFunction(irFunc) }
override string toString() { override string toString() {
result = concat(Language::getIdentityString(irFunc.getFunction()), "; ") result = concat(LanguageDebug::getIdentityString(irFunc.getFunction()), "; ")
} }
override Language::Location getLocation() { override Language::Location getLocation() {

View File

@@ -149,7 +149,9 @@ private class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction
override Language::Location getLocation() { result = irFunc.getLocation() } override Language::Location getLocation() { result = irFunc.getLocation() }
override string getLabel() { result = Language::getIdentityString(irFunc.getFunction()) } override string getLabel() {
result = Imports::LanguageDebug::getIdentityString(irFunc.getFunction())
}
override int getOrder() { override int getOrder() {
this = this =

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -1 +1,2 @@
import semmle.code.cpp.ir.IRConfiguration as IRConfiguration import semmle.code.cpp.ir.IRConfiguration as IRConfiguration
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -1,6 +1,7 @@
private import IR private import IR
import InstructionConsistency // module is below import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll import IRTypeConsistency // module is in IRType.qll
import internal.IRConsistencyImports
module InstructionConsistency { module InstructionConsistency {
private import internal.InstructionImports as Imports private import internal.InstructionImports as Imports
@@ -28,7 +29,7 @@ module InstructionConsistency {
PresentIRFunction() { this = TPresentIRFunction(irFunc) } PresentIRFunction() { this = TPresentIRFunction(irFunc) }
override string toString() { override string toString() {
result = concat(Language::getIdentityString(irFunc.getFunction()), "; ") result = concat(LanguageDebug::getIdentityString(irFunc.getFunction()), "; ")
} }
override Language::Location getLocation() { override Language::Location getLocation() {

View File

@@ -149,7 +149,9 @@ private class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction
override Language::Location getLocation() { result = irFunc.getLocation() } override Language::Location getLocation() { result = irFunc.getLocation() }
override string getLabel() { result = Language::getIdentityString(irFunc.getFunction()) } override string getLabel() {
result = Imports::LanguageDebug::getIdentityString(irFunc.getFunction())
}
override int getOrder() { override int getOrder() {
this = this =

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -1 +1,2 @@
import semmle.code.cpp.ir.IRConfiguration as IRConfiguration import semmle.code.cpp.ir.IRConfiguration as IRConfiguration
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -1,2 +1,55 @@
private import SSAConstruction as Ssa import SsaConsistency
import Ssa::SsaConsistency import SSAConsistencyImports
module SsaConsistency {
/**
* Holds if a `MemoryOperand` has more than one `MemoryLocation` assigned by alias analysis.
*/
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {
exists(int locationCount |
locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
locationCount > 1 and
func = operand.getEnclosingIRFunction() and
funcText = LanguageDebug::getIdentityString(func.getFunction()) and
message =
operand.getUse().toString() + " " + "Operand has " + locationCount.toString() +
" memory accesses in function '$@': " +
strictconcat(Alias::getOperandMemoryLocation(operand).toString(), ", ")
)
}
/**
* Holds if a `MemoryLocation` does not have an associated `VirtualVariable`.
*/
query predicate missingVirtualVariableForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
not exists(location.getVirtualVariable()) and
func = location.getIRFunction() and
funcText = LanguageDebug::getIdentityString(func.getFunction()) and
message = "Memory location has no virtual variable in function '$@'."
}
/**
* Holds if a `MemoryLocation` is a member of more than one `VirtualVariable`.
*/
query predicate multipleVirtualVariablesForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
exists(int vvarCount |
vvarCount = strictcount(location.getVirtualVariable()) and
vvarCount > 1 and
func = location.getIRFunction() and
funcText = LanguageDebug::getIdentityString(func.getFunction()) and
message =
"Memory location has " + vvarCount.toString() + " virtual variables in function '$@': (" +
concat(Alias::VirtualVariable vvar |
vvar = location.getVirtualVariable()
|
vvar.toString(), ", "
) + ")."
)
}
}

View File

@@ -0,0 +1,3 @@
import semmle.code.cpp.ir.implementation.raw.IR as OldIR
import SimpleSSA as Alias
import semmle.code.cpp.ir.internal.IRCppLanguageDebug as LanguageDebug

View File

@@ -996,7 +996,7 @@ deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1;
/** /**
* Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the * Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the
* `DebugSSA` module, which is then imported by PrintSSA. * `DebugSsa` module, which is then imported by PrintSSA.
*/ */
module DebugSsa { module DebugSsa {
import PhiInsertion import PhiInsertion
@@ -1063,62 +1063,6 @@ private module CachedForDebugging {
int maxValue() { result = 2147483647 } int maxValue() { result = 2147483647 }
} }
module SsaConsistency {
/**
* Holds if a `MemoryOperand` has more than one `MemoryLocation` assigned by alias analysis.
*/
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {
exists(int locationCount |
locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
locationCount > 1 and
func = operand.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message =
operand.getUse().toString() + " " + "Operand has " + locationCount.toString() +
" memory accesses in function '$@': " +
strictconcat(Alias::getOperandMemoryLocation(operand).toString(), ", ")
)
}
/**
* Holds if a `MemoryLocation` does not have an associated `VirtualVariable`.
*/
query predicate missingVirtualVariableForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
not exists(location.getVirtualVariable()) and
func = location.getIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message = "Memory location has no virtual variable in function '$@'."
}
/**
* Holds if a `MemoryLocation` is a member of more than one `VirtualVariable`.
*/
query predicate multipleVirtualVariablesForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
exists(int vvarCount |
vvarCount = strictcount(location.getVirtualVariable()) and
vvarCount > 1 and
func = location.getIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message =
"Memory location has " + vvarCount.toString() + " virtual variables in function '$@': (" +
concat(Alias::VirtualVariable vvar |
vvar = location.getVirtualVariable()
|
vvar.toString(), ", "
) + ")."
)
}
}
/** DEPRECATED: Alias for SsaConsistency */
deprecated module SSAConsistency = SsaConsistency;
/** /**
* Provides the portion of the parameterized IR interface that is used to construct the SSA stages * Provides the portion of the parameterized IR interface that is used to construct the SSA stages
* of the IR. The raw stage of the IR does not expose these predicates. * of the IR. The raw stage of the IR does not expose these predicates.

View File

@@ -1,5 +1,4 @@
private import cpp private import cpp
private import semmle.code.cpp.Print
private import semmle.code.cpp.ir.implementation.IRType private import semmle.code.cpp.ir.implementation.IRType
private import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction::Raw as Raw private import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction::Raw as Raw
@@ -538,12 +537,14 @@ CppType getCanonicalOpaqueType(Type tag, int byteSize) {
} }
/** /**
* Gets a string that uniquely identifies an `IROpaqueType` tag. This may be different from the usual * Gets a string that uniquely identifies an `IROpaqueType` tag. Using `toString` here might
* `toString()` of the tag in order to ensure uniqueness. * not be sufficient to ensure uniqueness, but suffices for our current debugging purposes.
* To ensure uniqueness `getOpaqueTagIdentityString` from `semmle.code.cpp.Print` could be used,
* but that comes at the cost of importing all the `Dump` classes defined in that library.
*/ */
string getOpaqueTagIdentityString(Type tag) { string getOpaqueTagIdentityString(Type tag) {
hasOpaqueType(tag, _) and hasOpaqueType(tag, _) and
result = getTypeIdentityString(tag) result = tag.toString()
} }
module LanguageTypeConsistency { module LanguageTypeConsistency {

View File

@@ -1,5 +1,4 @@
private import cpp as Cpp private import cpp as Cpp
private import semmle.code.cpp.Print as Print
private import IRUtilities private import IRUtilities
private import semmle.code.cpp.ir.implementation.IRType private import semmle.code.cpp.ir.implementation.IRType
private import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as IRConstruction private import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as IRConstruction
@@ -65,8 +64,6 @@ class Expr = Cpp::Expr;
class Class = Cpp::Class; // Used for inheritance conversions class Class = Cpp::Class; // Used for inheritance conversions
predicate getIdentityString = Print::getIdentityString/1;
predicate hasCaseEdge(string minValue, string maxValue) { hasCaseEdge(_, minValue, maxValue) } predicate hasCaseEdge(string minValue, string maxValue) { hasCaseEdge(_, minValue, maxValue) }
predicate hasPositionalArgIndex(int argIndex) { predicate hasPositionalArgIndex(int argIndex) {

View File

@@ -0,0 +1,3 @@
private import semmle.code.cpp.Print as Print
predicate getIdentityString = Print::getIdentityString/1;

View File

@@ -14,6 +14,8 @@ int getPointedSize(Type t) {
* BufferWrite differ. * BufferWrite differ.
*/ */
abstract class BufferAccess extends Expr { abstract class BufferAccess extends Expr {
BufferAccess() { not this.isUnevaluated() }
abstract string getName(); abstract string getName();
/** /**

View File

@@ -357,7 +357,7 @@ module BoostorgAsio {
* Abstract class for flows of protocol values to the first argument of a context * Abstract class for flows of protocol values to the first argument of a context
* constructor. * constructor.
*/ */
abstract class SslContextCallAbstractConfig extends DataFlow::Configuration { abstract deprecated class SslContextCallAbstractConfig extends DataFlow::Configuration {
bindingset[this] bindingset[this]
SslContextCallAbstractConfig() { any() } SslContextCallAbstractConfig() { any() }
@@ -369,10 +369,43 @@ module BoostorgAsio {
} }
} }
/**
* Signature for flows of protocol values to the first argument of a context
* constructor.
*/
signature module SslContextCallConfigSig {
/**
* Holds if `source` is a relevant data flow source.
*/
predicate isSource(DataFlow::Node source);
/**
* Holds if `sink` is a relevant data flow sink.
*/
default predicate isSink(DataFlow::Node sink) {
exists(ConstructorCall cc, SslContextClass c, Expr e | e = sink.asExpr() |
c.getAContructorCall() = cc and
cc.getArgument(0) = e
)
}
}
/**
* Constructs a standard data flow computation for protocol values to the first argument
* of a context constructor.
*/
module SslContextCallMake<SslContextCallConfigSig Config> {
private module C implements DataFlow::ConfigSig {
import Config
}
import DataFlow::Make<C>
}
/** /**
* Any protocol value that flows to the first argument of a context constructor. * Any protocol value that flows to the first argument of a context constructor.
*/ */
class SslContextCallConfig extends SslContextCallAbstractConfig { deprecated class SslContextCallConfig extends SslContextCallAbstractConfig {
SslContextCallConfig() { this = "SslContextCallConfig" } SslContextCallConfig() { this = "SslContextCallConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
@@ -383,10 +416,24 @@ module BoostorgAsio {
} }
} }
/**
* Any protocol value that flows to the first argument of a context constructor.
*/
private module SslContextCallConfig implements SslContextCallConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr e | e = source.asExpr() |
e.fromSource() and
not e.getLocation().getFile().toString().matches("%/boost/asio/%")
)
}
}
module SslContextCallFlow = SslContextCallMake<SslContextCallConfig>;
/** /**
* A banned protocol value that flows to the first argument of a context constructor. * A banned protocol value that flows to the first argument of a context constructor.
*/ */
class SslContextCallBannedProtocolConfig extends SslContextCallAbstractConfig { deprecated class SslContextCallBannedProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallBannedProtocolConfig() { this = "SslContextCallBannedProtocolConfig" } SslContextCallBannedProtocolConfig() { this = "SslContextCallBannedProtocolConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
@@ -398,10 +445,25 @@ module BoostorgAsio {
} }
} }
/**
* A banned protocol value that flows to the first argument of a context constructor.
*/
private module SslContextCallBannedProtocolConfig implements SslContextCallConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr e | e = source.asExpr() |
e.fromSource() and
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
isExprBannedBoostProtocol(e)
)
}
}
module SslContextCallBannedProtocolFlow = SslContextCallMake<SslContextCallBannedProtocolConfig>;
/** /**
* A TLS 1.2 protocol value that flows to the first argument of a context constructor. * A TLS 1.2 protocol value that flows to the first argument of a context constructor.
*/ */
class SslContextCallTls12ProtocolConfig extends SslContextCallAbstractConfig { deprecated class SslContextCallTls12ProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallTls12ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" } SslContextCallTls12ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
@@ -413,10 +475,25 @@ module BoostorgAsio {
} }
} }
/**
* A TLS 1.2 protocol value that flows to the first argument of a context constructor.
*/
private module SslContextCallTls12ProtocolConfig implements SslContextCallConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr e | e = source.asExpr() |
e.fromSource() and
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
isExprTls12BoostProtocol(e)
)
}
}
module SslContextCallTls12ProtocolFlow = SslContextCallMake<SslContextCallTls12ProtocolConfig>;
/** /**
* A TLS 1.3 protocol value that flows to the first argument of a context constructor. * A TLS 1.3 protocol value that flows to the first argument of a context constructor.
*/ */
class SslContextCallTls13ProtocolConfig extends SslContextCallAbstractConfig { deprecated class SslContextCallTls13ProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallTls13ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" } SslContextCallTls13ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
@@ -428,10 +505,25 @@ module BoostorgAsio {
} }
} }
/**
* A TLS 1.3 protocol value that flows to the first argument of a context constructor.
*/
private module SslContextCallTls13ProtocolConfig implements SslContextCallConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr e | e = source.asExpr() |
e.fromSource() and
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
isExprTls13BoostProtocol(e)
)
}
}
module SslContextCallTls13ProtocolFlow = SslContextCallMake<SslContextCallTls13ProtocolConfig>;
/** /**
* A generic TLS protocol value that flows to the first argument of a context constructor. * A generic TLS protocol value that flows to the first argument of a context constructor.
*/ */
class SslContextCallTlsProtocolConfig extends SslContextCallAbstractConfig { deprecated class SslContextCallTlsProtocolConfig extends SslContextCallAbstractConfig {
SslContextCallTlsProtocolConfig() { this = "SslContextCallTlsProtocolConfig" } SslContextCallTlsProtocolConfig() { this = "SslContextCallTlsProtocolConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
@@ -443,10 +535,25 @@ module BoostorgAsio {
} }
} }
/**
* A generic TLS protocol value that flows to the first argument of a context constructor.
*/
private module SslContextCallTlsProtocolConfig implements SslContextCallConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr e | e = source.asExpr() |
e.fromSource() and
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
isExprTlsBoostProtocol(e)
)
}
}
module SslContextCallTlsProtocolFlow = SslContextCallMake<SslContextCallTlsProtocolConfig>;
/** /**
* A context constructor call that flows to a call to `SetOptions()`. * A context constructor call that flows to a call to `SetOptions()`.
*/ */
class SslContextFlowsToSetOptionConfig extends DataFlow::Configuration { deprecated class SslContextFlowsToSetOptionConfig extends DataFlow::Configuration {
SslContextFlowsToSetOptionConfig() { this = "SslContextFlowsToSetOptionConfig" } SslContextFlowsToSetOptionConfig() { this = "SslContextFlowsToSetOptionConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
@@ -467,10 +574,34 @@ module BoostorgAsio {
} }
} }
/**
* A context constructor call that flows to a call to `SetOptions()`.
*/
private module SslContextFlowsToSetOptionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(SslContextClass c, ConstructorCall cc |
cc = source.asExpr() and
c.getAContructorCall() = cc
)
}
predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc, SslSetOptionsFunction f, Variable v, VariableAccess va |
va = sink.asExpr()
|
f.getACallToThisFunction() = fc and
v.getAnAccess() = va and
va = fc.getQualifier()
)
}
}
module SslContextFlowsToSetOptionFlow = DataFlow::Make<SslContextFlowsToSetOptionConfig>;
/** /**
* An option value that flows to the first parameter of a call to `SetOptions()`. * An option value that flows to the first parameter of a call to `SetOptions()`.
*/ */
class SslOptionConfig extends DataFlow::Configuration { deprecated class SslOptionConfig extends DataFlow::Configuration {
SslOptionConfig() { this = "SslOptionConfig" } SslOptionConfig() { this = "SslOptionConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
@@ -488,4 +619,26 @@ module BoostorgAsio {
) )
} }
} }
/**
* An option value that flows to the first parameter of a call to `SetOptions()`.
*/
private module SslOptionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr e | e = source.asExpr() |
e.fromSource() and
not e.getLocation().getFile().toString().matches("%/boost/asio/%")
)
}
predicate isSink(DataFlow::Node sink) {
exists(SslSetOptionsFunction f, FunctionCall call |
sink.asExpr() = call.getArgument(0) and
f.getACallToThisFunction() = call and
not sink.getLocation().getFile().toString().matches("%/boost/asio/%")
)
}
}
module SslOptionFlow = DataFlow::Make<SslOptionConfig>;
} }

View File

@@ -1,3 +1,10 @@
## 0.5.5
### Deprecated Queries
* The `NetworkToBufferSizeConfiguration` and `UntrustedDataToExternalApiConfig` dataflow configurations have been deprecated. Please use `NetworkToBufferSizeFlow` and `UntrustedDataToExternalApiFlow`.
* The `LeapYearCheckConfiguration`, `FiletimeYearArithmeticOperationCheckConfiguration`, and `PossibleYearArithmeticOperationCheckConfiguration` dataflow configurations have been deprecated. Please use `LeapYearCheckFlow`, `FiletimeYearArithmeticOperationCheckFlow` and `PossibleYearArithmeticOperationCheckFlow`.
## 0.5.4 ## 0.5.4
No user-facing changes. No user-facing changes.

View File

@@ -22,7 +22,8 @@ import LoopBounds
private predicate staticBufferBase(VariableAccess access, Variable v) { private predicate staticBufferBase(VariableAccess access, Variable v) {
v.getType().(ArrayType).getBaseType() instanceof CharType and v.getType().(ArrayType).getBaseType() instanceof CharType and
access = v.getAnAccess() and access = v.getAnAccess() and
not memberMayBeVarSize(_, v) not memberMayBeVarSize(_, v) and
not access.isUnevaluated()
} }
predicate staticBuffer(VariableAccess access, Variable v, int size) { predicate staticBuffer(VariableAccess access, Variable v, int size) {

View File

@@ -132,7 +132,7 @@ predicate isSinkImpl(DataFlow::Node sink, Expr formatString) {
exists(FormattingFunctionCall fc | formatString = fc.getArgument(fc.getFormatParameterIndex())) exists(FormattingFunctionCall fc | formatString = fc.getArgument(fc.getFormatParameterIndex()))
} }
module NonConstFlowConfiguration implements DataFlow::ConfigSig { module NonConstFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { predicate isSource(DataFlow::Node source) {
exists(boolean isIndirect, Type t | exists(boolean isIndirect, Type t |
isNonConst(source, isIndirect) and isNonConst(source, isIndirect) and
@@ -146,7 +146,7 @@ module NonConstFlowConfiguration implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node node) { isBarrierNode(node) } predicate isBarrier(DataFlow::Node node) { isBarrierNode(node) }
} }
module NonConstFlow = TaintTracking::Make<NonConstFlowConfiguration>; module NonConstFlow = TaintTracking::Make<NonConstFlowConfig>;
from FormattingFunctionCall call, Expr formatString from FormattingFunctionCall call, Expr formatString
where where

View File

@@ -223,7 +223,7 @@ deprecated class LeapYearCheckConfiguration extends DataFlow::Configuration {
* Data flow configuration for finding a variable access that would flow into * Data flow configuration for finding a variable access that would flow into
* a function call that includes an operation to check for leap year. * a function call that includes an operation to check for leap year.
*/ */
private module LeapYearCheckConfiguration implements DataFlow::ConfigSig { private module LeapYearCheckConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof VariableAccess } predicate isSource(DataFlow::Node source) { source.asExpr() instanceof VariableAccess }
predicate isSink(DataFlow::Node sink) { predicate isSink(DataFlow::Node sink) {
@@ -231,7 +231,7 @@ private module LeapYearCheckConfiguration implements DataFlow::ConfigSig {
} }
} }
module LeapYearCheckFlow = DataFlow::Make<LeapYearCheckConfiguration>; module LeapYearCheckFlow = DataFlow::Make<LeapYearCheckConfig>;
/** /**
* Data flow configuration for finding an operation with hardcoded 365 that will flow into * Data flow configuration for finding an operation with hardcoded 365 that will flow into
@@ -264,7 +264,7 @@ deprecated class FiletimeYearArithmeticOperationCheckConfiguration extends DataF
* Data flow configuration for finding an operation with hardcoded 365 that will flow into * Data flow configuration for finding an operation with hardcoded 365 that will flow into
* a `FILEINFO` field. * a `FILEINFO` field.
*/ */
private module FiletimeYearArithmeticOperationCheckConfiguration implements DataFlow::ConfigSig { private module FiletimeYearArithmeticOperationCheckConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { predicate isSource(DataFlow::Node source) {
exists(Expr e, Operation op | e = source.asExpr() | exists(Expr e, Operation op | e = source.asExpr() |
op.getAChild*().getValue().toInt() = 365 and op.getAChild*().getValue().toInt() = 365 and
@@ -284,7 +284,7 @@ private module FiletimeYearArithmeticOperationCheckConfiguration implements Data
} }
module FiletimeYearArithmeticOperationCheckFlow = module FiletimeYearArithmeticOperationCheckFlow =
DataFlow::Make<FiletimeYearArithmeticOperationCheckConfiguration>; DataFlow::Make<FiletimeYearArithmeticOperationCheckConfig>;
/** /**
* Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field. * Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field.
@@ -334,7 +334,7 @@ deprecated class PossibleYearArithmeticOperationCheckConfiguration extends Taint
/** /**
* Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field. * Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field.
*/ */
private module PossibleYearArithmeticOperationCheckConfiguration implements DataFlow::ConfigSig { private module PossibleYearArithmeticOperationCheckConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { predicate isSource(DataFlow::Node source) {
exists(Operation op | op = source.asConvertedExpr() | exists(Operation op | op = source.asConvertedExpr() |
op.getAChild*().getValue().toInt() = 365 and op.getAChild*().getValue().toInt() = 365 and
@@ -372,4 +372,4 @@ private module PossibleYearArithmeticOperationCheckConfiguration implements Data
} }
module PossibleYearArithmeticOperationCheckFlow = module PossibleYearArithmeticOperationCheckFlow =
TaintTracking::Make<PossibleYearArithmeticOperationCheckConfiguration>; TaintTracking::Make<PossibleYearArithmeticOperationCheckConfig>;

View File

@@ -147,7 +147,7 @@ deprecated class NetworkToBufferSizeConfiguration extends DataFlow::Configuratio
} }
} }
private module NetworkToBufferSizeConfiguration implements DataFlow::ConfigSig { private module NetworkToBufferSizeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall } predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall }
predicate isSink(DataFlow::Node node) { node.asExpr() = any(BufferAccess ba).getAccessedLength() } predicate isSink(DataFlow::Node node) { node.asExpr() = any(BufferAccess ba).getAccessedLength() }
@@ -161,4 +161,4 @@ private module NetworkToBufferSizeConfiguration implements DataFlow::ConfigSig {
} }
} }
module NetworkToBufferSizeFlow = DataFlow::Make<NetworkToBufferSizeConfiguration>; module NetworkToBufferSizeFlow = DataFlow::Make<NetworkToBufferSizeConfig>;

View File

@@ -33,13 +33,10 @@ predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) {
ExistsAnyFlow::hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and ExistsAnyFlow::hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and
exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions | exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions |
contextSetOptions = fcSetOptions.getQualifier() and contextSetOptions = fcSetOptions.getQualifier() and
forall( forall(Expr optionArgument, Expr optionArgumentSource |
Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig,
Expr optionArgumentSource
|
optionArgument = fcSetOptions.getArgument(0) and optionArgument = fcSetOptions.getArgument(0) and
optionArgConfig BoostorgAsio::SslOptionFlow::hasFlow(DataFlow::exprNode(optionArgumentSource),
.hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument)) DataFlow::exprNode(optionArgument))
| |
optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag
) )
@@ -50,11 +47,10 @@ predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) {
bindingset[flag] bindingset[flag]
predicate isOptionNotSet(ConstructorCall cc, int flag) { not isOptionSet(cc, flag, _) } predicate isOptionNotSet(ConstructorCall cc, int flag) { not isOptionSet(cc, flag, _) }
from from Expr protocolSource, Expr protocolSink, ConstructorCall cc, Expr e, string msg
BoostorgAsio::SslContextCallTlsProtocolConfig configConstructor, Expr protocolSource,
Expr protocolSink, ConstructorCall cc, Expr e, string msg
where where
configConstructor.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and BoostorgAsio::SslContextCallTlsProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource),
DataFlow::exprNode(protocolSink)) and
cc.getArgument(0) = protocolSink and cc.getArgument(0) = protocolSink and
( (
BoostorgAsio::isExprSslV23BoostProtocol(protocolSource) and BoostorgAsio::isExprSslV23BoostProtocol(protocolSource) and

View File

@@ -12,18 +12,15 @@
import cpp import cpp
import semmle.code.cpp.security.boostorg.asio.protocols import semmle.code.cpp.security.boostorg.asio.protocols
from from Expr protocolSource, Expr protocolSink, ConstructorCall cc
BoostorgAsio::SslContextCallConfig config, Expr protocolSource, Expr protocolSink,
ConstructorCall cc
where where
config.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and BoostorgAsio::SslContextCallFlow::hasFlow(DataFlow::exprNode(protocolSource),
not exists(BoostorgAsio::SslContextCallTlsProtocolConfig tlsConfig | DataFlow::exprNode(protocolSink)) and
tlsConfig.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) not BoostorgAsio::SslContextCallTlsProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource),
) and DataFlow::exprNode(protocolSink)) and
cc.getArgument(0) = protocolSink and cc.getArgument(0) = protocolSink and
exists(BoostorgAsio::SslContextCallBannedProtocolConfig bannedConfig | BoostorgAsio::SslContextCallBannedProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource),
bannedConfig.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) DataFlow::exprNode(protocolSink))
)
select protocolSink, "Usage of $@ specifying a deprecated hardcoded protocol $@ in function $@.", select protocolSink, "Usage of $@ specifying a deprecated hardcoded protocol $@ in function $@.",
cc, "boost::asio::ssl::context::context", protocolSource, protocolSource.toString(), cc, "boost::asio::ssl::context::context", protocolSource, protocolSource.toString(),
cc.getEnclosingFunction(), cc.getEnclosingFunction().toString() cc.getEnclosingFunction(), cc.getEnclosingFunction().toString()

View File

@@ -70,7 +70,7 @@ predicate hasUpperBoundsCheck(Variable var) {
) )
} }
module TaintedPathConfiguration implements DataFlow::ConfigSig { module TaintedPathConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof FlowSource } predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
predicate isSink(DataFlow::Node node) { predicate isSink(DataFlow::Node node) {
@@ -90,7 +90,7 @@ module TaintedPathConfiguration implements DataFlow::ConfigSig {
} }
} }
module TaintedPath = TaintTracking::Make<TaintedPathConfiguration>; module TaintedPath = TaintTracking::Make<TaintedPathConfig>;
from from
FileFunction fileFunction, Expr taintedArg, FlowSource taintSource, FileFunction fileFunction, Expr taintedArg, FlowSource taintSource,

View File

@@ -97,7 +97,7 @@ predicate isBarrierImpl(DataFlow::Node node) {
* given sink. This avoids a cartesian product between all sinks and all `ExecState`s in * given sink. This avoids a cartesian product between all sinks and all `ExecState`s in
* `ExecTaintConfiguration::isSink`. * `ExecTaintConfiguration::isSink`.
*/ */
module ExecStateConfiguration implements DataFlow::ConfigSig { module ExecStateConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { any(ExecState state).getOutgoingNode() = source } predicate isSource(DataFlow::Node source) { any(ExecState state).getOutgoingNode() = source }
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _, _) } predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _, _) }
@@ -109,9 +109,9 @@ module ExecStateConfiguration implements DataFlow::ConfigSig {
} }
} }
module ExecState = TaintTracking::Make<ExecStateConfiguration>; module ExecState = TaintTracking::Make<ExecStateConfig>;
module ExecTaintConfiguration implements DataFlow::StateConfigSig { module ExecTaintConfig implements DataFlow::StateConfigSig {
class FlowState = TState; class FlowState = TState;
predicate isSource(DataFlow::Node source, FlowState state) { predicate isSource(DataFlow::Node source, FlowState state) {
@@ -120,7 +120,7 @@ module ExecTaintConfiguration implements DataFlow::StateConfigSig {
} }
predicate isSink(DataFlow::Node sink, FlowState state) { predicate isSink(DataFlow::Node sink, FlowState state) {
ExecStateConfiguration::isSink(sink) and ExecStateConfig::isSink(sink) and
state.(ExecState).isFeasibleForSink(sink) state.(ExecState).isFeasibleForSink(sink)
} }
@@ -141,7 +141,7 @@ module ExecTaintConfiguration implements DataFlow::StateConfigSig {
} }
} }
module ExecTaint = TaintTracking::MakeWithState<ExecTaintConfiguration>; module ExecTaint = TaintTracking::MakeWithState<ExecTaintConfig>;
from from
ExecTaint::PathNode sourceNode, ExecTaint::PathNode sinkNode, string taintCause, string callChain, ExecTaint::PathNode sourceNode, ExecTaint::PathNode sinkNode, string taintCause, string callChain,

View File

@@ -90,7 +90,7 @@ predicate missingGuard(VariableAccess va, string effect) {
) )
} }
module UncontrolledArithConfiguration implements DataFlow::ConfigSig { module UncontrolledArithConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { predicate isSource(DataFlow::Node source) {
exists(RandomFunction rand, Call call | call.getTarget() = rand | exists(RandomFunction rand, Call call | call.getTarget() = rand |
rand.getFunctionOutput().isReturnValue() and rand.getFunctionOutput().isReturnValue() and
@@ -122,7 +122,7 @@ module UncontrolledArithConfiguration implements DataFlow::ConfigSig {
} }
} }
module UncontrolledArith = TaintTracking::Make<UncontrolledArithConfiguration>; module UncontrolledArith = TaintTracking::Make<UncontrolledArithConfig>;
/** Gets the expression that corresponds to `node`, if any. */ /** Gets the expression that corresponds to `node`, if any. */
Expr getExpr(DataFlow::Node node) { result = [node.asExpr(), node.asDefiningArgument()] } Expr getExpr(DataFlow::Node node) { result = [node.asExpr(), node.asDefiningArgument()] }

View File

@@ -54,7 +54,7 @@ predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Va
predicate isFlowSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() } predicate isFlowSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() }
module TaintedAllocationSizeConfiguration implements DataFlow::ConfigSig { module TaintedAllocationSizeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isFlowSource(source, _) } predicate isSource(DataFlow::Node source) { isFlowSource(source, _) }
predicate isSink(DataFlow::Node sink) { allocSink(_, sink) } predicate isSink(DataFlow::Node sink) { allocSink(_, sink) }
@@ -95,7 +95,7 @@ module TaintedAllocationSizeConfiguration implements DataFlow::ConfigSig {
} }
} }
module TaintedAllocationSize = TaintTracking::Make<TaintedAllocationSizeConfiguration>; module TaintedAllocationSize = TaintTracking::Make<TaintedAllocationSizeConfig>;
from from
Expr alloc, TaintedAllocationSize::PathNode source, TaintedAllocationSize::PathNode sink, Expr alloc, TaintedAllocationSize::PathNode source, TaintedAllocationSize::PathNode sink,

View File

@@ -39,7 +39,7 @@ class SensitiveBufferWrite extends Expr instanceof BufferWrite::BufferWrite {
* A taint flow configuration for flow from user input to a buffer write * A taint flow configuration for flow from user input to a buffer write
* into a sensitive expression. * into a sensitive expression.
*/ */
module ToBufferConfiguration implements DataFlow::ConfigSig { module ToBufferConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof FlowSource } predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
predicate isBarrier(DataFlow::Node node) { predicate isBarrier(DataFlow::Node node) {
@@ -49,7 +49,7 @@ module ToBufferConfiguration implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) } predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) }
} }
module ToBufferFlow = TaintTracking::Make<ToBufferConfiguration>; module ToBufferFlow = TaintTracking::Make<ToBufferConfig>;
predicate isSinkImpl(DataFlow::Node sink, SensitiveBufferWrite w) { predicate isSinkImpl(DataFlow::Node sink, SensitiveBufferWrite w) {
w.getASource() = sink.asIndirectExpr() w.getASource() = sink.asIndirectExpr()

View File

@@ -23,7 +23,7 @@ import FromSensitiveFlow::PathGraph
/** /**
* A taint flow configuration for flow from a sensitive expression to a `FileWrite` sink. * A taint flow configuration for flow from a sensitive expression to a `FileWrite` sink.
*/ */
module FromSensitiveConfiguration implements DataFlow::ConfigSig { module FromSensitiveConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSourceImpl(source, _) } predicate isSource(DataFlow::Node source) { isSourceImpl(source, _) }
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _, _) } predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _, _) }
@@ -33,7 +33,7 @@ module FromSensitiveConfiguration implements DataFlow::ConfigSig {
} }
} }
module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfiguration>; module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfig>;
predicate isSinkImpl(DataFlow::Node sink, FileWrite w, Expr dest) { predicate isSinkImpl(DataFlow::Node sink, FileWrite w, Expr dest) {
exists(Expr e | exists(Expr e |

View File

@@ -234,7 +234,7 @@ predicate isSourceImpl(DataFlow::Node source) {
* A taint flow configuration for flow from a sensitive expression to a network * A taint flow configuration for flow from a sensitive expression to a network
* operation. * operation.
*/ */
module FromSensitiveConfiguration implements DataFlow::ConfigSig { module FromSensitiveConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSourceImpl(source) } predicate isSource(DataFlow::Node source) { isSourceImpl(source) }
predicate isSink(DataFlow::Node sink) { isSinkSendRecv(sink, _) } predicate isSink(DataFlow::Node sink) { isSinkSendRecv(sink, _) }
@@ -250,12 +250,12 @@ module FromSensitiveConfiguration implements DataFlow::ConfigSig {
} }
} }
module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfiguration>; module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfig>;
/** /**
* A taint flow configuration for flow from a sensitive expression to an encryption operation. * A taint flow configuration for flow from a sensitive expression to an encryption operation.
*/ */
module ToEncryptionConfiguration implements DataFlow::ConfigSig { module ToEncryptionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { FromSensitiveFlow::hasFlow(source, _) } predicate isSource(DataFlow::Node source) { FromSensitiveFlow::hasFlow(source, _) }
predicate isSink(DataFlow::Node sink) { isSinkEncrypt(sink, _) } predicate isSink(DataFlow::Node sink) { isSinkEncrypt(sink, _) }
@@ -271,12 +271,12 @@ module ToEncryptionConfiguration implements DataFlow::ConfigSig {
} }
} }
module ToEncryptionFlow = TaintTracking::Make<ToEncryptionConfiguration>; module ToEncryptionFlow = TaintTracking::Make<ToEncryptionConfig>;
/** /**
* A taint flow configuration for flow from an encryption operation to a network operation. * A taint flow configuration for flow from an encryption operation to a network operation.
*/ */
module FromEncryptionConfiguration implements DataFlow::ConfigSig { module FromEncryptionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSinkEncrypt(source, _) } predicate isSource(DataFlow::Node source) { isSinkEncrypt(source, _) }
predicate isSink(DataFlow::Node sink) { FromSensitiveFlow::hasFlowTo(sink) } predicate isSink(DataFlow::Node sink) { FromSensitiveFlow::hasFlowTo(sink) }
@@ -286,7 +286,7 @@ module FromEncryptionConfiguration implements DataFlow::ConfigSig {
} }
} }
module FromEncryptionFlow = TaintTracking::Make<FromEncryptionConfiguration>; module FromEncryptionFlow = TaintTracking::Make<FromEncryptionConfig>;
from from
FromSensitiveFlow::PathNode source, FromSensitiveFlow::PathNode sink, FromSensitiveFlow::PathNode source, FromSensitiveFlow::PathNode sink,

View File

@@ -100,7 +100,7 @@ predicate isSinkImpl(DataFlow::Node sink, SqliteFunctionCall c, Type t) {
/** /**
* A taint flow configuration for flow from a sensitive expression to a `SqliteFunctionCall` sink. * A taint flow configuration for flow from a sensitive expression to a `SqliteFunctionCall` sink.
*/ */
module FromSensitiveConfiguration implements DataFlow::ConfigSig { module FromSensitiveConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { predicate isSource(DataFlow::Node source) {
isSourceImpl(source, _) and not sqlite_encryption_used() isSourceImpl(source, _) and not sqlite_encryption_used()
} }
@@ -125,7 +125,7 @@ module FromSensitiveConfiguration implements DataFlow::ConfigSig {
} }
} }
module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfiguration>; module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfig>;
from from
SensitiveExpr sensitive, FromSensitiveFlow::PathNode source, FromSensitiveFlow::PathNode sink, SensitiveExpr sensitive, FromSensitiveFlow::PathNode source, FromSensitiveFlow::PathNode sink,

View File

@@ -28,7 +28,7 @@ int getMinimumKeyStrength(string func, int paramIndex) {
result = 2048 result = 2048
} }
module KeyStrengthFlowConfiguration implements DataFlow::ConfigSig { module KeyStrengthFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { predicate isSource(DataFlow::Node node) {
exists(int bits | exists(int bits |
node.asInstruction().(IntegerConstantInstruction).getValue().toInt() = bits and node.asInstruction().(IntegerConstantInstruction).getValue().toInt() = bits and
@@ -46,7 +46,7 @@ module KeyStrengthFlowConfiguration implements DataFlow::ConfigSig {
} }
} }
module KeyStrengthFlow = DataFlow::Make<KeyStrengthFlowConfiguration>; module KeyStrengthFlow = DataFlow::Make<KeyStrengthFlowConfig>;
from from
KeyStrengthFlow::PathNode source, KeyStrengthFlow::PathNode sink, FunctionCall fc, int param, KeyStrengthFlow::PathNode source, KeyStrengthFlow::PathNode sink, FunctionCall fc, int param,

View File

@@ -54,7 +54,7 @@ class CreateProcessFunctionCall extends FunctionCall {
/** /**
* Dataflow that detects a call to CreateProcess with a NULL value for lpApplicationName argument * Dataflow that detects a call to CreateProcess with a NULL value for lpApplicationName argument
*/ */
module NullAppNameCreateProcessFunctionConfiguration implements DataFlow::ConfigSig { module NullAppNameCreateProcessFunctionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof NullValue } predicate isSource(DataFlow::Node source) { source.asExpr() instanceof NullValue }
predicate isSink(DataFlow::Node sink) { predicate isSink(DataFlow::Node sink) {
@@ -64,13 +64,12 @@ module NullAppNameCreateProcessFunctionConfiguration implements DataFlow::Config
} }
} }
module NullAppNameCreateProcessFunction = module NullAppNameCreateProcessFunction = DataFlow::Make<NullAppNameCreateProcessFunctionConfig>;
DataFlow::Make<NullAppNameCreateProcessFunctionConfiguration>;
/** /**
* Dataflow that detects a call to CreateProcess with an unquoted commandLine argument * Dataflow that detects a call to CreateProcess with an unquoted commandLine argument
*/ */
module QuotedCommandInCreateProcessFunctionConfiguration implements DataFlow::ConfigSig { module QuotedCommandInCreateProcessFunctionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { predicate isSource(DataFlow::Node source) {
exists(string s | exists(string s |
s = source.asExpr().getValue().toString() and s = source.asExpr().getValue().toString() and
@@ -86,7 +85,7 @@ module QuotedCommandInCreateProcessFunctionConfiguration implements DataFlow::Co
} }
module QuotedCommandInCreateProcessFunction = module QuotedCommandInCreateProcessFunction =
DataFlow::Make<QuotedCommandInCreateProcessFunctionConfiguration>; DataFlow::Make<QuotedCommandInCreateProcessFunctionConfig>;
bindingset[s] bindingset[s]
predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) { predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) {

View File

@@ -18,7 +18,7 @@ import semmle.code.cpp.models.interfaces.FlowSource
import ExposedSystemData::PathGraph import ExposedSystemData::PathGraph
import SystemData import SystemData
module ExposedSystemDataConfiguration implements DataFlow::ConfigSig { module ExposedSystemDataConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source = any(SystemData sd).getAnExpr() } predicate isSource(DataFlow::Node source) { source = any(SystemData sd).getAnExpr() }
predicate isSink(DataFlow::Node sink) { predicate isSink(DataFlow::Node sink) {
@@ -30,7 +30,7 @@ module ExposedSystemDataConfiguration implements DataFlow::ConfigSig {
} }
} }
module ExposedSystemData = TaintTracking::Make<ExposedSystemDataConfiguration>; module ExposedSystemData = TaintTracking::Make<ExposedSystemDataConfig>;
from ExposedSystemData::PathNode source, ExposedSystemData::PathNode sink from ExposedSystemData::PathNode source, ExposedSystemData::PathNode sink
where where

View File

@@ -31,7 +31,7 @@ import semmle.code.cpp.security.OutputWrite
import PotentiallyExposedSystemData::PathGraph import PotentiallyExposedSystemData::PathGraph
import SystemData import SystemData
module PotentiallyExposedSystemDataConfiguration implements DataFlow::ConfigSig { module PotentiallyExposedSystemDataConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { predicate isSource(DataFlow::Node source) {
source = any(SystemData sd | sd.isSensitive()).getAnExpr() source = any(SystemData sd | sd.isSensitive()).getAnExpr()
} }
@@ -51,8 +51,7 @@ module PotentiallyExposedSystemDataConfiguration implements DataFlow::ConfigSig
} }
} }
module PotentiallyExposedSystemData = module PotentiallyExposedSystemData = TaintTracking::Make<PotentiallyExposedSystemDataConfig>;
TaintTracking::Make<PotentiallyExposedSystemDataConfiguration>;
from PotentiallyExposedSystemData::PathNode source, PotentiallyExposedSystemData::PathNode sink from PotentiallyExposedSystemData::PathNode source, PotentiallyExposedSystemData::PathNode sink
where PotentiallyExposedSystemData::hasFlowPath(source, sink) where PotentiallyExposedSystemData::hasFlowPath(source, sink)

View File

@@ -19,7 +19,7 @@ import XxeFlow::PathGraph
/** /**
* A configuration for tracking XML objects and their states. * A configuration for tracking XML objects and their states.
*/ */
module XxeConfiguration implements DataFlow::StateConfigSig { module XxeConfig implements DataFlow::StateConfigSig {
class FlowState = TXxeFlowState; class FlowState = TXxeFlowState;
predicate isSource(DataFlow::Node node, FlowState flowstate) { predicate isSource(DataFlow::Node node, FlowState flowstate) {
@@ -45,7 +45,7 @@ module XxeConfiguration implements DataFlow::StateConfigSig {
} }
} }
module XxeFlow = DataFlow::MakeWithState<XxeConfiguration>; module XxeFlow = DataFlow::MakeWithState<XxeConfig>;
from XxeFlow::PathNode source, XxeFlow::PathNode sink from XxeFlow::PathNode source, XxeFlow::PathNode sink
where XxeFlow::hasFlowPath(source, sink) where XxeFlow::hasFlowPath(source, sink)

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* The `NetworkToBufferSizeConfiguration` and `UntrustedDataToExternalApiConfig` dataflow configurations have been deprecated. Please use `NetworkToBufferSizeFlow` and `UntrustedDataToExternalApiFlow`.

View File

@@ -1,4 +1,6 @@
--- ## 0.5.5
category: deprecated
--- ### Deprecated Queries
* The `NetworkToBufferSizeConfiguration` and `UntrustedDataToExternalApiConfig` dataflow configurations have been deprecated. Please use `NetworkToBufferSizeFlow` and `UntrustedDataToExternalApiFlow`.
* The `LeapYearCheckConfiguration`, `FiletimeYearArithmeticOperationCheckConfiguration`, and `PossibleYearArithmeticOperationCheckConfiguration` dataflow configurations have been deprecated. Please use `LeapYearCheckFlow`, `FiletimeYearArithmeticOperationCheckFlow` and `PossibleYearArithmeticOperationCheckFlow`. * The `LeapYearCheckConfiguration`, `FiletimeYearArithmeticOperationCheckConfiguration`, and `PossibleYearArithmeticOperationCheckConfiguration` dataflow configurations have been deprecated. Please use `LeapYearCheckFlow`, `FiletimeYearArithmeticOperationCheckFlow` and `PossibleYearArithmeticOperationCheckFlow`.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.5.4 lastReleaseVersion: 0.5.5

View File

@@ -35,7 +35,7 @@ private predicate isCommandSubstitutionDisabled(FunctionCall fc) {
/** /**
* A configuration to track user-supplied data to the `wordexp` function. * A configuration to track user-supplied data to the `wordexp` function.
*/ */
module WordexpTaintConfiguration implements DataFlow::ConfigSig { module WordexpTaintConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof FlowSource } predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
predicate isSink(DataFlow::Node sink) { predicate isSink(DataFlow::Node sink) {
@@ -50,7 +50,7 @@ module WordexpTaintConfiguration implements DataFlow::ConfigSig {
} }
} }
module WordexpTaint = TaintTracking::Make<WordexpTaintConfiguration>; module WordexpTaint = TaintTracking::Make<WordexpTaintConfig>;
from WordexpTaint::PathNode sourceNode, WordexpTaint::PathNode sinkNode from WordexpTaint::PathNode sourceNode, WordexpTaint::PathNode sinkNode
where WordexpTaint::hasFlowPath(sourceNode, sinkNode) where WordexpTaint::hasFlowPath(sourceNode, sinkNode)

View File

@@ -15,8 +15,7 @@ import experimental.semmle.code.cpp.semantic.SemanticBound
import experimental.semmle.code.cpp.semantic.SemanticExprSpecific import experimental.semmle.code.cpp.semantic.SemanticExprSpecific
import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.dataflow.DataFlow import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.ir.dataflow.DataFlow2 import PointerArithmeticToDerefFlow::PathGraph
import DataFlow2::PathGraph
pragma[nomagic] pragma[nomagic]
Instruction getABoundIn(SemBound b, IRFunction func) { Instruction getABoundIn(SemBound b, IRFunction func) {
@@ -36,16 +35,16 @@ predicate bounded(Instruction i, Instruction b, int delta) {
) )
} }
class FieldAddressToPointerArithmeticConf extends DataFlow::Configuration { module FieldAddressToPointerArithmeticConfig implements DataFlow::ConfigSig {
FieldAddressToPointerArithmeticConf() { this = "FieldAddressToPointerArithmeticConf" } predicate isSource(DataFlow::Node source) { isFieldAddressSource(_, source) }
override predicate isSource(DataFlow::Node source) { isFieldAddressSource(_, source) } predicate isSink(DataFlow::Node sink) {
override predicate isSink(DataFlow::Node sink) {
exists(PointerAddInstruction pai | pai.getLeft() = sink.asInstruction()) exists(PointerAddInstruction pai | pai.getLeft() = sink.asInstruction())
} }
} }
module FieldAddressToPointerArithmeticFlow = DataFlow::Make<FieldAddressToPointerArithmeticConfig>;
predicate isFieldAddressSource(Field f, DataFlow::Node source) { predicate isFieldAddressSource(Field f, DataFlow::Node source) {
source.asInstruction().(FieldAddressInstruction).getField() = f source.asInstruction().(FieldAddressInstruction).getField() = f
} }
@@ -70,11 +69,8 @@ predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string o
} }
predicate isConstantSizeOverflowSource(Field f, PointerAddInstruction pai, int delta) { predicate isConstantSizeOverflowSource(Field f, PointerAddInstruction pai, int delta) {
exists( exists(int size, int bound, DataFlow::Node source, DataFlow::InstructionNode sink |
int size, int bound, FieldAddressToPointerArithmeticConf conf, DataFlow::Node source, FieldAddressToPointerArithmeticFlow::hasFlow(source, sink) and
DataFlow::InstructionNode sink
|
conf.hasFlow(source, sink) and
isFieldAddressSource(f, source) and isFieldAddressSource(f, source) and
pai.getLeft() = sink.asInstruction() and pai.getLeft() = sink.asInstruction() and
f.getUnspecifiedType().(ArrayType).getArraySize() = size and f.getUnspecifiedType().(ArrayType).getArraySize() = size and
@@ -86,21 +82,21 @@ predicate isConstantSizeOverflowSource(Field f, PointerAddInstruction pai, int d
) )
} }
class PointerArithmeticToDerefConf extends DataFlow2::Configuration { module PointerArithmeticToDerefConfig implements DataFlow::ConfigSig {
PointerArithmeticToDerefConf() { this = "PointerArithmeticToDerefConf" } predicate isSource(DataFlow::Node source) {
override predicate isSource(DataFlow::Node source) {
isConstantSizeOverflowSource(_, source.asInstruction(), _) isConstantSizeOverflowSource(_, source.asInstruction(), _)
} }
override predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) } predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) }
} }
module PointerArithmeticToDerefFlow = DataFlow::Make<PointerArithmeticToDerefConfig>;
from from
Field f, DataFlow2::PathNode source, DataFlow2::PathNode sink, Instruction deref, Field f, PointerArithmeticToDerefFlow::PathNode source,
PointerArithmeticToDerefConf conf, string operation, int delta PointerArithmeticToDerefFlow::PathNode sink, Instruction deref, string operation, int delta
where where
conf.hasFlowPath(source, sink) and PointerArithmeticToDerefFlow::hasFlowPath(source, sink) and
isInvalidPointerDerefSink(sink.getNode(), deref, operation) and isInvalidPointerDerefSink(sink.getNode(), deref, operation) and
isConstantSizeOverflowSource(f, source.getNode().asInstruction(), delta) isConstantSizeOverflowSource(f, source.getNode().asInstruction(), delta)
select source, source, sink, select source, source, sink,

View File

@@ -17,7 +17,6 @@
import cpp import cpp
import experimental.semmle.code.cpp.dataflow.ProductFlow import experimental.semmle.code.cpp.dataflow.ProductFlow
import semmle.code.cpp.ir.dataflow.DataFlow3
import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis
import experimental.semmle.code.cpp.semantic.SemanticBound import experimental.semmle.code.cpp.semantic.SemanticBound
import experimental.semmle.code.cpp.semantic.SemanticExprSpecific import experimental.semmle.code.cpp.semantic.SemanticExprSpecific
@@ -204,14 +203,14 @@ predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string o
* A configuration to track flow from a pointer-arithmetic operation found * A configuration to track flow from a pointer-arithmetic operation found
* by `AllocToInvalidPointerConf` to a dereference of the pointer. * by `AllocToInvalidPointerConf` to a dereference of the pointer.
*/ */
class InvalidPointerToDerefConf extends DataFlow3::Configuration { module InvalidPointerToDerefConfig implements DataFlow::ConfigSig {
InvalidPointerToDerefConf() { this = "InvalidPointerToDerefConf" } predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, source, _) }
override predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, source, _) } predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) }
override predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) }
} }
module InvalidPointerToDerefFlow = DataFlow::Make<InvalidPointerToDerefConfig>;
/** /**
* Holds if `pai` is a pointer-arithmetic operation and `source` is a dataflow node with a * Holds if `pai` is a pointer-arithmetic operation and `source` is a dataflow node with a
* pointer-value that is non-strictly upper bounded by `pai + delta`. * pointer-value that is non-strictly upper bounded by `pai + delta`.
@@ -236,13 +235,13 @@ newtype TMergedPathNode =
// The path nodes computed by the first projection of `AllocToInvalidPointerConf` // The path nodes computed by the first projection of `AllocToInvalidPointerConf`
TPathNode1(DataFlow::PathNode p) or TPathNode1(DataFlow::PathNode p) or
// The path nodes computed by `InvalidPointerToDerefConf` // The path nodes computed by `InvalidPointerToDerefConf`
TPathNode3(DataFlow3::PathNode p) or TPathNode3(InvalidPointerToDerefFlow::PathNode p) or
// The read/write that uses the invalid pointer identified by `InvalidPointerToDerefConf`. // The read/write that uses the invalid pointer identified by `InvalidPointerToDerefConf`.
// This one is needed because the sink identified by `InvalidPointerToDerefConf` is the // This one is needed because the sink identified by `InvalidPointerToDerefConf` is the
// pointer, but we want to raise an alert at the dereference. // pointer, but we want to raise an alert at the dereference.
TPathNodeSink(Instruction i) { TPathNodeSink(Instruction i) {
exists(DataFlow::Node n | exists(DataFlow::Node n |
any(InvalidPointerToDerefConf conf).hasFlow(_, n) and InvalidPointerToDerefFlow::hasFlow(_, n) and
isInvalidPointerDerefSink(n, i, _) isInvalidPointerDerefSink(n, i, _)
) )
} }
@@ -252,7 +251,7 @@ class MergedPathNode extends TMergedPathNode {
final DataFlow::PathNode asPathNode1() { this = TPathNode1(result) } final DataFlow::PathNode asPathNode1() { this = TPathNode1(result) }
final DataFlow3::PathNode asPathNode3() { this = TPathNode3(result) } final InvalidPointerToDerefFlow::PathNode asPathNode3() { this = TPathNode3(result) }
final Instruction asSinkNode() { this = TPathNodeSink(result) } final Instruction asSinkNode() { this = TPathNodeSink(result) }
@@ -280,7 +279,7 @@ class PathNode1 extends MergedPathNode, TPathNode1 {
class PathNode3 extends MergedPathNode, TPathNode3 { class PathNode3 extends MergedPathNode, TPathNode3 {
override string toString() { override string toString() {
exists(DataFlow3::PathNode p | exists(InvalidPointerToDerefFlow::PathNode p |
this = TPathNode3(p) and this = TPathNode3(p) and
result = p.toString() result = p.toString()
) )
@@ -324,7 +323,9 @@ query predicate edges(MergedPathNode node1, MergedPathNode node2) {
* Holds if `p1` is a sink of `AllocToInvalidPointerConf` and `p2` is a source * Holds if `p1` is a sink of `AllocToInvalidPointerConf` and `p2` is a source
* of `InvalidPointerToDerefConf`, and they are connected through `pai`. * of `InvalidPointerToDerefConf`, and they are connected through `pai`.
*/ */
predicate joinOn1(PointerArithmeticInstruction pai, DataFlow::PathNode p1, DataFlow3::PathNode p2) { predicate joinOn1(
PointerArithmeticInstruction pai, DataFlow::PathNode p1, InvalidPointerToDerefFlow::PathNode p2
) {
isSinkImpl(pai, p1.getNode(), _, _) and isSinkImpl(pai, p1.getNode(), _, _) and
invalidPointerToDerefSource(pai, p2.getNode(), _) invalidPointerToDerefSource(pai, p2.getNode(), _)
} }
@@ -334,28 +335,29 @@ predicate joinOn1(PointerArithmeticInstruction pai, DataFlow::PathNode p1, DataF
* that dereferences `p1`. The string `operation` describes whether the `i` is * that dereferences `p1`. The string `operation` describes whether the `i` is
* a `StoreInstruction` or `LoadInstruction`. * a `StoreInstruction` or `LoadInstruction`.
*/ */
predicate joinOn2(DataFlow3::PathNode p1, Instruction i, string operation) { predicate joinOn2(InvalidPointerToDerefFlow::PathNode p1, Instruction i, string operation) {
isInvalidPointerDerefSink(p1.getNode(), i, operation) isInvalidPointerDerefSink(p1.getNode(), i, operation)
} }
predicate hasFlowPath( predicate hasFlowPath(
MergedPathNode source1, MergedPathNode sink, DataFlow3::PathNode source3, MergedPathNode source1, MergedPathNode sink, InvalidPointerToDerefFlow::PathNode source3,
PointerArithmeticInstruction pai, string operation PointerArithmeticInstruction pai, string operation
) { ) {
exists( exists(
AllocToInvalidPointerConf conf1, InvalidPointerToDerefConf conf2, DataFlow3::PathNode sink3, AllocToInvalidPointerConf conf1, InvalidPointerToDerefFlow::PathNode sink3,
DataFlow::PathNode sink1 DataFlow::PathNode sink1
| |
conf1.hasFlowPath(source1.asPathNode1(), _, sink1, _) and conf1.hasFlowPath(source1.asPathNode1(), _, sink1, _) and
joinOn1(pai, sink1, source3) and joinOn1(pai, sink1, source3) and
conf2.hasFlowPath(source3, sink3) and InvalidPointerToDerefFlow::hasFlowPath(source3, sink3) and
joinOn2(sink3, sink.asSinkNode(), operation) joinOn2(sink3, sink.asSinkNode(), operation)
) )
} }
from from
MergedPathNode source, MergedPathNode sink, int k, string kstr, DataFlow3::PathNode source3, MergedPathNode source, MergedPathNode sink, int k, string kstr,
PointerArithmeticInstruction pai, string operation, Expr offset, DataFlow::Node n InvalidPointerToDerefFlow::PathNode source3, PointerArithmeticInstruction pai, string operation,
Expr offset, DataFlow::Node n
where where
hasFlowPath(source, sink, source3, pai, operation) and hasFlowPath(source, sink, source3, pai, operation) and
invalidPointerToDerefSource(pai, source3.getNode(), k) and invalidPointerToDerefSource(pai, source3.getNode(), k) and

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries name: codeql/cpp-queries
version: 0.5.5-dev version: 0.5.6-dev
groups: groups:
- cpp - cpp
- queries - queries

View File

@@ -1,14 +1,10 @@
import cpp import cpp
import semmle.code.cpp.dataflow.new.DataFlow import semmle.code.cpp.dataflow.new.DataFlow
class LiteralToGethostbynameConfiguration extends DataFlow::Configuration { module LiteralToGethostbynameConfig implements DataFlow::ConfigSig {
LiteralToGethostbynameConfiguration() { this = "LiteralToGethostbynameConfiguration" } predicate isSource(DataFlow::Node source) { source.asIndirectExpr(1) instanceof StringLiteral }
override predicate isSource(DataFlow::Node source) { predicate isSink(DataFlow::Node sink) {
source.asIndirectExpr(1) instanceof StringLiteral
}
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc | exists(FunctionCall fc |
sink.asIndirectExpr(1) = fc.getArgument(0) and sink.asIndirectExpr(1) = fc.getArgument(0) and
fc.getTarget().hasName("gethostbyname") fc.getTarget().hasName("gethostbyname")
@@ -16,11 +12,11 @@ class LiteralToGethostbynameConfiguration extends DataFlow::Configuration {
} }
} }
from module LiteralToGethostbynameFlow = DataFlow::Make<LiteralToGethostbynameConfig>;
StringLiteral sl, FunctionCall fc, LiteralToGethostbynameConfiguration cfg, DataFlow::Node source,
DataFlow::Node sink from StringLiteral sl, FunctionCall fc, DataFlow::Node source, DataFlow::Node sink
where where
source.asIndirectExpr(1) = sl and source.asIndirectExpr(1) = sl and
sink.asIndirectExpr(1) = fc.getArgument(0) and sink.asIndirectExpr(1) = fc.getArgument(0) and
cfg.hasFlow(source, sink) LiteralToGethostbynameFlow::hasFlow(source, sink)
select sl, fc select sl, fc

View File

@@ -5,12 +5,10 @@ class GetenvSource extends DataFlow::Node {
GetenvSource() { this.asIndirectExpr(1).(FunctionCall).getTarget().hasGlobalName("getenv") } GetenvSource() { this.asIndirectExpr(1).(FunctionCall).getTarget().hasGlobalName("getenv") }
} }
class GetenvToGethostbynameConfiguration extends DataFlow::Configuration { module GetenvToGethostbynameConfig implements DataFlow::ConfigSig {
GetenvToGethostbynameConfiguration() { this = "GetenvToGethostbynameConfiguration" } predicate isSource(DataFlow::Node source) { source instanceof GetenvSource }
override predicate isSource(DataFlow::Node source) { source instanceof GetenvSource } predicate isSink(DataFlow::Node sink) {
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc | exists(FunctionCall fc |
sink.asIndirectExpr(1) = fc.getArgument(0) and sink.asIndirectExpr(1) = fc.getArgument(0) and
fc.getTarget().hasName("gethostbyname") fc.getTarget().hasName("gethostbyname")
@@ -18,11 +16,11 @@ class GetenvToGethostbynameConfiguration extends DataFlow::Configuration {
} }
} }
from module GetenvToGethostbynameFlow = DataFlow::Make<GetenvToGethostbynameConfig>;
Expr getenv, FunctionCall fc, GetenvToGethostbynameConfiguration cfg, DataFlow::Node source,
DataFlow::Node sink from Expr getenv, FunctionCall fc, DataFlow::Node source, DataFlow::Node sink
where where
source.asIndirectExpr(1) = getenv and source.asIndirectExpr(1) = getenv and
sink.asIndirectExpr(1) = fc.getArgument(0) and sink.asIndirectExpr(1) = fc.getArgument(0) and
cfg.hasFlow(source, sink) GetenvToGethostbynameFlow::hasFlow(source, sink)
select getenv, fc select getenv, fc

View File

@@ -1,17 +1,15 @@
import cpp import cpp
import semmle.code.cpp.dataflow.new.DataFlow import semmle.code.cpp.dataflow.new.DataFlow
class EnvironmentToFileConfiguration extends DataFlow::Configuration { module EnvironmentToFileConfig implements DataFlow::ConfigSig {
EnvironmentToFileConfiguration() { this = "EnvironmentToFileConfiguration" } predicate isSource(DataFlow::Node source) {
override predicate isSource(DataFlow::Node source) {
exists(Function getenv | exists(Function getenv |
source.asIndirectExpr(1).(FunctionCall).getTarget() = getenv and source.asIndirectExpr(1).(FunctionCall).getTarget() = getenv and
getenv.hasGlobalName("getenv") getenv.hasGlobalName("getenv")
) )
} }
override predicate isSink(DataFlow::Node sink) { predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc | exists(FunctionCall fc |
sink.asIndirectExpr(1) = fc.getArgument(0) and sink.asIndirectExpr(1) = fc.getArgument(0) and
fc.getTarget().hasGlobalName("fopen") fc.getTarget().hasGlobalName("fopen")
@@ -19,11 +17,11 @@ class EnvironmentToFileConfiguration extends DataFlow::Configuration {
} }
} }
from module EnvironmentToFileFlow = DataFlow::Make<EnvironmentToFileConfig>;
Expr getenv, Expr fopen, EnvironmentToFileConfiguration config, DataFlow::Node source,
DataFlow::Node sink from Expr getenv, Expr fopen, DataFlow::Node source, DataFlow::Node sink
where where
source.asIndirectExpr(1) = getenv and source.asIndirectExpr(1) = getenv and
sink.asIndirectExpr(1) = fopen and sink.asIndirectExpr(1) = fopen and
config.hasFlow(source, sink) EnvironmentToFileFlow::hasFlow(source, sink)
select fopen, "This 'fopen' uses data from $@.", getenv, "call to 'getenv'" select fopen, "This 'fopen' uses data from $@.", getenv, "call to 'getenv'"

View File

@@ -2,18 +2,16 @@ import cpp
import semmle.code.cpp.controlflow.Guards import semmle.code.cpp.controlflow.Guards
import semmle.code.cpp.dataflow.new.TaintTracking import semmle.code.cpp.dataflow.new.TaintTracking
class NetworkToBufferSizeConfiguration extends TaintTracking::Configuration { module NetworkToBufferSizeConfig implements DataFlow::ConfigSig {
NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" } predicate isSource(DataFlow::Node node) {
override predicate isSource(DataFlow::Node node) {
node.asExpr().(FunctionCall).getTarget().hasGlobalName("ntohl") node.asExpr().(FunctionCall).getTarget().hasGlobalName("ntohl")
} }
override predicate isSink(DataFlow::Node node) { predicate isSink(DataFlow::Node node) {
exists(ArrayExpr ae | node.asExpr() = ae.getArrayOffset()) exists(ArrayExpr ae | node.asExpr() = ae.getArrayOffset())
} }
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(Loop loop, LoopCounter lc | exists(Loop loop, LoopCounter lc |
loop = lc.getALoop() and loop = lc.getALoop() and
loop.getControllingExpr().(RelationalOperation).getGreaterOperand() = pred.asExpr() loop.getControllingExpr().(RelationalOperation).getGreaterOperand() = pred.asExpr()
@@ -22,7 +20,7 @@ class NetworkToBufferSizeConfiguration extends TaintTracking::Configuration {
) )
} }
override predicate isSanitizer(DataFlow::Node node) { predicate isBarrier(DataFlow::Node node) {
exists(GuardCondition gc, Variable v | exists(GuardCondition gc, Variable v |
gc.getAChild*() = v.getAnAccess() and gc.getAChild*() = v.getAnAccess() and
node.asExpr() = v.getAnAccess() and node.asExpr() = v.getAnAccess() and
@@ -32,7 +30,9 @@ class NetworkToBufferSizeConfiguration extends TaintTracking::Configuration {
} }
} }
from DataFlow::Node ntohl, DataFlow::Node offset, NetworkToBufferSizeConfiguration conf module NetworkToBufferSizeFlow = TaintTracking::Make<NetworkToBufferSizeConfig>;
where conf.hasFlow(ntohl, offset)
from DataFlow::Node ntohl, DataFlow::Node offset
where NetworkToBufferSizeFlow::hasFlow(ntohl, offset)
select offset, "This array offset may be influenced by $@.", ntohl, select offset, "This array offset may be influenced by $@.", ntohl,
"converted data from the network" "converted data from the network"

View File

@@ -4,12 +4,12 @@ import experimental.semmle.code.cpp.semantic.Semantic
import experimental.semmle.code.cpp.semantic.analysis.RangeUtils import experimental.semmle.code.cpp.semantic.analysis.RangeUtils
import experimental.semmle.code.cpp.semantic.analysis.FloatDelta import experimental.semmle.code.cpp.semantic.analysis.FloatDelta
import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific
import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisImpl
import semmle.code.cpp.ir.IR as IR import semmle.code.cpp.ir.IR as IR
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
module ModulusAnalysisInstantiated = module ModulusAnalysisInstantiated =
ModulusAnalysis<FloatDelta, Bounds, RangeUtil<FloatDelta, CppLangImpl>>; ModulusAnalysis<FloatDelta, ConstantBounds, RangeUtil<FloatDelta, CppLangImpl>>;
class ModulusAnalysisTest extends InlineExpectationsTest { class ModulusAnalysisTest extends InlineExpectationsTest {
ModulusAnalysisTest() { this = "ModulusAnalysisTest" } ModulusAnalysisTest() { this = "ModulusAnalysisTest" }

View File

@@ -119,6 +119,7 @@ int test9(int x, int y) {
} }
range(x); // $ range=>=4 range(x); // $ range=>=4
} }
range(x); // $ MISSING: range=>=4
return x; return x;
} }

View File

@@ -56,3 +56,8 @@ void f3() {
} }
} }
} }
int unevaluated_test() {
char buffer[100];
return sizeof(buffer) / sizeof(buffer[101]); // GOOD
}

View File

@@ -603,6 +603,11 @@ void test22(bool b, const char* source) {
memcpy(dest, source, n); // GOOD memcpy(dest, source, n); // GOOD
} }
int test23() {
char buffer[100];
return sizeof(buffer) / sizeof(buffer[101]); // GOOD
}
int tests_main(int argc, char *argv[]) int tests_main(int argc, char *argv[])
{ {
long long arr17[19]; long long arr17[19];
@@ -627,6 +632,7 @@ int tests_main(int argc, char *argv[])
test20(); test20();
test21(argc == 0); test21(argc == 0);
test22(argc == 0, argv[0]); test22(argc == 0, argv[0]);
test23();
return 0; return 0;
} }

View File

@@ -1,3 +1,7 @@
## 1.4.5
No user-facing changes.
## 1.4.4 ## 1.4.4
No user-facing changes. No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.4.5
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.4.4 lastReleaseVersion: 1.4.5

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all name: codeql/csharp-solorigate-all
version: 1.4.5-dev version: 1.4.6-dev
groups: groups:
- csharp - csharp
- solorigate - solorigate

View File

@@ -1,3 +1,7 @@
## 1.4.5
No user-facing changes.
## 1.4.4 ## 1.4.4
No user-facing changes. No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.4.5
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.4.4 lastReleaseVersion: 1.4.5

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries name: codeql/csharp-solorigate-queries
version: 1.4.5-dev version: 1.4.6-dev
groups: groups:
- csharp - csharp
- solorigate - solorigate

View File

@@ -1,3 +1,25 @@
## 0.5.5
### New Features
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.
### Major Analysis Improvements
* The main data flow and taint tracking APIs have been changed. The old APIs
remain in place for now and translate to the new through a
backwards-compatible wrapper. If multiple configurations are in scope
simultaneously, then this may affect results slightly. The new API is quite
similar to the old, but makes use of a configuration module instead of a
configuration class.
### Minor Analysis Improvements
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getAssertionIndex`, and `getAssertedParameter` predicates from the `AssertMethod` class.
* Deleted the deprecated `OverridableMethod` and `OverridableAccessor` classes.
* The `unsafe` predicate for `Modifiable` has been extended to cover delegate return types and identify pointer-like types at any nest level. This is relevant for `unsafe` declarations extracted from assemblies.
## 0.5.4 ## 0.5.4
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -1,9 +0,0 @@
---
category: majorAnalysis
---
* The main data flow and taint tracking APIs have been changed. The old APIs
remain in place for now and translate to the new through a
backwards-compatible wrapper. If multiple configurations are in scope
simultaneously, then this may affect results slightly. The new API is quite
similar to the old, but makes use of a configuration module instead of a
configuration class.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `unsafe` predicate for `Modifiable` has been extended to cover delegate return types and identify pointer like types at any nest level. This is relevant for `unsafe` declarations extracted from assemblies.

View File

@@ -1,6 +0,0 @@
---
category: minorAnalysis
---
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getAssertionIndex`, and `getAssertedParameter` predicates from the `AssertMethod` class.
* Deleted the deprecated `OverridableMethod` and `OverridableAccessor` classes.

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.

View File

@@ -0,0 +1,21 @@
## 0.5.5
### New Features
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.
### Major Analysis Improvements
* The main data flow and taint tracking APIs have been changed. The old APIs
remain in place for now and translate to the new through a
backwards-compatible wrapper. If multiple configurations are in scope
simultaneously, then this may affect results slightly. The new API is quite
similar to the old, but makes use of a configuration module instead of a
configuration class.
### Minor Analysis Improvements
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getAssertionIndex`, and `getAssertedParameter` predicates from the `AssertMethod` class.
* Deleted the deprecated `OverridableMethod` and `OverridableAccessor` classes.
* The `unsafe` predicate for `Modifiable` has been extended to cover delegate return types and identify pointer-like types at any nest level. This is relevant for `unsafe` declarations extracted from assemblies.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.5.4 lastReleaseVersion: 0.5.5

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all name: codeql/csharp-all
version: 0.5.5-dev version: 0.5.6-dev
groups: csharp groups: csharp
dbscheme: semmlecode.csharp.dbscheme dbscheme: semmlecode.csharp.dbscheme
extractor: csharp extractor: csharp

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