Compare commits

..

1516 Commits

Author SHA1 Message Date
Philip Ginsbach
8cdd8b6ae0 use instanceof extensions in javascript 2021-05-12 18:58:45 +01:00
Erik Krogh Kristensen
0194af9432 convert field based range pattern to casting based range pattern 2021-05-12 16:49:43 +02:00
Anders Schack-Mulligen
7974e3ad38 Merge pull request #5883 from zbazztian/consider-boxed-booleans-to-avoid-xxe-fps
Consider boxed booleans to avoid false positives for XXE.ql
2021-05-12 12:51:22 +02:00
Sebastian Bauersfeld
b05512a958 Add change notes. 2021-05-12 16:58:24 +07:00
Sebastian Bauersfeld
bf4d88175c Consider boxed booleans to avoid false positives for XXE.ql 2021-05-12 16:40:00 +07:00
Geoffrey White
8f152b7380 Merge pull request #5877 from MathiasVP/detect-more-abs-in-overflow-library
C++: Detect more uses of `abs`
2021-05-12 10:02:12 +01:00
Tom Hvitved
fc121e1cbd Merge pull request #5865 from tamasvajk/feature/remove-base-class-dependency-id
C#: Remove base class from type IDs in trap files
2021-05-12 10:30:31 +02:00
Anders Schack-Mulligen
a247ae4357 Merge pull request #5843 from JLLeitschuh/feat/JLL/improve_kryo_support
[Java] Fix Kryo FP & Kryo 5 Support
2021-05-12 09:52:24 +02:00
Anders Schack-Mulligen
74ae2e0857 Merge pull request #5773 from hvitved/dataflow/aggressive-caching
Data flow: Cache most language-dependent predicates
2021-05-12 09:41:55 +02:00
Tamas Vajk
8e371fd05a Adjust expected IR test file 2021-05-11 21:54:05 +02:00
Mathias Vorreiter Pedersen
948f1d8e34 C++: Add testcase with INTMAX_MIN. 2021-05-11 19:43:21 +02:00
Geoffrey White
d7e560c611 Merge pull request #5767 from ihsinme/ihsinme-patch-268
CPP: Add query for CWE-1126: Declaration of Variable with Unnecessarily Wide Scope
2021-05-11 15:24:25 +01:00
Mathias Vorreiter Pedersen
3e21f479a9 C++: Add change-note. 2021-05-11 14:58:48 +02:00
Tom Hvitved
d66506b0a3 Data flow: Rename {Argument,Parameter}NodeExt to {Arg,Param}Node 2021-05-11 14:40:10 +02:00
Mathias Vorreiter Pedersen
48e783184c C++: Fix false positive by recognizing more absolute value functions in Overflow.qll 2021-05-11 14:30:28 +02:00
Jonathan Leitschuh
0d9a85ca6b Update java/change-notes/2021-05-05-kryo-improvements.md
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-05-11 08:29:50 -04:00
Mathias Vorreiter Pedersen
24d8abd2c2 C++: Add false positive testcase when an absolute value is used in comparison. 2021-05-11 14:27:53 +02:00
CodeQL CI
922b276fac Merge pull request #5728 from asgerf/js/source-sink-queries
Approved by erik-krogh
2021-05-11 05:04:47 -07:00
Tamas Vajk
717070c7e4 Fix/cleanup passed and default arguments values 2021-05-11 13:11:35 +02:00
yoff
a7f97895ac Merge pull request #5863 from erik-krogh/printReg
JS: add printAst.ql support for regular expressions
2021-05-11 12:45:49 +02:00
yoff
0e5a2c4573 Merge pull request #5442 from jorgectf/jorgectf/python/redos
Python: Add Regular Expression Injection query
2021-05-11 12:11:35 +02:00
yoff
549c9eee1a Merge pull request #5739 from RasmusWL/share-sensitive-data-modeling
Python/JS: Share sensitive data modeling
2021-05-11 11:53:59 +02:00
CodeQL CI
a87731115a Merge pull request #5860 from max-schaefer/js/improve-sql-modelling
Approved by asgerf
2021-05-11 02:24:52 -07:00
CodeQL CI
beb66fc4db Merge pull request #5719 from asgerf/js/nestjs
Approved by esbena
2021-05-11 02:08:27 -07:00
Anders Schack-Mulligen
744c495ac2 Merge pull request #5824 from JLLeitschuh/feat/JLL/guava_first_non_null
[Java] Add support for com.google.common.base.MoreObjects#firstNonNull
2021-05-11 09:42:20 +02:00
AlexDenisov
2905bb8b9a Merge pull request #5861 from AlexDenisov/alexdenisov/adjust-user-defined-literals-test
C++: Adjust user-defined literals test' expectations
2021-05-11 09:31:54 +02:00
Anders Schack-Mulligen
7d6a497136 Merge pull request #5857 from dbartol/container/work
Java: Fix QLDoc for `Container.toString()`
2021-05-11 08:37:41 +02:00
Dave Bartolomeo
f85aff869c Java: Fix PR feedback 2021-05-10 16:37:23 -04:00
Mathias Vorreiter Pedersen
5016c6436a Merge pull request #5859 from MathiasVP/fix-fp-in-comparison-with-wider-type
C++: Fix false positive in `cpp/comparison-with-wider-type`
2021-05-10 17:58:31 +02:00
Jonathan Leitschuh
d27316eb3e Apply suggestions from code review
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-05-10 11:55:31 -04:00
Chris Smowton
0afe22d60c Merge pull request #5710 from p0wn4j/jsch-os-injection
[Java] CWE-078: Add JSch lib OS Command Injection sink
2021-05-10 16:12:00 +01:00
Tamas Vajk
dd86da3f24 C#: Remove base class from type IDs in trap files 2021-05-10 17:06:10 +02:00
Tamas Vajk
31ac6442e8 C#: Fix default parameter value generation in case of error symbols 2021-05-10 17:03:08 +02:00
Mathias Vorreiter Pedersen
d55db836cb C++: Remove implied conjunct. 2021-05-10 16:13:54 +02:00
Tom Hvitved
498f9b2547 Merge pull request #5848 from hvitved/csharp/trap-key-escape
C#: Escape IDs in TRAP label definitions
2021-05-10 16:13:13 +02:00
Mathias Vorreiter Pedersen
51d04cb5b3 C++: Correct test annotation. 2021-05-10 15:30:35 +02:00
Mathias Vorreiter Pedersen
c0b65314be C++: Fix false positive by restricting _both_ the old (unconverted) expression _and_ all of the conversions. 2021-05-10 15:18:42 +02:00
Mathias Vorreiter Pedersen
c7cd75437f C++: Add testcase demonstrating false positive from conversions. 2021-05-10 14:58:33 +02:00
CodeQL CI
a3d17a1437 Merge pull request #5769 from erik-krogh/libXss
Approved by esbena
2021-05-10 05:58:07 -07:00
yoff
78370cf63f Update python/ql/src/experimental/semmle/python/frameworks/Stdlib.qll 2021-05-10 14:53:40 +02:00
Erik Krogh Kristensen
504c34ed2c use shouldPrint to filter out regular expressions from other files 2021-05-10 14:51:13 +02:00
Erik Krogh Kristensen
d6f9e37e39 add printAst.ql support for regular expressions 2021-05-10 13:31:00 +02:00
ihsinme
9e5a38debd Update DeclarationOfVariableWithUnnecessarilyWideScope.expected 2021-05-10 14:17:40 +03:00
ihsinme
d3c6093f37 Update test.c 2021-05-10 14:16:38 +03:00
ihsinme
c8f2937df9 Update DeclarationOfVariableWithUnnecessarilyWideScope.ql 2021-05-10 14:16:11 +03:00
Tom Hvitved
7f1f2b4dd3 C#: Fix GetHashCode/Equals on EscapingTextWriter 2021-05-10 13:05:51 +02:00
Alex Denisov
dcdd54593e C++: Adjust user-defined literals test' expectations 2021-05-10 13:03:40 +02:00
Max Schaefer
8f91e9eba0 JavaScript: Model chaining calls in sqlite3. 2021-05-10 10:58:58 +01:00
Asger F
f4e636dcd6 Update javascript/ql/src/semmle/javascript/frameworks/ClassValidator.qll
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-05-10 10:08:10 +01:00
CodeQL CI
097b6e5e33 Merge pull request #5794 from erik-krogh/rxPipe
Approved by asgerf
2021-05-10 02:06:34 -07:00
Erik Krogh Kristensen
d913668943 move hasPathWithoutUnmatchedReturn to Configuration.qll 2021-05-10 10:55:33 +02:00
Erik Krogh Kristensen
b4e35f54d9 fix typo 2021-05-10 10:48:43 +02:00
Erik Krogh Kristensen
646bf99489 rewrite the qhelp to focus more on documenting unsafe functions 2021-05-10 10:48:40 +02:00
Asger Feldthaus
df5eab33f9 JS: Update relevantTaintSource() 2021-05-10 09:43:33 +01:00
CodeQL CI
b1f28afcbd Merge pull request #5741 from asgerf/js/more-cheat-sheet
Approved by erik-krogh
2021-05-10 01:34:56 -07:00
Mathias Vorreiter Pedersen
474b337eeb C++: Add change-note. 2021-05-10 10:22:44 +02:00
Mathias Vorreiter Pedersen
c91ed80e6c C++: Fix false positive by computing range of the converted expression. 2021-05-10 10:12:43 +02:00
Mathias Vorreiter Pedersen
7ac7830973 C++: Add testcase with false positive involving a conversion on the large-expression side of the comparison. 2021-05-10 10:11:31 +02:00
Erik Krogh Kristensen
3fe5dd0f35 add comment about filtering away jQuery from the source 2021-05-10 10:05:18 +02:00
Tom Hvitved
8b465e86e0 Merge pull request #5820 from hvitved/csharp/cfg/constructor-same-compilation
C#: Improve CFG for constructors when there are multiple implementations
2021-05-10 09:23:16 +02:00
Dave Bartolomeo
d9f243d18a Java: Fix QLDoc for Container.toString()
Fixes #5828

The QLDoc was just too specific about the default implementation. I've improved the wording.
2021-05-08 11:14:02 -04:00
Hayk Andriasyan
fd88b72101 Delete JSchOSInjection.qhelp 2021-05-08 12:51:15 +04:00
Geoffrey White
65ac5b862d Merge pull request #5847 from MathiasVP/improve-wrong-in-detecting-and-handling-memory-allocation-errors
Improve wrong in detecting and handling memory allocation errors
2021-05-07 17:39:04 +01:00
Mathias Vorreiter Pedersen
2241d7b359 Merge pull request #5616 from geoffw0/unsigneddiff2
C++: Improve cpp/unsigned-difference-expression-compared-zero
2021-05-07 17:58:53 +02:00
Geoffrey White
75edcf0b4f Merge branch 'main' into unsigneddiff2 2021-05-07 16:35:16 +01:00
Geoffrey White
69468514f0 Update cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-05-07 16:26:42 +01:00
Geoffrey White
91be483c57 Update cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-05-07 16:26:36 +01:00
Geoffrey White
fc96c1c400 Update cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-05-07 16:26:23 +01:00
Geoffrey White
5db6abe2f4 Update cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-05-07 16:22:48 +01:00
Geoffrey White
894f5d523c Update cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-05-07 16:19:48 +01:00
Felicity Chapman
10e76ff28f Merge pull request #5831 from github/3893-code-scanning
Update CodeQL CLI article to use different query suite example
2021-05-07 12:37:47 +01:00
Mathias Vorreiter Pedersen
fc7d9c2c09 C++: Fix missing result by properly specifying that the function with unknown code actually didn't throw an exception. 2021-05-07 12:34:38 +02:00
Mathias Vorreiter Pedersen
90e8368258 C++: Properly handle conversions in convertedExprMayThrow. This recursive implementation idea is stolen from convertedExprMightOverflow in SimpleRangeAnalysis. 2021-05-07 12:31:43 +02:00
Mathias Vorreiter Pedersen
7adb7b67f2 C++: Add false positive testcase involving conversions. 2021-05-07 12:19:19 +02:00
Anders Schack-Mulligen
8783746516 Merge pull request #5774 from atorralba/promote-xpath-injection
Java: Promote XPath Injection query from experimental
2021-05-07 12:04:49 +02:00
Mathias Vorreiter Pedersen
88e6cbaacd C++: Include Assignments in exprMayThrow and accept test changes. 2021-05-07 11:49:25 +02:00
Mathias Vorreiter Pedersen
80d41d9fe5 C++: Add false positive testcase involving assignments. 2021-05-07 11:48:09 +02:00
Tom Hvitved
ca89560849 C#: Remove unnecessary ! 2021-05-07 11:42:53 +02:00
Mathias Vorreiter Pedersen
08fa611700 C++: Avoid calling SwitchCase.getAStmt for performance reasons. This turns out to not be needed as the statements inside the switch case will get picked up by the BlockStmt.getAStmt case already. 2021-05-07 11:18:50 +02:00
Tony Torralba
2a501956b3 Mark a MISSING test result as suggested in code review 2021-05-07 11:17:51 +02:00
Tony Torralba
b69be30b88 Fix imports as suggested in code review 2021-05-07 11:07:06 +02:00
Erik Krogh Kristensen
b53759c5a0 corrections after code review 2021-05-06 22:49:25 +02:00
CodeQL CI
7a7586488a Merge pull request #5833 from erik-krogh/filterStep
Approved by esbena
2021-05-06 13:47:23 -07:00
Erik Krogh Kristensen
be69c3a458 Apply suggestions from code review
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-05-06 21:59:35 +02:00
Erik Krogh Kristensen
2d1ba59e6d Apply suggestions from code review
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-05-06 21:55:30 +02:00
Aditya Sharad
68e53054c6 Merge pull request #5840 from github/henrymercer/update-code-scanning-selectors
Update code scanning selectors to include summary metrics and `@kind alert` aliases
2021-05-06 11:51:12 -07:00
Tom Hvitved
fab8400ecd C#: Escape IDs in TRAP label definitions 2021-05-06 19:12:13 +02:00
Mathias Vorreiter Pedersen
856d512aa6 C++: Simplify noThrowInTryBlock. 2021-05-06 18:36:09 +02:00
Mathias Vorreiter Pedersen
7c1720a1d1 C++: Remove NoThrowAllocator and inline its (corrected) definition in ThrowingAllocator. 2021-05-06 18:02:05 +02:00
Mathias Vorreiter Pedersen
5437bd7a41 C++: Fix annotation. 2021-05-06 17:57:57 +02:00
Shati Patel
cf80773453 Merge pull request #5830 from Marcono1234/marcono1234/guides-link-updates
Docs: Use GitHub links for guides, improve formatting
2021-05-06 16:44:11 +01:00
Mathias Vorreiter Pedersen
d1eb774737 C++: Remove implied conjunction. 2021-05-06 17:03:42 +02:00
Mathias Vorreiter Pedersen
e0606d61b6 C++: Fix qldoc. 2021-05-06 16:58:49 +02:00
Mathias Vorreiter Pedersen
c12837cff0 C++: Fix false negative. 2021-05-06 16:57:09 +02:00
Mathias Vorreiter Pedersen
7b8a51f995 C++: Add test with missing result. 2021-05-06 16:56:11 +02:00
Mathias Vorreiter Pedersen
47a419a5f1 C++: Respond to review comments. First: Avoid using locations to detect constructor and destructor calls. Second: Include missing statements in stmtMayThrow. 2021-05-06 16:37:26 +02:00
Mathias Vorreiter Pedersen
4463293dc4 C++: Move common code from NewExpr and NewArrayExpr into the NewOrNewArrayExpr class. 2021-05-06 16:35:41 +02:00
Tony Torralba
f16605b3c1 Apply suggestions from code review
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2021-05-06 15:17:55 +02:00
Mathias Vorreiter Pedersen
167dc86f7a C++: Accept test changes. 2021-05-06 14:36:35 +02:00
Mathias Vorreiter Pedersen
95e65dec8f C++: Make sure a CatchBlock that catches a const std::bad_alloc& is also a BadAllocCatchBlock. 2021-05-06 14:35:27 +02:00
Mathias Vorreiter Pedersen
42b8f923be C++: Call noexcept constructor instead. 2021-05-06 14:30:43 +02:00
Mathias Vorreiter Pedersen
6cdef782c8 Merge branch 'main' into improve-wrong-in-detecting-and-handling-memory-allocation-errors 2021-05-06 13:37:21 +02:00
Mathias Vorreiter Pedersen
420215931c C++: Rename query. 2021-05-06 13:35:08 +02:00
Mathias Vorreiter Pedersen
d3576b9c92 C++: Accept test changes. 2021-05-06 13:29:28 +02:00
Mathias Vorreiter Pedersen
56d7342398 C++: Improve the cpp/detect-and-handle-memory-allocation-errors query. 2021-05-06 13:29:20 +02:00
Mathias Vorreiter Pedersen
58f3048808 C++: Add more testcases. 2021-05-06 13:15:34 +02:00
Tony Torralba
f1fab854c4 Fix tests for XXE, introduced a dependency with jaxen 2021-05-06 12:11:55 +02:00
Erik Krogh Kristensen
3815797dda add sanitizers from DOM and jQuery queries 2021-05-06 11:05:03 +02:00
Erik Krogh Kristensen
8ba5bddae8 add jQuery options objects as sources 2021-05-06 11:05:02 +02:00
Erik Krogh Kristensen
5c37e6a435 add change note 2021-05-06 11:05:02 +02:00
Erik Krogh Kristensen
7ef641e7b2 add qhelp 2021-05-06 11:05:02 +02:00
Erik Krogh Kristensen
ee0140e704 share code between unsafe-shell and unsafe-html queries 2021-05-06 11:05:02 +02:00
Erik Krogh Kristensen
23908f9ec2 remove flowpaths that has a returns without a matching call 2021-05-06 11:05:02 +02:00
Erik Krogh Kristensen
6e754c70aa add test for js/html-constructed-from-input 2021-05-06 11:05:02 +02:00
Erik Krogh Kristensen
e86a3b5e57 add js/html-constructed-from-input query 2021-05-06 11:04:49 +02:00
Erik Krogh Kristensen
a400a1e9d4 split the markdown steps into a separate class 2021-05-06 10:44:39 +02:00
Tony Torralba
76468559ba Add safe example for dom4j 2021-05-06 10:17:25 +02:00
Tony Torralba
926fedb7fb Update java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.java
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-05-06 09:18:50 +02:00
Tony Torralba
00a7576679 Rename XPath Injection test file 2021-05-06 09:18:50 +02:00
Tony Torralba
8af7f4a484 New sinks and test cases 2021-05-06 09:18:49 +02:00
Tony Torralba
ccb3ea4453 Fix XPath Injection tests classpath 2021-05-06 09:18:49 +02:00
Tony Torralba
509fc8a640 Add missing docs to stubs 2021-05-06 09:18:49 +02:00
Tony Torralba
26c3ff2cee Move from experimental to standard 2021-05-06 09:18:49 +02:00
Tony Torralba
215118c7ea Fixes in QLDocs and imports 2021-05-06 09:18:49 +02:00
Tony Torralba
720b5d6da3 Refactored sto use CSV sink model. Also, added more sinks 2021-05-06 09:18:49 +02:00
Tony Torralba
ab62bb66f4 Consider second parameter of Node.selectNodes 2021-05-06 09:18:49 +02:00
Tony Torralba
d72dd9b861 javax.xml.xpath.XPath is an interface 2021-05-06 09:18:49 +02:00
Tony Torralba
2bb2baf6f7 Support more methods that evaluate XPath expressions 2021-05-06 09:18:49 +02:00
Tony Torralba
3705970bfd Refactored XPath.qll to remove redundant classes and restrict visibility 2021-05-06 09:18:49 +02:00
Tony Torralba
d739a8cac2 Moved configuration from XPath.qll back to XPath Injection query 2021-05-06 09:18:48 +02:00
Tony Torralba
ee269fbc69 Added missing doc comments 2021-05-06 09:18:48 +02:00
Tony Torralba
fb3e56eac8 Fix imports and stubs so that tests pass 2021-05-06 09:18:48 +02:00
Tony Torralba
a62997463f Remove unused imports; use set literals in hasName 2021-05-06 09:18:48 +02:00
Tony Torralba
ed5619498c WIP: XPath Injection promotion 2021-05-06 09:18:48 +02:00
Jonathan Leitschuh
67e9f06304 [Java] Fix Kryo FP & Kryo 5 Support
Closes #4992
2021-05-05 17:38:34 -04:00
ihsinme
976ccda135 Update DeclarationOfVariableWithUnnecessarilyWideScope.ql 2021-05-05 23:34:21 +03:00
ihsinme
b277082462 Update DeclarationOfVariableWithUnnecessarilyWideScope.qhelp 2021-05-05 23:28:04 +03:00
Henry Mercer
a3c57c43c8 Code Scanning selectors: Include summary metrics 2021-05-05 16:38:39 +01:00
Henry Mercer
74c9994305 Code Scanning selectors: Add alert aliases 2021-05-05 16:36:39 +01:00
Shati Patel
059a5f35fa Merge pull request #5812 from mario-campos/patch-1
Add React Native to JavaScript frameworks docs
2021-05-05 16:03:41 +01:00
Erik Krogh Kristensen
4ac21e9f3f make the .filter step more precise 2021-05-05 14:53:09 +02:00
CodeQL CI
69cd9dfb7d Merge pull request #5826 from erik-krogh/moreLib
Approved by esbena
2021-05-05 04:40:49 -07:00
Felicity Chapman
8b2009cfb1 Minor updates to qhelp file 2021-05-05 12:36:29 +01:00
Erik Krogh Kristensen
ab53f3b380 add array.filter() as a taint-step 2021-05-05 12:03:14 +02:00
Erik Krogh Kristensen
e333267e69 require that the factory function is in a main module file 2021-05-05 12:00:38 +02:00
Erik Krogh Kristensen
fc3f5adbbb more source code examples in PackageExports.qll 2021-05-05 11:48:41 +02:00
Erik Krogh Kristensen
28eef264e5 recognize the define(..) call in PackageExports.qll 2021-05-05 11:23:25 +02:00
Jonas Jensen
390ee3a6b8 Merge pull request #5829 from MathiasVP/reorder-get-instruction-opcode
C++: Reorder getInstructionOpcode
2021-05-05 11:13:15 +02:00
Erik Krogh Kristensen
3ca670146e remove outdated comment 2021-05-05 11:10:45 +02:00
Rasmus Wriedt Larsen
dc4a0c1d38 Python/JS: Fix typo 2021-05-05 10:13:54 +02:00
Mathias Vorreiter Pedersen
066cdb55d7 C++: Add qldoc explaining column order. 2021-05-05 09:30:12 +02:00
Mathias Vorreiter Pedersen
f03c99ab03 Merge pull request #5835 from hmakholm/hmakholm/pr/blowup-fix
CPP: fix semi-unused variables in WrongInDetectingAndHandlingMemoryAllocationErrors.q
2021-05-05 08:15:37 +02:00
Henning Makholm
4964ce347b CPP: fix semi-unused variables in WrongInDetectingAndHandlingMemoryAllocationErrors.ql
The fact that `aex` and `it` was each used in just one disjunct of the
exists() body caused the optimizer to generate perfectly horrible
code, including a pointless cartesian product between them that caused
the evaluation to blow up.

Fix it such that each variable is logically scoped. That makes the
compiler much happier.
2021-05-05 02:31:11 +02:00
CodeQL CI
95f26aadd3 Merge pull request #5681 from yoff/python-support-pathlib
Approved by tausbn
2021-05-04 09:20:24 -07:00
Robert Marsh
5ee74d269a Merge pull request #5822 from MathiasVP/more-cwe-tags-in-code-scanning
C++: Add more CWE tags to queries in the Code Scanning suite
2021-05-04 09:01:00 -07:00
Mathias Vorreiter Pedersen
d5793418f9 C++: Remove parent CWE tags. 2021-05-04 14:39:23 +02:00
CodeQL CI
b160badbf6 Merge pull request #5768 from erik-krogh/cacheMore
Approved by esbena
2021-05-04 04:16:15 -07:00
Felicity Chapman
616a57d6d4 Update article with code scanning example 2021-05-04 12:11:18 +01:00
Tamás Vajk
05c045070e Merge pull request #5810 from tamasvajk/feature/culture
C#: Use invariant culture in the extractor
2021-05-04 13:09:38 +02:00
Mathias Vorreiter Pedersen
568724bffd C#: Fix getInstructionOpcode to make sure IRConstruction.qll compiles for C#. 2021-05-04 13:00:40 +02:00
Marcono1234
ab90fe18fd Docs: Use GitHub links for guides, improve formatting 2021-05-04 12:35:23 +02:00
Mathias Vorreiter Pedersen
ded377bcd2 C++: Reorder getInstructionOpcode to produce better RA. 2021-05-04 12:13:34 +02:00
Tamas Vajk
c547907784 C#: Use invariant culture in the extractor 2021-05-04 11:17:33 +02:00
Anders Schack-Mulligen
5bcf810a7c Merge pull request #5821 from JarLob/patch-1
Update UncaughtServletException.qhelp
2021-05-04 10:39:02 +02:00
Anders Schack-Mulligen
9ee9186a1a Merge pull request #5825 from github/yo-h/java-diagnostic-queries
Java: split extractor diagnostics query into two
2021-05-04 10:12:32 +02:00
Erik Krogh Kristensen
aaf754ebf5 recognize more library input 2021-05-04 10:06:14 +02:00
CodeQL CI
6931d9a6f7 Merge pull request #5785 from edvraa/httponlyjs
Approved by esbena
2021-05-03 23:14:26 -07:00
yo-h
edf1a90161 Java: split extractor diagnostics query into two 2021-05-03 20:27:07 -04:00
edvraa
6fa2f1e653 update test message 2021-05-04 00:32:01 +03:00
Jonathan Leitschuh
dfad1fc740 [Java] Add support for com.google.common.base.MoreObjects#firstNonNull 2021-05-03 12:58:00 -04:00
Taus
483199878d Merge pull request #5793 from RasmusWL/fix-qldoc
Python: Minor fix to Django RawSQL QLDoc
2021-05-03 18:18:02 +02:00
Mathias Vorreiter Pedersen
2912c2e7f5 C++: Add more CWE tags to queries in the code scanning suite. 2021-05-03 16:58:47 +02:00
Edwin
27c680e28b Apply suggestions from code review
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-05-03 16:41:09 +03:00
Jaroslav Lobačevski
38bce39baa Update UncaughtServletException.qhelp
There is no single word in https://cwe.mitre.org/data/definitions/600.html about possible DoS or unexpected state.
2021-05-03 15:06:57 +03:00
edvraa
cef845ac47 Support string expressions 2021-05-03 13:46:56 +03:00
edvraa
ea38f0d3bd a new test for simple flow 2021-05-03 12:19:05 +03:00
edvraa
000826af11 typo 2021-05-03 12:18:43 +03:00
Tom Hvitved
182b2d0457 C#: Improve CFG for constructors when there are multiple implementations 2021-05-03 10:46:36 +02:00
Tom Hvitved
633f228dc2 C#: Add CFG tests for partial classes 2021-05-03 10:23:29 +02:00
Tom Hvitved
bb1cb73675 Merge pull request #5795 from hvitved/csharp/implicit-constructor-inits
C#: Extract implicit constructor initializer calls
2021-05-03 10:21:04 +02:00
Tom Hvitved
b77b3da8d6 C#: Add change note 2021-05-03 09:40:13 +02:00
Jonas Jensen
c05ef1225c Merge pull request #5803 from MathiasVP/no-magic-in-getUnspecifiedType
C++: Add nomagic to getUnspecifiedType
2021-05-03 09:03:58 +02:00
edvraa
65183cde80 Move to experimental 2021-05-03 09:59:52 +03:00
edvraa
bd99114cd6 Comments added 2021-05-03 09:55:04 +03:00
edvraa
a24c1c8114 fix comment 2021-05-03 00:36:38 +03:00
edvraa
fa94fedfc3 simple dataflow for sensitive name 2021-05-03 00:36:26 +03:00
edvraa
97bc7e38d2 check for sensitive property name 2021-05-03 00:31:29 +03:00
edvraa
7ab91bb185 Inline getOptionsArgument 2021-05-03 00:09:15 +03:00
ihsinme
bb97507ebc Update test.c 2021-05-02 22:59:56 +03:00
ihsinme
21f43252e6 Update DeclarationOfVariableWithUnnecessarilyWideScope.expected 2021-05-02 22:59:04 +03:00
ihsinme
0935c5a0f2 Update DeclarationOfVariableWithUnnecessarilyWideScope.ql 2021-05-02 22:58:30 +03:00
ihsinme
8c3980d80b Update cpp/ql/src/experimental/Security/CWE/CWE-1126/DeclarationOfVariableWithUnnecessarilyWideScope.c
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-05-02 22:54:43 +03:00
Mario Campos
ae857db657 Add React Native to JavaScript frameworks
According to @asgerf, React Native is already supported 🎉
2021-04-30 10:47:08 -05:00
Chris Smowton
b2c0259197 Merge pull request #5631 from haby0/UseOfLessTrustedSource
[Java] CWE-348: Using a client-supplied IP address in a security check
2021-04-30 15:20:53 +01:00
haby0
fdcc517b9f UseOfLessTrustedSource -> ClientSuppliedIpUsedInSecurityCheck" 2021-04-30 17:43:34 +08:00
haby0
f41301f8f5 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.java
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-30 16:55:17 +08:00
haby0
0691cac5ab Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSourceLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-30 16:54:41 +08:00
haby0
8142810455 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-30 16:54:28 +08:00
Tom Hvitved
ecd40e5cae Merge pull request #5808 from intrigus-lgtm/fix-lambda-typos
Fix typo.
2021-04-30 09:08:28 +02:00
haby0
711a74c9c9 Eliminate false positives\ 2021-04-30 10:31:40 +08:00
intrigus
08731fc6cf Fix typo. 2021-04-29 20:26:34 +02:00
Jorge
bd4b189373 Polish documentation consistency
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-04-29 16:26:28 +02:00
Chris Smowton
ad9ea40954 Merge pull request #5597 from intrigus-lgtm/java/jwt-insecure-parse
[Java] JWT without signature check.
2021-04-29 14:41:11 +01:00
Geoffrey White
c4069362ce Merge pull request #5804 from MathiasVP/improve-detect-and-handle-memory-allocation-errors
C++: Improve qhelp and tests for cpp/detect-and-handle-memory-allocation-errors
2021-04-29 14:34:41 +01:00
haby0
e813257431 use hardCode 2021-04-29 21:23:52 +08:00
Anders Schack-Mulligen
404a6c1506 Merge pull request #5805 from smowton/smowton/admin/spring-setter-method-docs
Document `SpringProperty::getSetterMethod`.
2021-04-29 15:10:58 +02:00
Anders Schack-Mulligen
c78285e557 Merge pull request #5784 from Marcono1234/marcono1234/switch-expr-stmt-parent
Java: Add StmtParent as superclass of SwitchExpr
2021-04-29 15:02:05 +02:00
Tom Hvitved
c3890a9435 C#: Adjust CFG for instance constructors 2021-04-29 14:05:42 +02:00
Tom Hvitved
ee62522c51 C#: Extract implicit constructor initializer calls 2021-04-29 14:05:42 +02:00
Mathias Vorreiter Pedersen
c67ab8f1f0 C++: Respond to review comments. 2021-04-29 14:01:04 +02:00
Chris Smowton
2787c2f874 Document SpringProperty::getSetterMethod. 2021-04-29 12:28:26 +01:00
Mathias Vorreiter Pedersen
e81b40978e C++: Improve the description tag. 2021-04-29 12:10:29 +02:00
Arthur Baars
6693c5bdd0 Merge pull request #5395 from tausbn/python-share-typetracker
Python: Make the type tracking implementation shareable
2021-04-29 12:06:12 +02:00
Mathias Vorreiter Pedersen
9e39b08325 C++: Improve the qhelp for cpp/detect-and-handle-memory-allocation-errors. 2021-04-29 11:58:36 +02:00
Mathias Vorreiter Pedersen
44de127bff C++: Extend and improve the testcases for cpp/detect-and-handle-memory-allocation-errors. 2021-04-29 11:57:43 +02:00
Rasmus Wriedt Larsen
af0723c185 Merge pull request #5656 from asgerf/js/files-diagnostics
JS: Add file diagnostics queries
2021-04-29 11:53:11 +02:00
CodeQL CI
84d43946de Merge pull request #5755 from RasmusWL/non-alert-data-part1
Approved by tausbn
2021-04-29 02:51:34 -07:00
jorgectf
213d011a8c Edit code example in CompiledRegex
Signed-off-by: jorgectf <jorgectf@protonmail.com>
2021-04-29 11:10:03 +02:00
Mathias Vorreiter Pedersen
39c7816ede C++: Dont allow magic in getUnspecifiedType. 2021-04-29 10:09:46 +02:00
Tom Hvitved
0cb826a511 Merge pull request #5797 from hvitved/cpp/has-multi-scope-node-noinline
C++: Do not inline `Dominance::hasMultiScopeNode`
2021-04-29 09:51:05 +02:00
CodeQL CI
3240536d0e Merge pull request #5798 from erik-krogh/trackLoc
Approved by esbena
2021-04-29 00:45:21 -07:00
Aditya Sharad
4d2db08934 Merge pull request #5801 from github/aeisenberg/fix-codescanning
Actions: Fix code scanning workflow
2021-04-28 15:21:43 -07:00
Andrew Eisenberg
0376a13dd8 Actions: Fix code scanning workflow 2021-04-28 15:05:13 -07:00
intrigus
a8865e2fa2 Java: Cleanup jwt stubs. 2021-04-28 20:46:09 +02:00
Erik Krogh Kristensen
dfd63e5d5a track window object to where .location is read 2021-04-28 18:52:00 +02:00
Shati Patel
d288b9216e Merge pull request #5790 from github/cklin-find-the-thief-conditions-sync
Fix inconsistency in the find-the-thief exercise
2021-04-28 17:16:58 +01:00
CodeQL CI
9c5ad44e27 Merge pull request #5782 from erik-krogh/domFP
Approved by esbena
2021-04-28 09:12:00 -07:00
Rasmus Lerchedahl Petersen
16bde2729d Python: add flow from methods to calls 2021-04-28 17:02:24 +02:00
Tom Hvitved
058925cca9 C++: Do not inline Dominance::hasMultiScopeNode 2021-04-28 16:50:08 +02:00
yoff
73521e22de Merge pull request #5791 from tausbn/python-limit-absolute-imports
Python: Limit absolute imports
2021-04-28 16:22:08 +02:00
Tom Hvitved
c35a2b959a Python: Update data-flow caching 2021-04-28 14:49:05 +02:00
Tom Hvitved
e8347c2c20 C++: Update data-flow caching 2021-04-28 14:49:05 +02:00
Erik Krogh Kristensen
902a4368a1 assume that all pipe elements that return something, return outputs 2021-04-28 12:36:07 +02:00
Erik Krogh Kristensen
2f14a6218a generalize RxJS pipes 2021-04-28 12:26:02 +02:00
Rasmus Wriedt Larsen
baa926359e Python: Minor fix to Django RawSQL QLDoc 2021-04-28 12:18:27 +02:00
Rasmus Wriedt Larsen
8b9c5f8228 Python/JS: Remove "Only added to aid with internal rewrite" 2021-04-28 11:50:06 +02:00
Erik Krogh Kristensen
d5450f1df6 use isWildcardLike in MetacharEscapeSanitizer 2021-04-28 11:46:50 +02:00
Erik Krogh Kristensen
d07c71c99d unlimited repetition of a wildcard is also a wildcard 2021-04-28 11:46:35 +02:00
Erik Krogh Kristensen
160fa148f1 move InfiniteRepetitionQuantifier to Regexp.qll 2021-04-28 11:39:28 +02:00
Erik Krogh Kristensen
e60628d463 add global replacements using inverted char classes as a sanitizer for DOM based XSS 2021-04-28 11:29:30 +02:00
Rasmus Wriedt Larsen
f2b4e31e7f Python: Make Diagnostics tests pass
I had comitted a bad .expected file it seems, and since the encoding for UTF-8
is named differently from Python 2 to Python 3, we're only going to run the test
for one version.
2021-04-28 10:21:59 +02:00
Tamás Vajk
310baab73f Merge pull request #5740 from tamasvajk/feature/diag
C#: Add extraction error diagnostic query
2021-04-28 08:46:35 +02:00
haby0
b0f745365d Node type restriction 2021-04-28 14:32:25 +08:00
Taus
4ae3a23089 Python: Limit absolute imports
Limits the behaviour of github/codeql#5614 in two ways:

First, we only consider files that are contained in the source archive.
This prevents unnecessary computation involving files in e.g. the
standard library.

Secondly, we ignore any relative imports (e.g. `from .foo import ...`),
as these only work inside packages anyway.

This fixes an observed performance regression on projects that include
`google-cloud-sdk` as part of their source code.
2021-04-27 21:47:38 +00:00
CodeQL CI
2b9fb79b1d Merge pull request #5786 from erik-krogh/anser
Approved by esbena
2021-04-27 14:40:48 -07:00
Chuan-kai Lin
c27363cea5 Fix inconsistencies in information about the thief
The find-the-thief exercise is inconsistent.  The first part lists 10 answered questions about the thief, but later discussion silently adds a new question as question 8, so there are a total of 11 answered questions.

This commit updates the first list of answered questions so that it matches later discussions and the sample solution.
2021-04-27 13:57:16 -07:00
Mathias Vorreiter Pedersen
0f141edbc3 Merge pull request #5737 from dbartol/dbartol/smart-pointers/work
C++: IR Alias Analysis for smart pointers
2021-04-27 21:40:14 +02:00
jorgectf
21e01b809f Add code example in CompiledRegex
Signed-off-by: jorgectf <jorgectf@protonmail.com>
2021-04-27 19:54:42 +02:00
jorgectf
8a800986a2 Remove unused class variables
Signed-off-by: jorgectf <jorgectf@protonmail.com>
2021-04-27 19:54:42 +02:00
jorgectf
20b532ec5e Update to-cast sink's naming
Signed-off-by: jorgectf <jorgectf@protonmail.com>
2021-04-27 19:54:41 +02:00
Jorge
c0c71c509c Apply suggestions from code review
Update `RegexExecution` docs and use `flowsTo()` instead of `getALocalSource()`.

Co-authored-by: yoff <lerchedahl@gmail.com>
2021-04-27 19:54:41 +02:00
jorgectf
c4322848ec Polish qhelp 2021-04-27 19:54:40 +02:00
jorgectf
12ccd7e3b6 Update .expected 2021-04-27 19:54:39 +02:00
jorgectf
05ee853c4e Remove wrong comment 2021-04-27 19:54:39 +02:00
jorgectf
3fae3fd93e Take ApiGraphs out of Concepts.qll 2021-04-27 19:54:39 +02:00
jorgectf
6a20a4dcc3 Add newline to qhelp 2021-04-27 19:54:38 +02:00
jorgectf
d968eea914 Move expected to /test 2021-04-27 19:54:38 +02:00
jorgectf
81d23c066c Move tests and qlref from /src to /test 2021-04-27 19:54:37 +02:00
jorgectf
d401d18e71 Add .expected and qlref 2021-04-27 19:54:36 +02:00
jorgectf
ec85ee4537 Sink's predicate typo 2021-04-27 19:54:36 +02:00
jorgectf
03825a6052 Add comment to Sink's predicates 2021-04-27 19:54:36 +02:00
jorgectf
fc27c6c547 Fix RegexExecution ambiguity 2021-04-27 19:54:35 +02:00
jorgectf
3655514924 Fix ambiguity 2021-04-27 19:54:35 +02:00
jorgectf
b6721971dd Improve code comments 2021-04-27 19:54:35 +02:00
jorgectf
d4a89b2fd8 Fix qhelp typo while converting to python's regex injection 2021-04-27 19:54:34 +02:00
jorgectf
d49c23fe67 Improve tests' readability 2021-04-27 19:54:34 +02:00
jorgectf
0e169ba10e Format qhelp 2021-04-27 19:54:33 +02:00
jorgectf
c54f08f33a Improve qhelp 2021-04-27 19:54:33 +02:00
jorgectf
66ee67a781 Polished select statement 2021-04-27 19:54:32 +02:00
jorgectf
f75110365f Fix Sink utilization in select 2021-04-27 19:54:32 +02:00
jorgectf
a5850f4a99 Use getRegexModule to know used lib 2021-04-27 19:54:31 +02:00
jorgectf
e78e2ac266 Get rid of (get)regexMethod 2021-04-27 19:54:30 +02:00
jorgectf
18ce257fc8 Move RegexInjectionSink to query config (qll) 2021-04-27 19:54:29 +02:00
jorgectf
53d61c4fb6 Use custom Sink 2021-04-27 19:54:29 +02:00
jorgectf
36cc7b5e3f Fix CompiledRegex 2021-04-27 19:54:28 +02:00
jorgectf
35f1c45d32 Change from Attribute to DataFlow::CallCfgNode in getRegexMethod() 2021-04-27 19:54:28 +02:00
jorgectf
c127b109d0 Create re.compile().ReMethod test 2021-04-27 19:54:27 +02:00
jorgectf
be09ffec3f Create RegexEscape Range 2021-04-27 19:54:27 +02:00
jorgectf
805f86a5cf Polish RegexEscape 2021-04-27 19:54:26 +02:00
jorgectf
3d990c5950 Get back to ApiGraphs 2021-04-27 19:54:26 +02:00
jorgectf
30554a16da Format 2021-04-27 19:54:24 +02:00
jorgectf
ee1d2b645b Delete DirectRegex and CompiledRegex 2021-04-27 19:54:24 +02:00
jorgectf
ce23db2e9c Move Sanitizer to ReEscapeCall 2021-04-27 19:54:23 +02:00
jorgectf
b5ea41fcca Fix CompiledRegex 2021-04-27 19:54:22 +02:00
jorgectf
d61adccd3c Take main Concepts.qll out of the PR 2021-04-27 19:54:22 +02:00
jorgectf
a1a3c98d92 Undo main Concepts.qll change 2021-04-27 19:54:21 +02:00
jorgectf
28fdeba4fa Structure development 2021-04-27 19:54:20 +02:00
jorgectf
444a15a461 Polish imports 2021-04-27 19:54:20 +02:00
Jorge
0f20eeb395 Apply suggestions
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-04-27 19:54:19 +02:00
Jorge
b27b77c38f Apply suggestions from code review
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-04-27 19:54:18 +02:00
Jorge
249e4097e3 Change query ID
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-27 19:54:17 +02:00
jorgectf
b207929e0a RegexExecution restructuring 2021-04-27 19:54:16 +02:00
jorgectf
3daec8e6a2 Enclose Sinks and ReMethods in a module 2021-04-27 19:54:15 +02:00
jorgectf
caaf5436c6 Attempt to restructuring ReMethods and RegexExecution's modules 2021-04-27 19:54:14 +02:00
jorgectf
6d5a0f2f84 Limit Sanitizer to re.escape(arg) 2021-04-27 19:54:13 +02:00
jorgectf
a1b5cc3bc6 Typo 2021-04-27 19:54:13 +02:00
jorgectf
e4736d064e Typo 2021-04-27 19:54:12 +02:00
jorgectf
f45307f990 Apply rebase 2021-04-27 19:54:12 +02:00
jorgectf
5dae920783 Edit filenames to match consistent naming 2021-04-27 19:54:11 +02:00
jorgectf
63f708dd57 Apply suggestions 2021-04-27 19:54:10 +02:00
Jorge
6cc714464c Apply suggestions from code review
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-04-27 19:54:09 +02:00
jorgectf
21f8135fa6 Move to experimental folder 2021-04-27 19:54:08 +02:00
jorgectf
afc4f51e9c Remove CWE references 2021-04-27 19:54:07 +02:00
jorgectf
bd3d2ec686 Update to match consistent naming across languages 2021-04-27 19:54:07 +02:00
jorgectf
7adc3c2fba Upload ReDoS query, qhelp and tests 2021-04-27 19:54:05 +02:00
Tom Hvitved
bd0a196a39 Java: Update data-flow caching 2021-04-27 19:06:39 +02:00
Tom Hvitved
befc80b3cb C#: Update data-flow caching 2021-04-27 19:06:39 +02:00
Tom Hvitved
914184f3dd Data flow: Sync files 2021-04-27 19:06:39 +02:00
Tom Hvitved
0c8886967b Data flow: Cache nodeIsHidden 2021-04-27 19:05:11 +02:00
Tom Hvitved
1112c0f994 Data flow: Cache ParameterNode 2021-04-27 19:05:11 +02:00
Tom Hvitved
7d4feaca2f Data flow: Cache ArgumentNode 2021-04-27 19:05:11 +02:00
Tom Hvitved
ade99c2c2b Data flow: Cache Cast(ing)Node 2021-04-27 19:05:11 +02:00
Tom Hvitved
346af4f97a Data flow: Cache ReturnNodeExt 2021-04-27 19:05:10 +02:00
Tom Hvitved
9738de2cb9 Data flow: Cache OutNodeExt 2021-04-27 19:05:10 +02:00
Tom Hvitved
23113c4ff7 Data flow: Cache isUnreachableInCall 2021-04-27 19:05:10 +02:00
Tom Hvitved
1bf0e01a83 Data flow: Cache clearsContent 2021-04-27 19:05:10 +02:00
Tom Hvitved
4009c01558 Data flow: Cache readStep 2021-04-27 19:05:10 +02:00
Tom Hvitved
96aa182893 Data flow: Cache jumpStep 2021-04-27 19:05:10 +02:00
Tom Hvitved
8bfeae768f Data flow: Cache simpleLocalFlowStep 2021-04-27 19:05:10 +02:00
Tom Hvitved
1a56f0b79c Data flow: Cache getNodeType 2021-04-27 19:05:10 +02:00
Tom Hvitved
044c92016b Data flow: Cache enclosing callable predicates 2021-04-27 19:05:09 +02:00
Tom Hvitved
37377644c9 Merge pull request #5781 from hvitved/java/predictable-seed-df6
Java: Use separate data-flow copy for `PredictableSeedFlowConfiguration`
2021-04-27 19:01:55 +02:00
Andrew Eisenberg
c6db90e9b7 Merge pull request #5775 from aeisenberg/aeisenberg/codeql-action-main
Actions: Use the main branch of the codeql action
2021-04-27 09:36:33 -07:00
Tamás Vajk
4cc88662e2 Merge pull request #5557 from tamasvajk/feature/java-sinks-csv
Java: convert sinks to CSV
2021-04-27 15:58:09 +02:00
Erik Krogh Kristensen
9178f4b1c5 add support for the anser library 2021-04-27 15:57:17 +02:00
Tamas Vajk
51e08d4940 Fix error severity 2021-04-27 15:47:16 +02:00
edvraa
3aec9c1a41 Cookies without HttpOnly 2021-04-27 16:28:32 +03:00
Marcono1234
05ce49adaf Java: Add StmtParent as superclass of SwitchExpr
Database type `@stmtparent` already includes `@switchexpr`, this commit merely
changes the class SwitchExpr to also accordingly extend StmtParent.
2021-04-27 15:17:55 +02:00
Tamas Vajk
5b79094f34 Fix naming in HTTPS URL check 2021-04-27 14:59:52 +02:00
Rasmus Wriedt Larsen
523ed8272d Python: Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2021-04-27 14:42:05 +02:00
yoff
0509a12790 Merge pull request #5770 from tausbn/python-small-api-graph-fix
Python: Use only `TApiNode` in `API::Impl`
2021-04-27 14:06:09 +02:00
Geoffrey White
afa89256c5 Merge pull request #5780 from MathiasVP/cleanup-missingGuard-predicates-after-range-analysis-fix
C++: Cleanup missingGuardAgainstOverflow
2021-04-27 12:56:10 +01:00
Chris Smowton
64a2320be7 Merge pull request #5757 from smowton/smowton/admin/fix-dead-qhelp-links
Fix all dead qhelp links
2021-04-27 12:17:08 +01:00
Tom Hvitved
2e266c7ddd Merge pull request #5756 from hvitved/csharp/string-builder-fluent
C#: Add missing `StringBuilder` flow summaries
2021-04-27 11:24:56 +02:00
Tom Hvitved
fb606112fa Merge pull request #5754 from hvitved/csharp/guards/performance
C#: Improve performance of guards library
2021-04-27 10:53:01 +02:00
Tamas Vajk
e08b629cb5 Add documentation for URL opening sinks 2021-04-27 10:32:41 +02:00
Tom Hvitved
017beb6786 Java: Use separate data-flow copy for PredictableSeedFlowConfiguration 2021-04-27 10:07:33 +02:00
CodeQL CI
79ed94b22c Merge pull request #5779 from erik-krogh/updateJSAndTSVersionDoc
Approved by esbena
2021-04-27 00:51:58 -07:00
Mathias Vorreiter Pedersen
04a785b9fb C++: Accept test changes. 2021-04-27 09:43:27 +02:00
Mathias Vorreiter Pedersen
a41e9055c5 C++: Delete the fix that was introduced in bb447d7174. This is no longer needed after #5678. 2021-04-27 09:43:02 +02:00
Mathias Vorreiter Pedersen
05d693e3bb C++: Also include the assignment versions in exprThatCanOverflow. 2021-04-27 09:41:13 +02:00
Rasmus Wriedt Larsen
37db21d269 Merge pull request #5284 from yoff/python-port-insecure-protocol
Python: port py/insecure-protocol
2021-04-27 09:30:18 +02:00
Erik Krogh Kristensen
0b322a3143 update JS/TS versions to reflect supported versions 2021-04-27 08:53:15 +02:00
haby0
5be9fbbc5a Remove LogOperationSink and PrintSink 2021-04-27 14:12:33 +08:00
Andrew Eisenberg
0e53ad33f6 Actions: Add permissions block to code scanning workflow 2021-04-26 10:53:29 -07:00
Geoffrey White
0e7eeb3051 Merge pull request #5678 from MathiasVP/sound-expr-might-overflow-predicate
C++: Make exprMightOverflowPositively sound for unanalyzable expressions
2021-04-26 17:38:23 +01:00
Andrew Eisenberg
3670c729c0 Actions: Use the main branch of the codeql action
This commit switches to the bleeding edge, main branch of the
codeql action. This helps us test the action before merging all
of the new changes into main, which occurs roughly once a week.

If there are commits that introduce bugs in codeql-action, then
we will be more likely to catch it before releasing to the world
if we are using it in this extension.
2021-04-26 08:43:28 -07:00
Taus
3889c8afec Python: Use only TApiNode in API::Impl
This ensures that changes to `API::Node` does not invalidate the cached
`module Impl`. At present, I don't expect this to have any effect (as
the `Node` class is also fairly static, though not explicitly cached),
but I can imagine us making some of the `Node` methods have
user-extensible behaviour, in which case we definitely do not want this
to result in reevaluation of `API::Impl`.
2021-04-26 13:10:15 +00:00
Shati Patel
a09c12acfe Merge pull request #5537 from alexet/ambig-super
Docs: Update the language specification for changes to super.
2021-04-26 13:34:50 +01:00
Hayk Andriasyan
7455b1b4f0 Update JSchOSInjectionSanitized.java 2021-04-26 15:17:57 +04:00
p0wn4j
3d891f0b39 [Java] CWE-078: Add JSch OS command injection sink 2021-04-26 18:20:32 +04:00
Chris Smowton
d717fc7b1f Use Microsoft archive of vijaysk's blog 2021-04-26 10:13:04 +01:00
Tom Hvitved
824c243268 C#: Add change note 2021-04-26 10:50:17 +02:00
Mathias Vorreiter Pedersen
772d5eacca C++: Add change note. 2021-04-26 09:55:32 +02:00
Erik Krogh Kristensen
4e8ae77b6f cache more predicates 2021-04-26 08:57:20 +02:00
ihsinme
98f7f70814 Add files via upload 2021-04-25 22:35:40 +03:00
ihsinme
50c63a88c3 Add files via upload 2021-04-25 22:34:41 +03:00
intrigus
b1a3633495 Java: Remove redundant condition + docs. 2021-04-23 22:06:04 +02:00
Rasmus Lerchedahl Petersen
7cc97836a9 Python: More cleanup from reviewer suggestions 2021-04-23 20:26:13 +02:00
Chris Smowton
78b9682a4e Fix dead links in JS externs too 2021-04-23 15:46:48 +01:00
Tamás Vajk
a7030c7fed Merge pull request #5308 from tamasvajk/feature/flow-sources-sinks
C#: Add Console.Read* to local flow sources
2021-04-23 16:36:16 +02:00
Tamás Vajk
c3058f4744 Merge pull request #5749 from tamasvajk/feature/fix-fromsource
C#: Adjust 'fromSource' to hold only on files passed to the compiler as a source file
2021-04-23 16:35:40 +02:00
Chris Smowton
455b840712 Fix all dead qhelp links
For those documents with no obvious new home I've pointed the links to the Internet Archive.
2021-04-23 15:20:21 +01:00
Tom Hvitved
004450b201 C#: Add missing StringBuilder flow summaries 2021-04-23 16:17:49 +02:00
Mathias Vorreiter Pedersen
86822f6c61 C++: Exclude pointer results from cpp/integer-overflow-tainted. 2021-04-23 16:01:53 +02:00
Mathias Vorreiter Pedersen
3cf4f1f956 C++: Accept test changes. 2021-04-23 16:00:23 +02:00
Shati Patel
6f2103f312 Merge pull request #5722 from github/tamasvajk-patch-1
C#: Add Dapper to supported frameworks
2021-04-23 14:32:22 +01:00
Jonas Jensen
9b5bb95766 Merge pull request #5696 from jbj/reapply-inconsistency-workaround
Revert "Revert "C++: Work around extractor issue CPP-383""
2021-04-23 14:49:32 +02:00
Asger Feldthaus
0da0670a79 JS: Add Nest.js to list of supported framworks 2021-04-23 13:15:35 +01:00
Asger Feldthaus
71e3041370 JS: Fewer spurious reflected xss sinks 2021-04-23 13:15:35 +01:00
Asger Feldthaus
4f53a1ab40 JS: Cache ClassNode::Range 2021-04-23 13:15:35 +01:00
Asger Feldthaus
d0b8b32345 JS: Add change notes 2021-04-23 13:15:35 +01:00
Asger Feldthaus
671e968936 JS: Model NestJS 2021-04-23 13:15:35 +01:00
Anders Schack-Mulligen
bc8c55836a Merge pull request #5743 from aschackmull/java/flow-summary-tweaks
Java/C#: Move a couple of flow summary tweaks to the shared implementation.
2021-04-23 13:46:04 +02:00
Tamas Vajk
1b4c3c7415 Fix code review findings 2021-04-23 13:44:34 +02:00
Tamás Vajk
819be43ce7 Fix alphabetical order of supported frameworks 2021-04-23 13:41:59 +02:00
Tamas Vajk
b4bd7af9c8 Add change note 2021-04-23 13:40:12 +02:00
Tamas Vajk
e3f10c0e32 Cleanup DiagnosticError classes 2021-04-23 13:37:42 +02:00
Rasmus Wriedt Larsen
deb3db3f95 Python: Add non-alert data for extractor diagnostics
This is basically just a port of the C++/JS queries added in:

- https://github.com/github/codeql/pull/5414 (C++)
- https://github.com/github/codeql/pull/5656 (JS)

SyntaxError should capture all errors we have information about. At least in
`python/ql/src/semmlecode.python.dbscheme` the only match for `error` is
`py_syntax_error_versioned` (which `SyntaxError` is based on).
2021-04-23 13:29:44 +02:00
Rasmus Wriedt Larsen
354dee1b09 Python: Add non-alert data for lines of code
`py/summary/lines-of-code` is just a port of the C++/JS queries added in:

- https://github.com/github/codeql/pull/5271 (C++)
- https://github.com/github/codeql/pull/5304 (JS)

We are the first to implement the `lines-of-user-code` query, so nothing to
compare with in other languages -- but it makes a lot of sense to do for Python 👍
2021-04-23 13:22:18 +02:00
Asger Feldthaus
109d1ad27f JS: Model fs.promises 2021-04-23 11:59:48 +01:00
Asger Feldthaus
822d4525af JS: Drive-by change in LogInjection 2021-04-23 11:59:48 +01:00
Asger Feldthaus
ad12f383d9 JS: Reduce reliance on RouteHandler in Express model 2021-04-23 11:59:48 +01:00
Tamás Vajk
43dc9bbc94 Merge pull request #5744 from tamasvajk/feature/java-loc
Java: Introduce LoC summary metric query
2021-04-23 11:39:42 +02:00
Mathias Vorreiter Pedersen
e6077127be C++: Only unary and binary arithmetic operations and left shifts are now
reported as overflowing when we cannot analyze them.
2021-04-23 11:13:34 +02:00
Tom Hvitved
956507b5fa C#: Add guards stress test 2021-04-23 10:25:31 +02:00
yoff
1954c0ba84 Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2021-04-23 10:20:18 +02:00
Tom Hvitved
4c597dd467 C#: Improve performance of guards library 2021-04-23 10:09:43 +02:00
Jonas Jensen
6de5b3021e C++: Replace Jira ticket reference with GH issue 2021-04-23 09:58:39 +02:00
Jonas Jensen
6e059ea002 C++: Remove reference to obsolete issue CPP-383 2021-04-23 09:58:15 +02:00
Shati Patel
96a4d91a6c Merge pull request #5731 from shati-patel/docs/unbind-pragmas
Docs: New "directional binding" pragmas
2021-04-23 08:37:02 +01:00
intrigus
98dcd4e52b Java: Tighten definition of sink. 2021-04-23 00:14:48 +02:00
CodeQL CI
635fb4c25a Merge pull request #5685 from erik-krogh/markdownIt
Approved by asgerf
2021-04-22 14:55:31 -07:00
intrigus
a385b30c29 Java: Factor common expr into class. 2021-04-22 23:51:27 +02:00
intrigus-lgtm
958e2fab05 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-22 23:36:17 +02:00
Dave Bartolomeo
3b04bedee0 Stub out additional bits of Alias model for C# 2021-04-22 17:19:00 -04:00
Dave Bartolomeo
5d0a4cae90 C++: Add {AllAliased} side effects for smart pointers
Smart pointer constructors, assignments, and `reset()` can actually have fairly large side effects, especially with custom deleters, destructors for objects being destroyed, and so on. I've re-introduced `{AllAliased}` side effects for these functions. There was no immediate effect on analysis results.
2021-04-22 16:51:36 -04:00
Taus
3e4ff9e472 Merge pull request #5742 from RasmusWL/django-3.2
Python: Add support for new features in Django 3.2
2021-04-22 17:39:02 +02:00
Rasmus Lerchedahl Petersen
5a4e661e60 Merge branch 'main' of github.com:github/codeql into python-support-pathlib 2021-04-22 15:04:21 +02:00
CodeQL CI
bdb41423e2 Merge pull request #5748 from asgerf/js/rate-limiting-fixes
Approved by erik-krogh
2021-04-22 05:56:50 -07:00
Tamas Vajk
ed42c878b0 Adjust 'fromSource' to hold only on '.cs' files 2021-04-22 14:17:16 +02:00
Tamas Vajk
b36d35bf1e Revert "C#: Adjust 'fromSource' to hold only on files passed to the compiler as a source file"
This reverts commit 1dab1590ea.
2021-04-22 14:16:10 +02:00
haby0
407dcea751 add String type startsWith 2021-04-22 19:20:54 +08:00
haby0
1712d01b74 Merge branch 'UseOfLessTrustedSource' of https://github.com/haby0/codeql into UseOfLessTrustedSource 2021-04-22 19:02:23 +08:00
haby0
9b4442be8b Fix some errors 2021-04-22 19:01:55 +08:00
haby0
aaef4ef22b Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSourceLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-22 18:52:55 +08:00
Tamás Vajk
cb28bc80b7 Merge branch 'main' into feature/java-sinks-csv 2021-04-22 11:41:18 +02:00
Tamas Vajk
7134eb9079 Improve documentation of csv sink models 2021-04-22 11:37:41 +02:00
Mathias Vorreiter Pedersen
2b8afe55e8 Merge pull request #5747 from rdmarsh2/rdmarsh2/cpp/deprecate-return-stack-allocated-object
C++: deprecate cpp/return-stack-allocated-object
2021-04-22 11:37:07 +02:00
Tamas Vajk
1caa5c4780 Adjust hostname verifier sink identifier name 2021-04-22 11:22:18 +02:00
Tamas Vajk
6c78a247f2 Revert erroneous refactoring in header splitting sink base class 2021-04-22 11:20:39 +02:00
Tamas Vajk
9b1c54e81b Add argument indices to HTTP header splitting sinks 2021-04-22 11:17:25 +02:00
Tamas Vajk
180904e9f6 Revert "Java: Convert Google HTTP client API parseAs sink to CSV format"
This reverts commit 3e53484bb3.
2021-04-22 11:14:51 +02:00
Owen Mansel-Chan
fea9f5f431 Merge pull request #5746 from owen-mc/java/refactor-exec-tainted
Make ExecTainted easier to extend
2021-04-22 10:14:28 +01:00
Tamas Vajk
a8a920c8f0 Add change note 2021-04-22 11:01:12 +02:00
Owen Mansel-Chan
8a01799fb8 Make imports private
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-04-22 09:46:49 +01:00
Rasmus Lerchedahl Petersen
b724e51cab Python: Improvements from review suggestions 2021-04-22 10:40:42 +02:00
Owen Mansel-Chan
4b8d4f5bbd Update docs 2021-04-22 09:30:50 +01:00
Owen Mansel-Chan
e448dcb725 Avoid bad join order
We want to avoid joining on `i` first.
2021-04-22 09:30:49 +01:00
Owen Mansel-Chan
9f1704560b Include constructors in abstract class 2021-04-22 09:30:48 +01:00
Tamas Vajk
1dab1590ea C#: Adjust 'fromSource' to hold only on files passed to the compiler as a source file 2021-04-22 10:21:28 +02:00
Tamas Vajk
1a708affbf Include compilation errors in diagnostic check 2021-04-22 10:08:33 +02:00
Asger Feldthaus
d2646ea4ad JS: More consistent section capitalization 2021-04-22 09:06:44 +01:00
Asger Feldthaus
0dceabe704 JS: Reference specific section of cheat sheet 2021-04-22 09:06:09 +01:00
Tamas Vajk
64354bbfaa Fix test results after rebase 2021-04-22 09:23:59 +02:00
Tamas Vajk
ff9327a035 Add diagnostic query to get correctly extracted files 2021-04-22 09:21:46 +02:00
Tamas Vajk
b05e211e21 Fix failing test 2021-04-22 09:21:45 +02:00
Tamas Vajk
353d43a039 Log model errors even in standalone extraction 2021-04-22 09:13:06 +02:00
Tamas Vajk
5149ffdd16 C#: Add extraction error diagnostic query 2021-04-22 09:13:06 +02:00
Tamás Vajk
9c936867fa Exclude code from XML files
Co-authored-by: yo-h <55373593+yo-h@users.noreply.github.com>
2021-04-22 09:00:31 +02:00
Tamás Vajk
a7cc9f98ef Merge pull request #5745 from tamasvajk/feature/fix-arg-default
C#: Fix special case of default argument value extraction
2021-04-22 08:58:13 +02:00
haby0
454324781d delete IfStmt 2021-04-22 11:59:33 +08:00
Robert Marsh
cac1bef6ea C++: deprecate cpp/return-stack-allocated-object 2021-04-21 15:17:31 -07:00
Asger Feldthaus
fe8deeaf6b JS: Autoformat 2021-04-21 23:13:57 +01:00
Dave Bartolomeo
383210096c C++: Isolate models from AST dataflow's reference/object conflation
`DataFlowFunction` models treat references a pointers - an explicit level of indirection. The AST dataflow library generally treats references as if they were the referred-to object. This commit removes a workaround in the dataflow model for unary `operator*` on smart pointers, and makes the AST dataflow library adjust the results of querying the model so that a returned reference only gets flow that was modeled as going to the dereference of the return value.

This fixes some missing flow in IR dataflow, and recovers some (presumably) missing reverse taint flow in AST taint tracking as well.
2021-04-21 18:09:44 -04:00
Asger Feldthaus
e98bfe921e JS: QLDoc 2021-04-21 22:14:50 +01:00
Asger Feldthaus
bb7934b381 JS: Change note 2021-04-21 21:20:12 +01:00
Asger Feldthaus
c113cfd8b7 JS: Autoformat 2021-04-21 21:13:07 +01:00
Dave Bartolomeo
0bc4b0421d C++: Remove unnecessary cast 2021-04-21 12:12:01 -04:00
Rasmus Wriedt Larsen
5a9e27c6fc Merge branch 'main' into django-3.2 2021-04-21 17:15:47 +02:00
Chris Smowton
94f0a1532d Merge pull request #5682 from smowton/smowton/docs/fix-has-modifier-comment
Fix documentation of Modifier.qll
2021-04-21 15:41:29 +01:00
Tamas Vajk
a0f5e45ae9 C#: Fix special case of default argument value extraction 2021-04-21 16:34:29 +02:00
Geoffrey White
ba335089c4 Merge pull request #5601 from ihsinme/ihsinme-patch-259
CPP: Add query for CWE-691 Insufficient Control Flow Management After Refactoring The Code
2021-04-21 15:13:38 +01:00
Owen Mansel-Chan
9c72e73a82 Make ExecTainted easier to extend
To add a method that executes a command, you can now define a class
extending ExecMethod.
2021-04-21 14:55:37 +01:00
CodeQL CI
30d7f0dc98 Merge pull request #5687 from RasmusWL/inline-taint-tests
Approved by yoff
2021-04-21 06:24:12 -07:00
Taus
71780228ae Python: Rename TypeTrackerPrivate.qll 2021-04-21 13:08:26 +00:00
Asger Feldthaus
2c9a6e7bef JS: Cache function-wrapping steps in type-tracking stage 2021-04-21 13:45:58 +01:00
Tamas Vajk
e25305e3cc Java: Introduce LoC summary metric query 2021-04-21 14:27:00 +02:00
Anders Schack-Mulligen
f9599da32d Java/C#: Move a couple of flow summary tweaks to the shared implementation. 2021-04-21 14:24:15 +02:00
Rasmus Wriedt Larsen
be9cbd79d6 Python: Add change-note for Django 3.2 support 2021-04-21 13:58:34 +02:00
Rasmus Wriedt Larsen
59c6f76457 Python: Add test for new response.headers in Django
See https://docs.djangoproject.com/en/3.2/ref/request-response/#setting-header-fields
2021-04-21 13:55:22 +02:00
Rasmus Wriedt Larsen
2302c8d5fa Python: Model new alias method on django QuerySets 2021-04-21 13:52:38 +02:00
yoff
a19373ab54 Merge pull request #5727 from tausbn/python-use-localsource-in-stepsummary
Python: Use `LocalSourceNode` in `StepSummary::step`
2021-04-21 13:50:31 +02:00
Tamás Vajk
205469316c Merge pull request #5738 from tamasvajk/feature/loc
C# Add line of code metric query
2021-04-21 13:49:32 +02:00
Taus
489e1e94e4 Python: Prevent bad joins
Adds a few unbinds to prevent bad joins from occurring.

Firstly, we never want to join `StepSummary::step` with
`TypeTracker::append` on `summary` as the first join, as the resulting
relation is absolutely massive. So we decouple the two occurrences of
`summary` by unbinding each of them.

Secondly, in some cases the node we're stepping to (`nodeTo` for type
trackers, `nodeFrom` for type backtrackers) will get joined eagerly
with the typetracker one is defining, and again this produces an
uncomfortably large intermediate join. A bit of unbinding prevents this
as well.
2021-04-21 11:44:34 +00:00
Taus
9e95f6e7c1 Python: Remove typePreservingStep
This requires a bit of explanation, so strap in.

Firstly, because we use `LocalSourceNode`s as the start and end points
of our `StepSummary::step` relation, there's no need to include
`simpleLocalFlowStep` (via `typePreservingStep`) in `smallstep`. Indeed,
since the successor node for a `step` is a `LocalSourceNode`, and local
sources never have incoming flow, this is entirely futile -- we can find
values for `mid` and `nodeTo` that satisfy the body of `step`, but
`nodeTo` will never be a `LocalSourceNode`.

With this in mind, we can simplify `smallstep` to only refer to
`jumpStep`.

This then brings the other uses of `typePreservingStep` into question.
The only other place we use this predicate is in the `TypeTracker` and
`TypeBackTracker` `smallstep` predicates. Note, however, that here we
no longer need `jumpStep` to be part of `typeTrackingStep` (as it is
already accounted for in `StepSummary::smallstep`) so we can simplify
to `simpleLocalFlowStep`. At this point, `typePreservingStep` is unused.

Finally, because of the way `smallstep` is used in `step` (inside
`StepSummary`), `nodeTo` must always be a `LocalSourceNode`, so I have
propagated this restriction to `smallstep` as well. We can always lift
this restriction later, but for now it seems like it's likely to cause
fewer surprises to have made this explicit.
2021-04-21 11:12:06 +00:00
asgerf
226792c73a JS: Expand RemoteFlowSource and move into own section 2021-04-21 12:04:09 +01:00
asgerf
5df8583056 JS: Mention isUserControlledObject 2021-04-21 11:40:27 +01:00
asgerf
ff73c0b247 JS: Add section with access paths to cheat sheet 2021-04-21 11:40:27 +01:00
asgerf
f611d06ed0 JS: Add getALocalUse to cheat sheet 2021-04-21 10:53:10 +01:00
Rasmus Wriedt Larsen
08e86fdfe5 JS: Make CredentialsFunctionName use nameIndicatesSensitiveData
Someone from JS team needs to verify that this is actually OK.
2021-04-21 11:38:52 +02:00
Rasmus Wriedt Larsen
e977d6eb75 JS: Rewrite to use notSensitiveRegexp 2021-04-21 11:36:39 +02:00
Rasmus Wriedt Larsen
b9a1a1fd5c JS: Rewrite to use nameIndicatesSensitiveData
I added this predicate mostly because it was nice with an easy shortcut for it,
but also since I spotted the `CredentialsFunctionName` not checking agaisnt the
regexps in `notSensitive`, which looked suspicious. So the main goal of adding
`nameIndicatesSensitiveData` is that you don't accidentially forget to ensure
that the name doesn't match against `notSensitve`.
2021-04-21 11:36:38 +02:00
Rasmus Wriedt Larsen
b6f8e5057b JS: Rewrite to use SensitiveDataClassification::password (and like) 2021-04-21 11:36:17 +02:00
Rasmus Wriedt Larsen
94fec5f8b7 JS: Rewrite to use SensitiveDataClassification 2021-04-21 11:34:02 +02:00
Rasmus Wriedt Larsen
0d08718f08 JS: Adapt SensitiveActions to use shared lib
Although there are warnings for the new deprecated classes/predicates, the test
in javascript/ql/test/library-tests/SensitiveActions/ passes 👍
2021-04-21 11:34:01 +02:00
Rasmus Wriedt Larsen
775ed41592 Python: Update SensitiveDataHeuristics with newer JS version
which also prompted me to rewrite the QLDoc for `nameIndicatesSensitiveData`
2021-04-21 11:34:01 +02:00
Rasmus Wriedt Larsen
16b62486e9 Python: Extract SensitiveDataHeuristics to be shared with JS
Initially I had called `nameIndicatesSensitiveData` for `maybeSensitiveName`,
which made the relationship with `maybeSensitive` and `notSensitive` quite
strange -- and therefore I added the more informative `maybeSensitiveRegexp` and
`notSensitiveRegexp`.

Although I'm no longer using `maybeSensitiveName`, and I no longer have a strong
argument for making this name change, I still like it. If someone thinks this is
a terrible idea, I'm happy to change it though 👍
2021-04-21 11:31:28 +02:00
Tamas Vajk
2a6f979ce6 C# Add line of code metric query 2021-04-21 10:42:06 +02:00
Anders Schack-Mulligen
9362ae0687 Merge pull request #5422 from tamasvajk/feature/sink-migration-ldap
Java: Migrate LDAP injection sinks to CSV format
2021-04-21 10:05:28 +02:00
Rasmus Wriedt Larsen
63a2657aef Merge branch 'main' into inline-taint-tests 2021-04-21 10:02:55 +02:00
Tom Hvitved
7080b256fb Merge pull request #5715 from hvitved/csharp/ssa/perf-tweaks
C#: A few minor SSA performance tweaks
2021-04-21 09:59:12 +02:00
Tom Hvitved
def62e8c22 Merge pull request #5718 from hvitved/csharp/hardcoded-cred-remove-cp
C#: Remove CP from `HardcodedCredentials::getCredentialSink`
2021-04-21 09:58:56 +02:00
Tom Hvitved
1ed11b297b Merge pull request #5725 from hvitved/csharp/dataflow/performance
C#: Various data-flow performance tweaks
2021-04-21 09:46:15 +02:00
haby0
84f00c21df update IfConditionSink. 2021-04-21 15:38:41 +08:00
Dave Bartolomeo
1d0cb0407d Merge from main 2021-04-20 23:37:04 -04:00
Dave Bartolomeo
b9da6ce04a C++: Prepare for merge of smart pointer models 2021-04-20 23:12:05 -04:00
Dave Bartolomeo
a447b049fc C++: Impoved alias analysis of smart pointers 2021-04-20 19:42:06 -04:00
Dave Bartolomeo
63fe4fb317 C++: More general model for pointer flow 2021-04-20 19:41:15 -04:00
Dave Bartolomeo
078d2522d2 C++: Add missing shared_ptr<T> members 2021-04-20 19:40:36 -04:00
Dave Bartolomeo
45968efd28 C++: Add shared test headers to emulate standard library types 2021-04-20 18:21:50 -04:00
intrigus
231b07795c Java: Ignore results in test directories. 2021-04-20 23:25:13 +02:00
intrigus
fcaf5e7657 Java: Plural type name -> singular type name. 2021-04-20 23:09:44 +02:00
intrigus
3acec94773 Java: Fix typos. 2021-04-20 23:04:06 +02:00
intrigus
149c4491ce Java: Simplify qldoc. 2021-04-20 23:03:10 +02:00
intrigus
9e4fa90f6e Java: Refer to Java types in qldoc instead of ql types. 2021-04-20 23:02:18 +02:00
intrigus
26502881d7 Java: Consistently use this in charpred. 2021-04-20 22:56:58 +02:00
yoff
0c4181178d Update python/ql/src/semmle/python/frameworks/Stdlib.qll
Co-authored-by: Taus <tausbn@github.com>
2021-04-20 22:15:09 +02:00
yoff
ef0ea247c4 Merge pull request #5679 from tausbn/python-fix-bad-points-to-joins
Python: Fix bad points-to joins
2021-04-20 21:19:32 +02:00
Asger Feldthaus
02707f0777 JS: informational -> info 2021-04-20 19:51:16 +01:00
Dave Bartolomeo
5085e462b0 C++: Allow alias propagation to/from side effects (part 1) 2021-04-20 14:09:41 -04:00
Dave Bartolomeo
01a95316c2 C++: Add Instruction::getAParameterSideEffect(). 2021-04-20 14:03:48 -04:00
Rasmus Lerchedahl Petersen
6408ee2eaf Python: Fix bad join 2021-04-20 20:03:06 +02:00
Tom Hvitved
3eba5b0aac Merge pull request #5676 from hvitved/csharp/dispatch/get-a-viable-overrider-perf
C#: Speedup `DispatchMethodOrAccessorCall::getAViableOverrider()`
2021-04-20 19:57:59 +02:00
Erik Krogh Kristensen
357e1c0802 Update javascript/ql/src/semmle/javascript/frameworks/Markdown.qll
Co-authored-by: Asger F <asgerf@github.com>
2021-04-20 19:57:47 +02:00
yo-h
00137f2905 Merge pull request #5721 from github/yo-h/java-diagnostic-queries
Java: add extractor `diagnostic` queries
2021-04-20 13:36:49 -04:00
Shati Patel
98a0959784 Docs: New "directional binding" pragmas 2021-04-20 18:12:35 +01:00
Rasmus Lerchedahl Petersen
fc2c62350e Python: Fix bad join
Also fixed up the QLDoc
2021-04-20 18:54:03 +02:00
Asger Feldthaus
9f8a9b9cad JS: Add taint source/sink summary queries 2021-04-20 17:10:31 +01:00
Taus
890f96d9b5 Python: Prevent bad joins in TypeBackTracker
Perhaps unsurprisingly, the join orderer was eager and willing to find
the wrong join order in this predicate as well. Applying a similar
fix to the one used in `TypeTracker::step` fixes the problem.
2021-04-20 15:01:04 +00:00
Taus
c0569da65c Python: Move track/backtrack to LocalSourceNode
This is merely making explicit what was implicitly enforced. The move
to change the return type of `step` already meant that `this` and
`result` had to be `LocalSourceNode`. By moving these methods to their
rightful place, we should hopefully avoid a bit of suprising behaviour.
2021-04-20 14:39:56 +00:00
Taus
2a07441c19 Python: ModuleVariableNodes are not API uses
This caused some suprising test changes, where suddenly we had flow from
a `ModuleVariableNode` (as a `RemoteFlowSource`) to a sink. This of
course makes little sense, so instead we simply exclude these nodes as
uses in the first place.
2021-04-20 14:33:42 +00:00
Rasmus Lerchedahl Petersen
9c893cb0f4 Merge branch 'main' of github.com:github/codeql into python-port-insecure-protocol 2021-04-20 16:33:03 +02:00
Taus
7581cbade6 Python: Fix forgotten type tracker
This was the last remaining type tracker that did not use
`LocalSourceNode`.
2021-04-20 14:32:56 +00:00
Tamas Vajk
583513bafd Fix review findings 2021-04-20 16:28:47 +02:00
Asger Feldthaus
43ca8ea5f7 JS: Fix perf issue in forwardsParameter 2021-04-20 15:15:12 +01:00
Chris Smowton
a5cfdd2cfe Merge pull request #5467 from p0wn4j/groovy-execute
[Java] CWE-094: Query to detect Groovy Code Injections
2021-04-20 14:49:56 +01:00
Erik Krogh Kristensen
62dfd1fa7d improve the markdown-it model 2021-04-20 15:23:03 +02:00
Taus
38548c9acd Python: Simplify charpred for LocalSourceNode
The somewhat convoluted `comes_from_cfgnode` was originally introduced
in order to have local sources for instances of global variables. This
was needed because global variables have an implicit "scope entry" SSA
definition that flows to the first actual use of the variable (and so
would not fit the strict "has no incoming flow" definition of a local
source node).

However, a subsequent change means that we include all global variable
reads anyway, and so the old definition is no longer needed.

(See commit 3fafb47b16 for further
context.)
2021-04-20 13:19:36 +00:00
Taus
038bf612be Python: Add change note 2021-04-20 13:06:30 +00:00
Jonas Jensen
f02c86cb22 Merge pull request #5726 from MathiasVP/fix-false-positive-in-return-stack-allocated-memory-2
C++: Fix false positive in return stack allocated memory (second attempt)
2021-04-20 15:05:11 +02:00
Taus
a55b43b67e Python: Use LocalSourceNode throughout step
This commit does a lot of stuff all at once, so here are the main
highlights:

In `TypeTracker.qll`, we change `StepSummary::step` to step only between
source nodes. Because reads and writes of global variables happen in two
different (jump) steps, this requires the intermediate
`ModuleVariableNode` to _also_ be a `LocalSourceNode`, and we therefore
modify the charpred for that class accordingly. (This also means
changing a few of the tests to account for these new source nodes.)

In addition, we change `TypeTracker::step` to likewise step between
local source nodes.

Next, to enable the use of the `track` convenience method on nodes, we
add some pragmas to `TypeTracker::step` that prevent bad joins from
occurring. With this, we can eliminate all of the manual type tracker
join predicates.

Next, we observe that because `StepSummary::step` now uses `flowsTo`, it
automatically encapsulates all local-flow steps. In particular this
means we do not have to use `typePreservingStep` in `smallstep`, but can
use `jumpStep` directly. A similar observation applies to
`TypeTracker::smallstep`.

Having done this, we no longer need `typePreservingStep`, so we get rid
of it.
2021-04-20 12:59:33 +00:00
Taus
31bd701bd5 Python: Final LocalSourceNode fixes 2021-04-20 12:59:33 +00:00
Chris Smowton
9bfb0d93ca Autoformat QL 2021-04-20 13:59:09 +01:00
Rasmus Wriedt Larsen
897105de02 Merge pull request #5717 from tausbn/python-use-api-graphs-in-django
Python: Use API graphs in Django model
2021-04-20 14:57:55 +02:00
Erik Krogh Kristensen
19c5889775 use mayHaveBooleanValue 2021-04-20 14:39:54 +02:00
Erik Krogh Kristensen
13d915927b add change note 2021-04-20 14:39:54 +02:00
Erik Krogh Kristensen
7046f1a902 add taint-step for markdown-it when the HTML flag is set 2021-04-20 14:39:54 +02:00
Taus
76700d17d6 Merge pull request #5684 from RasmusWL/flask-more-taint-tests
Python: Add taint tests for .get() in flask
2021-04-20 14:08:08 +02:00
Asger Feldthaus
f8d428cb2d JS: Use function-forwarding steps when tracking rate limiters 2021-04-20 13:00:42 +01:00
Mathias Vorreiter Pedersen
93e55e2631 C++: Fix FP in cpp/return-stack-allocated-memory. 2021-04-20 13:58:12 +02:00
Mathias Vorreiter Pedersen
1797b6c7f9 C++: Add FP test from the work on smart pointers in dataflow. 2021-04-20 13:54:57 +02:00
Asger Feldthaus
581f4ed757 JS: Generalize handling of route handler wrapper functions 2021-04-20 12:46:40 +01:00
Chris Smowton
0ec3ee29e4 Style last use of SecureASTCustomizer 2021-04-20 12:44:49 +01:00
Hayk Andriasyan
bb58a50503 Update GroovyInjection.qhelp 2021-04-20 15:41:58 +04:00
p0wn4j
f2de440886 [Java] CWE-094: Query to detect Groovy Code Injections 2021-04-20 19:18:24 +04:00
haby0
3e376f95c4 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:36:16 +08:00
haby0
b1ee864ad9 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:35:52 +08:00
haby0
9e87f4ec4e Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:35:34 +08:00
haby0
408dd31d3c Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:34:37 +08:00
haby0
9ece4dac0f Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:33:47 +08:00
haby0
d82878ac3b Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:33:06 +08:00
haby0
0b1637a409 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:32:39 +08:00
haby0
b60bffaf83 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSourceLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-20 19:31:59 +08:00
Jonas Jensen
d4fdd50e2c Merge pull request #5723 from MathiasVP/cleanup-smart-ptr-model
C++: Simplify smart pointer model
2021-04-20 13:25:02 +02:00
Tom Hvitved
dd1bb18938 C#: Various data-flow performance tweaks
- Cache `DataFlowCall::getEnclosingCallable()`.
- Cache `ParameterNode`.
- Cache `ArgumentNode`.
- Force proper join-orders for uses of `getNodeType()`.
- Inline `localFlow` to prevent calculating full TC.
2021-04-20 11:56:25 +02:00
Tom Hvitved
1f9239089f Merge pull request #5695 from hvitved/csharp/dispose-not-called-on-exc-perf
C#: Improve performance of `DisposeNotCalledOnException.ql`
2021-04-20 11:52:18 +02:00
Tom Hvitved
b2a7a3ed30 Merge pull request #5674 from hvitved/csharp/ssa/call-graph-perf
C#: Improve performance of `SsaImpl::CallGraph::SimpleDelegateAnalysis`
2021-04-20 11:51:52 +02:00
Geoffrey White
2b7e599dc4 Merge pull request #5703 from MathiasVP/improve-access-of-memory-location-after-end-of-buffer-using-strncat
C++: Improve cpp/access-memory-location-after-end-buffer-strncat
2021-04-20 10:44:24 +01:00
Mathias Vorreiter Pedersen
61d4d17225 C++: Simplify smart pointer model and accept test changes. 2021-04-20 09:57:58 +02:00
Tamás Vajk
408954e4d8 C#: Add Dapper to supported frameworks 2021-04-20 09:30:47 +02:00
haby0
0053158884 update qhelp file and ql comments 2021-04-20 10:58:54 +08:00
yo-h
87cd72496c Java: add extractor diagnostic queries 2021-04-19 15:34:16 -04:00
yo-h
cb524b6c19 Merge pull request #5611 from github/yo-h/java16
Java: adjust test `options` for JDK 16 upgrade
2021-04-19 15:12:23 -04:00
Taus
bc6685aa3f Python: Fix typo
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-19 19:57:35 +02:00
Anders Schack-Mulligen
5458c02cc2 Merge pull request #5456 from aschackmull/java/adopt-flow-summary
Java: Use shared flow summary library for CSV models.
2021-04-19 16:21:10 +02:00
Anders Schack-Mulligen
33db0c13cd Merge pull request #5689 from github/aeisenberg/rework-staleness
Actions: Change staleness calculation
2021-04-19 15:57:41 +02:00
Tom Hvitved
9128ec72ad C#: A few minor SSA performance tweaks 2021-04-19 15:51:14 +02:00
Anders Schack-Mulligen
80eb0a2df6 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-19 15:45:58 +02:00
CodeQL CI
437bba1e3c Merge pull request #5716 from erik-krogh/vscodeRegress
Approved by esbena
2021-04-19 06:30:02 -07:00
Tom Hvitved
15e4b7f95d C#: Remove CP from HardcodedCredentials::getCredentialSink 2021-04-19 15:03:11 +02:00
haby0
0159956fa5 Fix Modify the ql query (the qhelp part is not modified). 2021-04-19 21:03:01 +08:00
Rasmus Wriedt Larsen
d607c13ab6 Python: Taint tests: include elment for forgotten MISSING 2021-04-19 15:01:42 +02:00
haby0
8296abcea8 Fix Modify the ql query (the qhelp part is not modified). 2021-04-19 20:59:47 +08:00
Rasmus Wriedt Larsen
9585390941 Python: Taint tests, report error location first
To better match the standard output from inline expectation tests
2021-04-19 14:59:47 +02:00
Rasmus Wriedt Larsen
b2cb284ff2 Python: Add more examples of what is ok with new taint tests 2021-04-19 14:56:20 +02:00
Anders Schack-Mulligen
7d84cfacef Java: Add MapKeyContent and MapValueContent. 2021-04-19 14:06:27 +02:00
Anders Schack-Mulligen
39862740e0 Java: Convert support for fluent interfaces. 2021-04-19 14:06:27 +02:00
Anders Schack-Mulligen
579c955892 Java: Adjust some tests. 2021-04-19 14:06:27 +02:00
Anders Schack-Mulligen
175c71221a Java: Adjust some test output with more edges/nodes. 2021-04-19 14:06:27 +02:00
haby0
23b508c5e7 Merge remote-tracking branch 'upstream/main' into UseOfLessTrustedSource 2021-04-19 20:05:49 +08:00
Anders Schack-Mulligen
60965b0d8c Java: Adjust some csv models. 2021-04-19 14:02:19 +02:00
Anders Schack-Mulligen
a27dac029f Java: Use shared flow summary library for csv models. 2021-04-19 14:02:19 +02:00
Chris Smowton
36abf8733e Merge pull request #5714 from aschackmull/java/add-misc-qltests
Java: Add a few qltests
2021-04-19 13:00:10 +01:00
Taus
9acc71a7cb Python: Get rid of all _attr methods in Django.qll 2021-04-19 11:54:10 +00:00
Erik Krogh Kristensen
9e6f28e335 fix bad join order in Xss.qll 2021-04-19 13:17:49 +02:00
Anders Schack-Mulligen
29aec0d770 Java: Adjust expected output. 2021-04-19 13:16:46 +02:00
Anders Schack-Mulligen
c5193cf03f Apply suggestions from code review 2021-04-19 13:14:56 +02:00
Anders Schack-Mulligen
06514159be Java: Add XXE tests. 2021-04-19 10:58:21 +02:00
Anders Schack-Mulligen
daad62c4e0 Java: Add TaintedPath test. 2021-04-19 10:07:03 +02:00
Jonas Jensen
1ab75eb6f4 Merge pull request #5708 from github/fix-id-in-JsonpInjection-1
Java: Fix id in experimental JsonpInjection.ql query
2021-04-19 08:23:34 +02:00
yoff
118840dad4 Merge pull request #5690 from tausbn/python-disallow-post-update-nodes-as-local-source-nodes
Python: Disallow `PostUpdateNode` as `LocalSourceNode`
2021-04-19 06:56:11 +02:00
ihsinme
c2d97b98e2 Merge branch 'main' into ihsinme-patch-259 2021-04-18 21:01:56 +03:00
Mathias Vorreiter Pedersen
e36b42a03f Java: Fix invalid id in experimental query
The invalid id broke CI here: https://github.com/github/codeql/pull/5703 (see https://github.slack.com/archives/CPSEA0G22/p1618602834224600)
2021-04-17 09:47:15 +02:00
Taus
f3661c34ee Python: Clean up Django models using API graphs
First sweep. Takes care of most of the models.
2021-04-16 19:53:36 +00:00
Mathias Vorreiter Pedersen
95742aec69 C++: Accept test changes for the other experimental query in the directory. This is only a change in line numbers. 2021-04-16 21:29:17 +02:00
Mathias Vorreiter Pedersen
64f8316a6d C++: Tidy up the ql file and accept test changes. 2021-04-16 21:22:13 +02:00
Mathias Vorreiter Pedersen
1e327289b2 C++: Add false negative test. 2021-04-16 18:38:51 +02:00
Mathias Vorreiter Pedersen
50abb6e3a1 C++: Cleanup test.c 2021-04-16 17:32:44 +02:00
Shati Patel
5c2bf68a05 Merge pull request #5692 from tamasvajk/feature/doc-cs9
Update supported C#/.NET versions
2021-04-16 16:22:06 +01:00
Jonas Jensen
f8d45f04ed Revert "Revert "C++: Work around extractor issue CPP-383""
**Revert the revert** of the workaround for CFG issues when a
`FunctionCall` has a `getTarget` that does not exist. While we've fixed
the main cause of the problem, it can apparently still happen in rare
cases as a result of extractor crashes.

This reverts commit ee5eaef5e4.
2021-04-16 16:44:58 +02:00
Tom Hvitved
40b74167e0 C#: Improve performance of DisposeNotCalledOnException.ql 2021-04-16 14:34:16 +02:00
Rasmus Wriedt Larsen
3c8ea167c4 Merge pull request #5668 from tausbn/python-use-api-graphs-in-fabric
Python: Use API graphs in Fabric model
2021-04-16 14:27:55 +02:00
Rasmus Wriedt Larsen
6ed1016bb8 Merge pull request #5669 from tausbn/python-use-api-graphs-for-invoke
Python: Use API graphs for Invoke
2021-04-16 14:27:19 +02:00
Taus
92b4eb7f02 Python: Cleanup and more explanation
Goes into some detail about the intended semantics of local source nodes
and `flowsTo`.
2021-04-16 11:54:20 +00:00
Geoffrey White
e1028a2765 Merge pull request #5667 from MathiasVP/use-range-analysis-in-overflow
C++: Use range analysis in Overflow.qll
2021-04-16 12:00:28 +01:00
Taus
5c79ad2412 Python: Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-16 11:38:29 +02:00
Taus
af0c32c01d Python: Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-16 11:35:12 +02:00
Anders Schack-Mulligen
605f28f741 Merge pull request #5686 from smowton/haby0/JsonHijacking
Java: JSONP Injection w/cleanups
2021-04-16 11:09:17 +02:00
Tom Hvitved
946fcf1c82 C#: Speedup DispatchMethodOrAccessorCall::getAViableOverrider()
In addition to improved performance, the analysis no longer applies a closed-world
assumption to type parameters. That is, if the type of a receiver is a type parameter,
then the call may target any method of a compatible receiver type, not just the
types that actually instantiate the type parameter.
2021-04-16 10:43:17 +02:00
Tamas Vajk
b0975bb3ea Update supported C#/.NET versions 2021-04-16 09:15:43 +02:00
Rasmus Lerchedahl Petersen
a8280f9b12 Python: update test expectation 2021-04-16 08:25:29 +02:00
Rasmus Lerchedahl Petersen
0678745677 Python: refactor based on review suggestion 2021-04-16 08:22:00 +02:00
Rasmus Lerchedahl Petersen
341dbcef2e Python: simplify code following review suggestion
also standardise on camelCase.
2021-04-16 07:41:00 +02:00
Rasmus Lerchedahl Petersen
8aa6b1a87c Python: use standard tracking construction 2021-04-16 07:36:04 +02:00
Taus
451d36dc97 Python: Allow _some_ PostUpdateNodes
Specifically, allow the ones arising from calls, but not reads or
writes. This should fix the tests.
2021-04-15 21:26:12 +00:00
Taus
c9c8259ed0 Python: Disallow PostUpdateNode as LocalSourceNode
Previously, in cases like

```python
def foo(x):
    x.bar()
    x.baz()
    x.quux()
```

we would have flow from the first `x` to each use _and_ flow from the
post-update node for each method call to each subsequent use, and all
of these would be `LocalSourceNode`s. For large functions with the above
pattern, this would lead to a quadratic blowup in `hasLocalSource`.

With this commit, only the first of these will count as a
`LocalSourceNode`, and the blowup disappears.
2021-04-15 17:56:14 +00:00
Andrew Eisenberg
5d827b6fc8 Actions: Change staleness calculation
Calculate staleness on issues that have the
`Stale` label. Leave all other issues untouched.
2021-04-15 10:14:13 -07:00
Rasmus Wriedt Larsen
3e7dc12246 Python: Port taint tests to use inline expectations
The meat of this PR is described in the new python/ql/test/experimental/meta/InlineTaintTest.qll file:

> Defines a InlineExpectationsTest for checking whether any arguments in
> `ensure_tainted` and `ensure_not_tainted` calls are tainted.
>
> Also defines query predicates to ensure that:
> - if any arguments to `ensure_not_tainted` are tainted, their annotation is marked with `SPURIOUS`.
> - if any arguments to `ensure_tainted` are not tainted, their annotation is marked with `MISSING`.
>
> The functionality of this module is tested in `ql/test/experimental/meta/inline-taint-test-demo`.
2021-04-15 18:00:33 +02:00
Chris Smowton
c37994089c Revert changes to unrelated query 2021-04-15 16:24:29 +01:00
Chris Smowton
254de76078 Remove unnecessary stubs 2021-04-15 16:20:27 +01:00
haby0
dedf765542 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-15 22:59:22 +08:00
Rasmus Lerchedahl Petersen
42ae5f4f7d Python: support / from the right
Will also support both operands being paths
2021-04-15 16:07:35 +02:00
Rasmus Wriedt Larsen
b359205d17 Python: Add taint tests for .get() in flask 2021-04-15 14:53:44 +02:00
CodeQL CI
578ce1e512 Merge pull request #5683 from asgerf/js/typescript-template-literal-type-crash
Approved by erik-krogh
2021-04-15 05:11:11 -07:00
Mathias Vorreiter Pedersen
7fbc62358e C++: Accept test changes after making the exprMightOverFlow predicates more sound. 2021-04-15 13:57:44 +02:00
haby0
0e183ab4a4 Finish comment 2021-04-15 19:49:06 +08:00
Chris Smowton
fa36ba901a Merge pull request #5471 from artem-smotrakov/el-injection
Java: Query for detecting Jakarta Expression Language injections
2021-04-15 12:39:34 +01:00
haby0
d269a7e717 CWE-598 reduction 2021-04-15 19:33:15 +08:00
haby0
216f204438 delete FilterClass 2021-04-15 19:28:25 +08:00
haby0
583d0889e2 delete tomcat-embed-core stub, update the ServletGetMethod class 2021-04-15 17:40:51 +08:00
haby0
5d05e4d224 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-15 17:28:53 +08:00
Tom Hvitved
0f24db8759 C#: Improve performance of SsaImpl::CallGraph::SimpleDelegateAnalysis 2021-04-15 11:25:27 +02:00
Asger Feldthaus
f8570bb293 JS: Update TRAP 2021-04-15 10:16:46 +01:00
Rasmus Lerchedahl Petersen
d361d999b7 Python: add some path returning functions
that were only listed as file sytem accesses.
2021-04-15 10:55:09 +02:00
Rasmus Lerchedahl Petersen
02e41d8018 Python: update annotations
This because `resolve` accesses the file system,
I am open to not include that fact in the modelling.
2021-04-15 10:49:22 +02:00
Rasmus Lerchedahl Petersen
3eb1813584 Python: update test expectations 2021-04-15 10:47:49 +02:00
Asger Feldthaus
cb736c8c82 JS: Change note 2021-04-15 09:37:57 +01:00
Tom Hvitved
972cc47f67 Merge pull request #5673 from hvitved/csharp/customizations
C#: Add `Customizations.qll`
2021-04-15 10:24:29 +02:00
Asger Feldthaus
b4a2a9db25 JS: Fix extraction of non-substitution template literal types 2021-04-15 09:23:45 +01:00
Chris Smowton
bd3b3178ba Fix documentation of Modifier.qll 2021-04-15 09:16:51 +01:00
Rasmus Lerchedahl Petersen
c9b2c7885e Python: add changenote 2021-04-15 10:14:35 +02:00
Rasmus Lerchedahl Petersen
52a9040d73 Python update tests 2021-04-15 09:46:53 +02:00
Rasmus Lerchedahl Petersen
2387dc640c Python: Attempts at modelling pathlib-Paths 2021-04-15 09:40:23 +02:00
Rasmus Lerchedahl Petersen
8489403051 Python: Add some tests for pathlib 2021-04-15 09:40:23 +02:00
haby0
b3bdf89fc2 rm VerificationMethodFlowConfig, use springframework-5.2.3 stub 2021-04-15 10:25:40 +08:00
CodeQL CI
4be183c7f6 Merge pull request #5675 from erik-krogh/libXss
Approved by esbena
2021-04-14 14:34:23 -07:00
ihsinme
b30ae3980c Update InsufficientControlFlowManagementAfterRefactoringTheCode.ql 2021-04-14 20:48:20 +03:00
Robert Marsh
fe57876fd8 Merge pull request #5643 from dbartol/smart-pointers/side-effect-refactor
C++: Refactor some side effect generation code
2021-04-14 09:59:41 -07:00
Taus
897d12420b Python: Prevent bad join in isinstanceEvaluatesTo
In some cases, we were joining the result of `val.getClass()` against
the first argument of `Types::improperSubclass` before filtering out the
vast majority of tuples by the call to `isinstance_call`.

To fix this, we let `isinstance_call` take care of figuring out the
class of the value being tested. As a bonus, this cleans up the only
other place where `isinstance_call` is used, where we _also_ want to
know the class of the value being tested in the `isinstance` call.
2021-04-14 16:49:12 +00:00
Artem Smotrakov
97186b3d30 Added comments for tests 2021-04-14 19:30:58 +03:00
Andrew Eisenberg
56ba0f080a Merge pull request #5659 from github/aeisenberg/mark-as-stale
Actions: Add workflow for marking stale questions
2021-04-14 08:37:55 -07:00
Taus
a7fcf52267 Python: Fix bad join in total_cost
The recent change to `appliesTo` lead to a perturbation in the join
order of this predicate, which resulted in a cartesian product between
`call` and `ctx` being created (before being filtered by `appliesTo`).

By splitting the intermediate result into its own helper predicate,
suitably marked to prevent inlining/magic, we prevent this from
happening again.
2021-04-14 15:36:01 +00:00
Andrew Eisenberg
392adf2a25 Workflows: Remove dry-run flag for labeller 2021-04-14 08:25:34 -07:00
Dave Bartolomeo
b29f35f564 Fix formatting 2021-04-14 11:15:16 -04:00
Geoffrey White
64fed4cb10 Merge pull request #5677 from MathiasVP/fix-duplicate-ids-in-experimental
C++: Fix duplicate names in experimental queries
2021-04-14 15:58:49 +01:00
Mathias Vorreiter Pedersen
ed64ed3d8d C++: Make exprMightOverflowPositively/exprMightOverFlowNegatively hold for unanalyzable expressions. This hopefully means that expressions that do not satisfy these predicates will never overflow/underflow. 2021-04-14 16:45:27 +02:00
Jonas Jensen
b4f01c9afa Merge pull request #5578 from MathiasVP/ast-flow-smart-pointers
C++: AST dataflow through smart pointers
2021-04-14 16:39:05 +02:00
Mathias Vorreiter Pedersen
53a320a810 C++: Fix duplicate names. 2021-04-14 16:33:18 +02:00
Mathias Vorreiter Pedersen
bb447d7174 C++: Make sure missingGuardAgainstOverflow (and underflow) holds when range analysis fails to deduce a bound. 2021-04-14 16:30:43 +02:00
yoff
447f339857 Merge pull request #5641 from tausbn/python-use-localsourcenode-in-typetrackers
Python: Use API graphs in PEP249 support
2021-04-14 15:39:49 +02:00
Mathias Vorreiter Pedersen
92508beb82 Merge pull request #5600 from ihsinme/ihsinme-patch-258
CPP: Add query for CWE-691 Insufficient Control Flow Management When Using Bit Operations
2021-04-14 14:55:30 +02:00
Anders Schack-Mulligen
f43d427875 Merge pull request #5645 from Marcono1234/marcono1234/primary-ql-class
Java: Override getAPrimaryQlClass() for more classes
2021-04-14 14:51:29 +02:00
Mathias Vorreiter Pedersen
bc7cc2f7ce C++: Remove rule that wasn't needed. 2021-04-14 14:50:27 +02:00
Mathias Vorreiter Pedersen
da36508714 Revert "C++: As response to the review comments this commit adds a reference-to-pointer state to AddressFlow. A call to an unwrapper function now adds a pointer -> reference-to-pointer transition, and a ReferenceDereference adds a reference-to-pointer -> pointer transition."
This reverts commit 5aeaab7c6d.
2021-04-14 14:41:22 +02:00
Chris Smowton
591ac38c31 Merge pull request #5591 from Marcono1234/marcono1234/member-nested-type
Java: Add MemberType
2021-04-14 12:29:54 +01:00
Taus
54c79bff74 Merge pull request #5666 from RasmusWL/django-refactor
Python: Refactoring and exposing of Django views/fields/forms
2021-04-14 13:07:20 +02:00
Mathias Vorreiter Pedersen
2e40d01397 Update cpp/ql/src/semmle/code/cpp/security/Overflow.qll
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-04-14 13:01:31 +02:00
Rasmus Wriedt Larsen
44d2bf42d7 Merge pull request #5671 from tausbn/python-use-api-graphs-in-werkzeug
Python: Use API graphs in Werkzeug
2021-04-14 12:57:58 +02:00
Erik Krogh Kristensen
fd23e0bdda use more API nodes in XmlParsers, and recognize more results from parsing XML 2021-04-14 11:48:31 +02:00
Anders Schack-Mulligen
3b6cd0f681 Merge pull request #5661 from smowton/smowton/cleanup/call-is-exprparent
Make Call a subclass of ExprParent.
2021-04-14 10:49:33 +02:00
Rasmus Wriedt Larsen
9de8085571 Merge pull request #5665 from tausbn/python-use-api-graphs-in-tornado
Python: Tornado cleanup using API graphs
2021-04-14 10:22:21 +02:00
Rasmus Wriedt Larsen
2d0c9b6bf2 Merge pull request #5670 from tausbn/python-use-api-graphs-in-dill
Python: Use API graphs in Dill model
2021-04-14 10:08:02 +02:00
Rasmus Wriedt Larsen
55723618a9 Python: Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2021-04-14 10:05:50 +02:00
Chris Smowton
2965a1f204 Use Thread$State as an inner-class example
Map<>$Entry currently has odd generic notation that may be about to change.
2021-04-14 08:43:05 +01:00
Chris Smowton
5158e7964e Add change note 2021-04-14 08:25:12 +01:00
Tom Hvitved
36fe72246b C#: Add change note 2021-04-14 09:22:16 +02:00
Tom Hvitved
4810308b16 C#: Add Customizations.qll 2021-04-14 09:16:31 +02:00
haby0
77208bcc91 Fix the error that there is no VerificationMethodToIfFlowConfig 2021-04-14 13:14:43 +08:00
haby0
e2ed0d02b0 Delete existsFilterVerificationMethod and existsServletVerificationMethod, add from get handler to filter 2021-04-14 12:34:52 +08:00
haby0
37dae67a0d Fix RequestResponseFlowConfig.isSink error 2021-04-14 09:55:24 +08:00
Robert Marsh
419d25cbcf Merge pull request #5325 from ihsinme/ihsinme-patch-245
CPP: Add query for CWE-783 Operator Precedence Logic Error When Use Bool Type
2021-04-13 13:24:39 -07:00
Taus
981c5deb57 Merge pull request #5639 from tausbn/python-api-graphs-missing-builtins
Python: Add missing builtins to `API::builtin`
2021-04-13 21:27:52 +02:00
Marcono1234
d853f0c400 Java: Add MemberType 2021-04-13 18:55:20 +02:00
Taus
a6bb9ebb9f Python: Re-introduce abstract toString
This seems like the easier solution in the short run.
2021-04-13 16:08:41 +00:00
Taus
079c7e089d Python: Autoformat 2021-04-13 16:05:45 +00:00
Taus
273e8ce4ef Python: Add change note 2021-04-13 16:04:07 +00:00
haby0
00235ed3b3 Update java/ql/src/semmle/code/java/frameworks/Servlets.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:58:52 +08:00
haby0
25b012db48 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:58:28 +08:00
Taus
5f7d3d0d36 Python: Use API graphs in Werkzeug 2021-04-13 15:57:21 +00:00
haby0
7be45e7c5e Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:56:17 +08:00
haby0
6e73d13670 Update java/ql/src/semmle/code/java/frameworks/Servlets.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:48:45 +08:00
Taus
2890fe6d61 Python: Use API graphs in Dill model
If only all rewrites were this smooth...
2021-04-13 15:26:54 +00:00
Taus
7ed09904b4 Python: Use API graphs for Invoke
A few stragglers remain, as they are modelling the use of decorators.

They will be dealt with at a later date.
2021-04-13 15:21:19 +00:00
Mathias Vorreiter Pedersen
aa52585120 C++: Add change-note. 2021-04-13 17:17:05 +02:00
Marcono1234
89a5acf6e8 Java: Revert overriding XMLFile.getAPrimaryQlClass()
Library file has to be kept in sync with the other languages, however except
cpp none of them have the getAPrimaryQlClass() predicate declared in a
superclass. Therefore for simplicity revert the change for Java.
2021-04-13 17:09:15 +02:00
Taus
7f131c1f35 Python: Get rid of _attr predicates 2021-04-13 14:55:44 +00:00
Taus
1008411594 Python: Use API graphs in Fabric model 2021-04-13 14:49:44 +00:00
Mathias Vorreiter Pedersen
d1457995dd C++: Use range analysis in Overflow.qll 2021-04-13 16:39:28 +02:00
Geoffrey White
8daca01c87 C++: Cleaner use of DataFlow::Node in exprIsSubLeftOrLess. 2021-04-13 15:13:11 +01:00
Geoffrey White
4879104568 C++: Add more dataflow cases to replace the loss. 2021-04-13 15:09:12 +01:00
Geoffrey White
b0ad927fdd C++: Remove useUsePair. 2021-04-13 15:03:06 +01:00
Taus
a404faa302 Python: Use American English in change note
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-04-13 15:05:44 +02:00
Taus
7825a2cdfc Python: Add change note 2021-04-13 12:48:45 +00:00
Taus
1a4845f417 Python: Restrict types a bit
The `CallCfgNode` restrictions are familiar and useful.

Restricting `InstanceSource` to extend `LocalSourceNode` is novel, but I
think it makes sense. It will act as a good reminder to anyone extending
`InstanceSource` that the node in question is a `LocalSourceNode`, which
will be enforced by the return type of the internal type tracker anyway.
2021-04-13 12:28:38 +00:00
Taus
f93b68d4dc Python: Get rid of _attr methods 2021-04-13 12:25:38 +00:00
Taus
98d936d8b3 Python: Tornado cleanup using API graphs
I wasn't able to roll out API graphs as widely in Tornado as I had
hoped, since we're lacking the "def" part. This means most of the
`InstanceSource` machinery will have to stay.
2021-04-13 12:25:38 +00:00
CodeQL CI
f341d5010d Merge pull request #5662 from asgerf/js/simpler-json-api
Approved by erik-krogh
2021-04-13 04:37:56 -07:00
Tom Hvitved
9b0ef2fe21 Merge pull request #5654 from hvitved/csharp/autobuilder/pwsh
C#: First try `pwsh` and then `powershell` when calling `dotnet-install.ps1`
2021-04-13 13:15:01 +02:00
Chris Smowton
58d198261e Merge pull request #5663 from smowton/luchua/java/sensitive-cookie-not-httponly
Java: CWE-1004 Query to check sensitive cookies without the HttpOnly flag set w/minor corrections
2021-04-13 12:08:53 +01:00
CodeQL CI
646639bc73 Merge pull request #5460 from erik-krogh/forgery-2
Approved by asgerf
2021-04-13 03:57:04 -07:00
Chris Smowton
f22b11881e Minimise stubs
By removing all business logic from the stubs, we better test that our analysis treats them as opaque and does not rely on their internal structure
2021-04-13 10:36:28 +01:00
Chris Smowton
45e1a61d7b Mark test as bad-but-missed
This test ought ideally to be caught, but isn't by the current version of the query.
2021-04-13 10:36:27 +01:00
Rasmus Lerchedahl Petersen
30fbb8f1e7 Python: clean up interface 2021-04-13 11:34:47 +02:00
Asger Feldthaus
e77117f902 JS: Autoformat 2021-04-13 10:29:14 +01:00
Asger Feldthaus
929d9da4b4 JS: Migrate to new JSON API 2021-04-13 10:29:13 +01:00
Asger Feldthaus
7c13163413 JS: Lift JSON accessors to JSONValue 2021-04-13 10:29:13 +01:00
Rasmus Lerchedahl Petersen
178cb6c90f Python: Bit too eager with the modernisation...
Lift type restrictions to recover results.
2021-04-13 11:26:05 +02:00
Rasmus Lerchedahl Petersen
7c0b0642c8 Python: Add imports to make code compile 2021-04-13 11:09:27 +02:00
Tom Hvitved
15c103e42d C#: Remove code duplication in BuildScripts.cs 2021-04-13 10:57:15 +02:00
Chris Smowton
dee974ff2d Make Call a subclass of ExprParent. All of its subclasses are in any case (via Expr or Stmt) 2021-04-13 09:13:47 +01:00
Marcono1234
c37dbb2e68 Java: Override getAPrimaryQlClass() for more classes 2021-04-13 08:46:01 +01:00
Mathias Vorreiter Pedersen
3cfd30ef6f Merge pull request #5629 from hvitved/cpp/remove-unique
C++: Remove `unique` wrapper from `DataFlow::Node::getEnclosingCallable`
2021-04-13 09:42:34 +02:00
haby0
be39883166 Change the class name and comment,Use .(CompileTimeConstantExpr).getStringValue() 2021-04-13 14:10:10 +08:00
Dave Bartolomeo
afd2f58f9f C++: Fix PR feedback 2021-04-12 18:21:05 -04:00
Dave Bartolomeo
697b2dcde8 C++: Add missing store step for single-field struct use
We have special code to handle field flow for single-field structs, but that special case was too specific. Some `Store`s to single-field structs have no `Chi` instruction, which is the case that we handled already. However, it is possible for the `Store` to have a `Chi` instruction (e.g. for `{AllAliased}`), but still have a use of the result of the `Store` directly. We now add a `PostUpdateNode` for the result of the `Store` itself in those cases, just like we already did if the `Store` had no `Chi`.
2021-04-12 18:11:41 -04:00
Rasmus Lerchedahl Petersen
b6bd782746 Python: Modernize via CallCfgNode 2021-04-12 23:55:59 +02:00
yoff
e4d74cf098 Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-12 23:47:54 +02:00
Robert Marsh
0102d68f38 Merge pull request #5658 from MathiasVP/fix-partial-def-diff-test
C++: Fix performance in test
2021-04-12 13:08:30 -07:00
Andrew Eisenberg
e0fcb15739 Actions: Add workflow for marking stale questions
This PR adds a workflow for marking and closing issues as stale. Issues must be labeled as _question_. PRs are never marked as stale.
2021-04-12 13:05:53 -07:00
Artem Smotrakov
b96b665262 Renaming in java/ql/src/experimental/Security/CWE/CWE-094 2021-04-12 21:40:49 +03:00
Mathias Vorreiter Pedersen
037e6369ce C++: Ensure all values are bound in both disjunctions. 2021-04-12 18:27:21 +02:00
luchua-bc
d7f26dfc18 Update stub classes and qldoc 2021-04-12 16:19:23 +00:00
Taus
fda750ef26 Merge pull request #5642 from tausbn/python-use-api-graphs-in-stdlib
Python: Use API graphs in `Stdlib.qll`
2021-04-12 18:05:38 +02:00
Chris Smowton
423ff32d04 Merge pull request #5384 from luchua-bc/java/insecure-spring-actuator-config
Java: CWE-016 Query to detect insecure configuration of Spring Boot Actuator
2021-04-12 17:04:47 +01:00
Taus
6d4ddc0329 Merge pull request #5614 from tausbn/python-allow-absolute-imports-from-source-directory
Python: Allow absolute imports from source directory
2021-04-12 18:02:00 +02:00
CodeQL CI
bc56d16c18 Merge pull request #5485 from RasmusWL/django-queryset-chains
Approved by tausbn
2021-04-12 08:49:31 -07:00
Tom Hvitved
dfc91b8331 C#: Simplify dotnet-install.ps1 invocation
Using the pattern from https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script.
2021-04-12 17:33:33 +02:00
Chris Smowton
bb23866cec Add missing doc comments 2021-04-12 16:33:01 +01:00
Tom Hvitved
d35a501121 Merge pull request #5583 from lcartey/cs/restrict-jump-to-def
C#: Exclude jump-to-def information for elements with too many locations
2021-04-12 16:52:20 +02:00
ihsinme
a43698802f Update InsufficientControlFlowManagementWhenUsingBitOperations.ql 2021-04-12 17:36:50 +03:00
CodeQL CI
310a2c8bb3 Merge pull request #5655 from erik-krogh/cert
Approved by esbena
2021-04-12 07:31:04 -07:00
Chris Smowton
2656a52880 Merge pull request #5538 from luchua-bc/java/credentials-in-properties
Java: CWE-555 Query to detect plaintext credentials in Java properties files
2021-04-12 15:22:21 +01:00
Chris Smowton
abeefcaced Merge pull request #4947 from porcupineyhairs/DexLoading
Java : add query to detect insecure loading of Dex File
2021-04-12 15:22:12 +01:00
Asger Feldthaus
d2fad180f8 JS: Add test 2021-04-12 15:07:45 +01:00
Mathias Vorreiter Pedersen
5aeaab7c6d C++: As response to the review comments this commit adds a reference-to-pointer state to AddressFlow. A call to an unwrapper function now adds a pointer -> reference-to-pointer transition, and a ReferenceDereference adds a reference-to-pointer -> pointer transition. 2021-04-12 16:01:01 +02:00
ihsinme
58d5ad48d5 Update InsufficientControlFlowManagementAfterRefactoringTheCode.ql 2021-04-12 17:00:34 +03:00
ihsinme
d7c14775bf Update InsufficientControlFlowManagementAfterRefactoringTheCode.qhelp 2021-04-12 16:56:48 +03:00
Chris Smowton
11bf982728 Remove superfluous linebreaks in qhelp file 2021-04-12 14:36:42 +01:00
Asger Feldthaus
24de826133 JS: Add file diagnostics errors 2021-04-12 14:11:38 +01:00
Erik Krogh Kristensen
32737a17fb add change note 2021-04-12 15:09:13 +02:00
Erik Krogh Kristensen
172d6139e2 support all ClientRequests in js/disabling-certificate-validation 2021-04-12 15:06:10 +02:00
luchua-bc
c281e54d22 Remove unused files and update qldoc 2021-04-12 13:05:01 +00:00
Tom Hvitved
57016ddbde C++: Remove unique wrapper from DataFlow::Node::getEnclosingCallable() 2021-04-12 14:41:52 +02:00
Tom Hvitved
7d2a60e910 Merge pull request #5640 from hvitved/dataflow/path-step-perf
Data flow: Prevent bad join-order in `pathStep`
2021-04-12 14:40:46 +02:00
Tamas Vajk
b4d35b52c3 C#: Add Console.Read* to local flow sources 2021-04-12 14:19:17 +02:00
Tom Hvitved
5446532e1d C#: Update auto-builder tests 2021-04-12 14:01:55 +02:00
Anders Schack-Mulligen
acd4cf2878 Merge pull request #5636 from aschackmull/java/shared-flow-summaries
Java: Adopt shared flow summaries
2021-04-12 13:35:31 +02:00
CodeQL CI
e8d835b422 Merge pull request #5638 from erik-krogh/smartInliner
Approved by esbena
2021-04-12 04:17:25 -07:00
Tom Hvitved
c7686b1838 C#: First try pwsh and then powershell when calling dotnet-install.ps1 2021-04-12 13:01:14 +02:00
Tom Hvitved
cf5f838b13 Data flow: Remove recommendation to use unique in Node::getEnclosingCallable() 2021-04-12 12:04:23 +02:00
Anders Schack-Mulligen
e003b04061 Merge pull request #5637 from Marcono1234/marcono1234/toString-method
Java: Add ToStringMethod
2021-04-12 11:43:55 +02:00
Max Schaefer
cd57e61f65 Rename MkHasUnderlyingType to MkTypeUse. 2021-04-12 11:30:15 +02:00
Erik Krogh Kristensen
91d28fb8b0 cleanup in API-graphs 2021-04-12 11:30:15 +02:00
CodeQL CI
63f087a8e9 Merge pull request #5653 from erik-krogh/givenCommand
Approved by asgerf
2021-04-12 02:01:32 -07:00
Rasmus Wriedt Larsen
364d48948f Merge pull request #3810 from dilanbhalla/syntaxpython
Python: Function/Class Naming Convention (Syntax)
2021-04-12 10:42:17 +02:00
Rasmus Lerchedahl Petersen
3ff8e010b2 Python: Refactor based on review
- more natural handling of default arguments
- do not assume default construction gives a family
- simplifies `UnspecificSSLContextCreation`
2021-04-12 10:00:07 +02:00
Rasmus Lerchedahl Petersen
9f91dde76f Python: Update test expectation after comment 2021-04-12 09:58:06 +02:00
Erik Krogh Kristensen
17c4bbbc4e allow parameters that end with "Command" in js/shell-command-constructed-from-input 2021-04-12 09:57:40 +02:00
haby0
1b948ac2e2 Combine two Configurations into one 2021-04-12 15:44:39 +08:00
Rasmus Lerchedahl Petersen
036fddfdb5 Python: Namable -> Nameable 2021-04-12 08:18:24 +02:00
yoff
02d6de81a7 Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2021-04-12 08:16:36 +02:00
ihsinme
feb3a8deb1 Update InsufficientControlFlowManagementAfterRefactoringTheCode.expected 2021-04-12 08:23:41 +03:00
ihsinme
6924c6c51c Update test.c 2021-04-12 08:23:06 +03:00
ihsinme
3da88f2103 Update InsufficientControlFlowManagementAfterRefactoringTheCode.c 2021-04-12 08:15:36 +03:00
ihsinme
17d1c77a14 Update InsufficientControlFlowManagementAfterRefactoringTheCode.ql 2021-04-12 08:14:17 +03:00
yo-h
4f2060f96b Merge commit '2d618d6b928d8b76ac8033b3b63d9bde71caa325' into yo-h/java16 2021-04-11 23:55:33 -04:00
Taus
10be2735ec Python: Get rid of _attr predicates
Also changes all `CfgNode`s representing calls to `CallCfgNode`s.
2021-04-10 12:12:18 +00:00
intrigus
8d11bc97ca [Java] Add "missing jwt signature check" qhelp. 2021-04-10 13:36:22 +02:00
haby0
d90527bead JsonpInjectionExpr updated to JsonpBuilderExpr 2021-04-10 10:33:21 +08:00
Marcono1234
9349e6922d Java: Add ToStringMethod 2021-04-10 04:00:44 +02:00
haby0
eeae91e620 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:48:55 +08:00
haby0
046aeaa38c Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:37:29 +08:00
haby0
8b756d7f1b Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:27:03 +08:00
haby0
650446f761 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:26:32 +08:00
haby0
a5ebe8c600 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:26:08 +08:00
porcupineyhairs
8687c5c145 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:18:35 +05:30
haby0
8a7d28a2ed Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:29:49 +08:00
haby0
4c21980d4f Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:29:30 +08:00
haby0
9635a36044 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:29:06 +08:00
haby0
760231c004 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:28:17 +08:00
haby0
c77c7b0a98 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:27:16 +08:00
haby0
837f20108d Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:25:43 +08:00
haby0
157e4670fd Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:25:11 +08:00
haby0
79c1374925 Update java/ql/src/semmle/code/java/frameworks/Servlets.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:24:49 +08:00
haby0
1510048f7a Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:23:13 +08:00
haby0
d8165145c7 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:22:44 +08:00
haby0
ebd38eaf3b Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:22:08 +08:00
haby0
b8c11503f0 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:21:49 +08:00
Dave Bartolomeo
0a86642056 C++: Refactor some side effect generation code
This change was necessary for my upcoming changes to introduce side effect instructions for indirections of smart pointers. The code to decide which parameters have which side effects appeared in both the IPA constructor for `TTranslatedSideEffect` and in `TranslatedCall`. These two versions didn't quite agree, especially once the `SideEffectFunction` model provides its own side effects instead of the defaults.
The relevant code has now been factored out into `SideEffects.qll`. This queries the model if one exists, and provides default side effects if no model exists. This fixes at least one existing issue, where we were emitting a buffer read side effect for `*this` instead of an indirect read side effect. This accounts for all of the IR diffs in the tests.
2021-04-09 16:14:03 -04:00
luchua-bc
4e3791dc0d Remove LoadCredentialsConfiguration and update qldoc 2021-04-09 19:36:35 +00:00
Taus
720fbaf301 Python: Fix test error.
Somehow, having to type "Node" all day long made me turn "json" into
"node"...

Also removes some bits that weren't needed after all.
2021-04-09 19:04:49 +00:00
Mathias Vorreiter Pedersen
1510fe370d C++: Add cases for const pointer wrapper references to AddressFlow and FlowVar. 2021-04-09 20:58:05 +02:00
Mathias Vorreiter Pedersen
2329b31601 C++: Replace the new SmartPointerPartialDefinition with additional steps in AddressFlow.qll 2021-04-09 20:49:45 +02:00
Mathias Vorreiter Pedersen
a460e3ad3d Merge branch 'main' into ast-flow-smart-pointers 2021-04-09 19:41:10 +02:00
Geoffrey White
40637c18ce C++: Add change note. 2021-04-09 18:14:12 +01:00
Geoffrey White
0818c1d703 C++: Update QLDoc. 2021-04-09 18:11:48 +01:00
Taus
cc4827600b Python: Use API graphs in Stdlib.qll
Eliminates _almost_ all of the bespoke type trackers found here. The
ones that remain do not fit easily inside the framework of API graphs
(at least, not yet), and I did not see any easy ways to clean them up.
They have, however, been rewritten to use `LocalSourceNode` internally,
which was the primary goal of this exercise.

I'm sure we could also clean up many of the inner modules given the more
lean presentation we have now, but this can wait for a different PR.
2021-04-09 17:11:47 +00:00
luchua-bc
04b0682bbf Use isAdditionalTaintStep and make the query more readable 2021-04-09 16:14:51 +00:00
Tom Hvitved
fd8f745468 Java: Adopt shared flow summary library and refactor data-flow nodes. 2021-04-09 16:57:03 +02:00
Shati Patel
2d618d6b92 Merge pull request #5625 from shati-patel/docs/cli-manual
Docs: Link to CodeQL CLI manual from the sidebar
2021-04-09 15:30:24 +01:00
Tom Hvitved
f130616369 Data flow: Make getLocalCc private again 2021-04-09 16:22:58 +02:00
Geoffrey White
3b437fe6cf C++: Replace GVN with some other libraries. 2021-04-09 15:21:42 +01:00
Taus
d2b874f217 Python: Use API graphs in PEP249 support
Because the replacement extension point now extends `API::Node`, I
modified the `toString` method of the latter to have an empty body.
The alternative would be to require everyone to provide a `toString`
predicate for their extensions, but seeing as these will usually be
pointing to already existing API graph nodes, this seems silly.

(This may be the reason why the equivalent method in the JS libs has
such an implementation.)
2021-04-09 14:19:00 +00:00
Jonas Jensen
e1d0bbb021 Merge pull request #5607 from MathiasVP/smart-pointer-ast-read-store-steps
C++: read and store steps for smart pointers in AST dataflow
2021-04-09 16:11:48 +02:00
CodeQL CI
6fd4a8afff Merge pull request #5567 from asgerf/js/sql-models
Approved by esbena
2021-04-09 07:11:10 -07:00
CodeQL CI
be2fe6e171 Merge pull request #5630 from erik-krogh/urlStep
Approved by esbena
2021-04-09 07:05:43 -07:00
CodeQL CI
8d2768b2ce Merge pull request #5634 from erik-krogh/fileSource
Approved by asgerf
2021-04-09 07:04:42 -07:00
Anders Schack-Mulligen
701e815368 Merge pull request #5628 from hvitved/java/remove-unique
Java: Remove `unique` wrapper from `DataFlow::Node::getEnclosingCallable()`
2021-04-09 15:21:26 +02:00
Mathias Vorreiter Pedersen
cd310eb9d5 C++: Remove unused import. 2021-04-09 15:08:48 +02:00
Tamás Vajk
992a4df12f Merge pull request #5619 from tamasvajk/feature/fix-default-argument-value-extraction
C# Improve default argument value extraction
2021-04-09 14:58:35 +02:00
Mathias Vorreiter Pedersen
996cda9b97 C++: Fix incorrect test annotation. 2021-04-09 14:46:46 +02:00
Tom Hvitved
6874b8d4b3 Data flow: Prevent bad join-order in pathStep 2021-04-09 14:24:47 +02:00
Mathias Vorreiter Pedersen
80d5b17900 C++: Remove the dataflow rule for smart_ptr -> *smart_ptr. 2021-04-09 14:20:51 +02:00
Mathias Vorreiter Pedersen
cae0060a89 C++: Replace the new rules in DataFlowUtil with a dataflow model for pointer wrapper classes. 2021-04-09 14:06:58 +02:00
Taus
affdedd840 Python: Add missing builtins to API::builtin
We were missing out on `None`, `True`, and `False` as these do not
appear as actual attributes of the `builtins` module in Python 3
(because they are elevated to the status of keywords there)

The simple solution, then, is to just always include them directly.
2021-04-09 12:02:07 +00:00
Tamas Vajk
46197e6e69 Address review comments 2021-04-09 13:39:37 +02:00
Tamas Vajk
351f35d9bc Revert "Java: Convert other sinks"
This reverts commit 87d42b02c0.
2021-04-09 13:13:49 +02:00
Tamas Vajk
87d42b02c0 Java: Convert other sinks 2021-04-09 13:13:39 +02:00
Tamas Vajk
3e53484bb3 Java: Convert Google HTTP client API parseAs sink to CSV format 2021-04-09 13:10:44 +02:00
Tamas Vajk
e544faed6d Java: Convert unsafe hostname verification sinks to CSV format 2021-04-09 13:10:44 +02:00
Tamas Vajk
17fd758df1 Java: Convert XSS sinks to CSV format 2021-04-09 13:10:44 +02:00
Erik Krogh Kristensen
595bdedb22 rename predicate to getStem, and update regexp 2021-04-09 13:07:54 +02:00
Tamas Vajk
0b7a6671dd Java: Convert header splitting sinks to CSV format 2021-04-09 13:06:05 +02:00
Tamas Vajk
f329c3fdab Java: Convert insecure bean validation sink to CSV format 2021-04-09 13:06:04 +02:00
Mathias Vorreiter Pedersen
0a6aef71a2 C++: Respond to review comments. 2021-04-09 12:29:13 +02:00
CodeQL CI
652e8b4872 Merge pull request #5586 from asgerf/js/tsconfig-file-inclusion-handling
Approved by esbena
2021-04-09 02:50:51 -07:00
Tamas Vajk
9e2832a82d Java: Convert zipslip sinks to CSV format 2021-04-09 11:43:29 +02:00
Tamas Vajk
b9ce1aefc0 Java: Convert unsafe URL opening sinks to CSV format 2021-04-09 11:43:29 +02:00
Tom Hvitved
c9c4c067b6 Merge pull request #5633 from hvitved/csharp/get-a-source-type-perf
C#: Improve performance of `Dispatch::SimpleTypeDataFlow::getASourceType()`
2021-04-09 11:42:34 +02:00
Tamás Vajk
a335bb0115 Merge pull request #5609 from tamasvajk/feature/dapper
C#: Dapper support
2021-04-09 10:52:17 +02:00
CodeQL CI
ad267404c9 Merge pull request #5137 from asgerf/js/redux-less
Approved by erik-krogh
2021-04-09 01:24:19 -07:00
Tamas Vajk
d7f0b9a7fa Add change note 2021-04-09 09:58:37 +02:00
Tamas Vajk
749db379ca Address code review findings 2021-04-09 09:55:37 +02:00
Tamas Vajk
dbb3d3dc17 Add change note 2021-04-09 09:50:55 +02:00
Tamas Vajk
53daa7c436 Java: Migrate LDAP injection sinks to CSV format 2021-04-09 09:15:47 +02:00
luchua-bc
11304b2ae1 Update qldoc and change the wrapper method implementation 2021-04-09 02:21:59 +00:00
Erik Krogh Kristensen
7f01586bf1 fix bad join order in getDocumentedParameter 2021-04-09 01:15:46 +02:00
Erik Krogh Kristensen
e5bce548de add nomagic on mayHaveStringValue 2021-04-09 00:08:51 +02:00
Erik Krogh Kristensen
956311457d fixed bad SourceNode X SourceNode join in HTTP model 2021-04-08 21:15:50 +02:00
ihsinme
9b3ccade43 Update test.c 2021-04-08 22:06:35 +03:00
ihsinme
3d117243e4 Update test.c 2021-04-08 22:05:31 +03:00
ihsinme
02eb447a35 Update InsufficientControlFlowManagementWhenUsingBitOperations.expected 2021-04-08 22:04:08 +03:00
ihsinme
a6b486a448 Update InsufficientControlFlowManagementWhenUsingBitOperations.ql 2021-04-08 22:01:43 +03:00
Dilan
d73ba13b28 autoformat fix 2021-04-08 11:41:58 -07:00
Artem Smotrakov
b39a3ab12c Added setVariable() sink 2021-04-08 20:41:43 +03:00
Tamás Vajk
8adaee05b6 Merge pull request #5453 from tamasvajk/feature/use_codeql_stubs
C#: Adjust make_stubs.py to use codeql instead of odasa
2021-04-08 16:16:05 +02:00
Anders Schack-Mulligen
6109ef5e88 Merge pull request #5475 from Marcono1234/marcono1234/minus-literal
Java: Improve documentation regarding minus in front of numeric literals
2021-04-08 16:11:14 +02:00
Asger Feldthaus
7d300b53d7 JS: Autoformat 2021-04-08 15:06:48 +01:00
Anders Schack-Mulligen
d42a01cb3a qldoc fixup 2021-04-08 15:45:21 +02:00
Tamas Vajk
e5160929eb Remove ODASA reference from make_stubs.py 2021-04-08 15:04:02 +02:00
Erik Krogh Kristensen
30ba69d991 treat "files" in a package.json as main modules, if "main" is not present 2021-04-08 14:42:12 +02:00
Tom Hvitved
036e181bc1 C#: Improve performance of Dispatch::SimpleTypeDataFlow::getASourceType() 2021-04-08 14:27:28 +02:00
Tom Hvitved
716568ebd1 Merge pull request #5623 from hvitved/csharp/enclosing
C#: Compute enclosing callable as a transitive closure
2021-04-08 14:20:09 +02:00
Tom Hvitved
9820116734 Merge pull request #5603 from hvitved/csharp/dataflow/no-unique
C#: Remove `unique` wrappers from `DataFlow::Node::get(EnclosingCallable|ControlFlowNode)`
2021-04-08 14:19:34 +02:00
Asger Feldthaus
52a2260dc7 JS: Rename change note file 2021-04-08 12:52:23 +01:00
Rasmus Wriedt Larsen
c738f387b1 Merge pull request #5624 from tausbn/python-make-callcfgnode-a-localsourcenode
Python: Improve `CallCfgNode` interface
2021-04-08 13:38:24 +02:00
haby0
1da48ed4d1 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-08 19:22:14 +08:00
haby0
bfbfe7af13 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSource.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-08 19:21:58 +08:00
haby0
21004006d6 Update java/ql/src/experimental/Security/CWE/CWE-348/UseOfLessTrustedSourceLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-08 19:17:04 +08:00
Taus
cf5f760ecd Merge pull request #5582 from RasmusWL/all-tuple
Python: Add support for `__all__` assigned to tuple
2021-04-08 13:03:27 +02:00
Rasmus Wriedt Larsen
83477439a1 Python: Make django views/fields/forms class modeling extensible
This also requires that we make this part of the modeling public, which I guess
is step we want to take eventually anyway!

I'm not quite sure whether the modules `Django::Views` and `Django::Forms` are
actually helpful, or whether we should just have their modules available as
`Django::View`, `Django::Form`, and `Django::Field`...
2021-04-08 12:45:37 +02:00
Rasmus Wriedt Larsen
b7483a5394 Python: Add modeledSubclassRef for Django views/fields/forms 2021-04-08 12:45:36 +02:00
Rasmus Wriedt Larsen
322bdcb703 Python: Port Django view modeling to API graphs 2021-04-08 12:45:35 +02:00
Rasmus Wriedt Larsen
8ce5c46e05 Python: Minor refactor
modName/clsName _is_ shorter, but also looks way worse :D
2021-04-08 12:45:34 +02:00
Tamas Vajk
a790eb8110 Fix for unconstrained generic types 2021-04-08 12:20:01 +02:00
Tamas Vajk
a8cbdc92b9 Add more test cases 2021-04-08 12:17:19 +02:00
Tamas Vajk
551a7ce9e5 Fix expression value of struct default argument values 2021-04-08 12:14:53 +02:00
Tamas Vajk
c069c3384e Fix tests 2021-04-08 12:07:36 +02:00
Tamas Vajk
cb9a9db356 C# Improve default argument value extraction 2021-04-08 12:07:22 +02:00
Tamas Vajk
2ac1e60406 C#: Add parameter default value tests 2021-04-08 12:04:18 +02:00
haby0
86ef2588f1 Restore @Component annotation 2021-04-08 17:55:29 +08:00
Jonas Jensen
51bab81f56 Merge pull request #5622 from MathiasVP/inline-is-before
C++: Inline Location::isBefore
2021-04-08 11:24:33 +02:00
haby0
3f0a3266aa [Java] CWE-348: Use of less trusted source 2021-04-08 17:14:03 +08:00
Erik Krogh Kristensen
99dd5330c2 add taint-step for URL construction in js/request-forgery 2021-04-08 11:10:33 +02:00
Geoffrey White
517fd23ca5 C++: Correct and add to test cases. 2021-04-08 09:48:38 +01:00
CodeQL CI
a9527fd913 Merge pull request #5621 from erik-krogh/shellSink
Approved by esbena
2021-04-08 09:47:45 +01:00
Tom Hvitved
2faf52b6bd Java: Remove unique wrapper from DataFlow::Node::getEnclosingCallable()` 2021-04-08 10:07:19 +02:00
Dilan
675de07c3e autoformat ql 2021-04-07 15:04:18 -07:00
ihsinme
ed34c96357 Update InsufficientControlFlowManagementWhenUsingBitOperations.ql 2021-04-07 21:40:49 +03:00
ihsinme
eb9b41acab Apply suggestions from code review
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-04-07 21:31:12 +03:00
Artem Smotrakov
a764a79090 Always bind arguments in TaintPropagatingCall 2021-04-07 21:12:21 +03:00
Artem Smotrakov
c13ee0859a LambdaExpression should extend JakartaType 2021-04-07 21:02:21 +03:00
Shati Patel
4cf0b8e725 Merge pull request #5626 from shati-patel/docs/broken-links
Docs: Fix broken link to cached "RemoteFlowSource"
2021-04-07 19:01:33 +01:00
Artem Smotrakov
3d8e173c57 Removed a reference to Apache Commons EL 2021-04-07 20:59:07 +03:00
Artem Smotrakov
80ac2aff26 Fixed typos
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-04-07 20:55:03 +03:00
Shati Patel
f372274857 Docs: Fix broken links 2021-04-07 18:02:29 +01:00
Shati Patel
2373bf2dfb Docs: Link to CodeQL CLI manual from the sidebar 2021-04-07 17:55:05 +01:00
Tom Hvitved
1cf30d2a9e C#: Compute enclosing callable as a transitive closure 2021-04-07 17:44:41 +02:00
Jonas Jensen
ab58cb3d44 Merge pull request #5604 from MathiasVP/fix-false-positive-in-assign-where-compare-meant
C++: Fix FP in cpp/assign-where-compare-meant
2021-04-07 16:54:45 +02:00
CodeQL CI
f0491af64c Merge pull request #5529 from erik-krogh/socketInput
Approved by esbena
2021-04-07 15:03:13 +01:00
Asger F
0c724a8427 Merge pull request #5304 from asgerf/js/non-alert-data
JS: Implement new metric queries for line counting
2021-04-07 14:52:51 +01:00
yoff
38daeb4df2 Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-07 15:50:51 +02:00
Mathias Vorreiter Pedersen
03b12dbc6d C++: Inline Location::isBefore. 2021-04-07 15:45:08 +02:00
Erik Krogh Kristensen
365b4d722d backtrack string-concatenations from shell-execution sinks 2021-04-07 15:34:54 +02:00
Taus
903f364dab Python: Improve CallCfgNode interface
Call nodes are always local sources (specifically sources of the return
value of the call), and so inheriting from `LocalSourceNode` will have
no effect on results, but _should_ make it a bit more smooth to use the
API.
2021-04-07 13:31:12 +00:00
CodeQL CI
073a43ce74 Merge pull request #5606 from erik-krogh/shellInput
Approved by esbena
2021-04-07 14:30:31 +01:00
Shati Patel
461d4e45af Merge pull request #5608 from shati-patel/docs/telemetry-settings
Docs: Mention telemetry in "customizing settings"
2021-04-07 13:44:32 +01:00
Erik Krogh Kristensen
c9f54ea1ad update expected output 2021-04-07 12:37:17 +00:00
Asger Feldthaus
ee13ff71d6 JS: Add another change note 2021-04-07 12:29:06 +01:00
Asger Feldthaus
26cddc7d04 JS: Update test output 2021-04-07 12:28:45 +01:00
Taus
6c69c1aeeb Python: Minor cleanup 2021-04-07 10:47:21 +00:00
Asger Feldthaus
69973d0fa2 JS: Autoformat 2021-04-07 11:24:11 +01:00
ihsinme
cbf158ea6b Add files via upload 2021-04-07 13:12:30 +03:00
ihsinme
36de496d47 Add files via upload 2021-04-07 13:12:29 +03:00
ihsinme
ed2a8db8c9 Add files via upload 2021-04-07 13:10:01 +03:00
ihsinme
9c3b7e81c7 Add files via upload 2021-04-07 13:10:00 +03:00
Erik Krogh Kristensen
a66083d685 change "Uncontrolled path" to "Path concatenation" 2021-04-07 08:23:07 +00:00
CodeQL CI
fd4e8f8282 Merge pull request #5526 from erik-krogh/quotedShell
Approved by esbena
2021-04-07 08:39:01 +01:00
CodeQL CI
61880ba90a Merge pull request #5530 from erik-krogh/moreFS
Approved by esbena
2021-04-07 08:37:23 +01:00
Rasmus Lerchedahl Petersen
a006a92f8d Python: Expand commentary 2021-04-07 08:32:40 +02:00
Rasmus Lerchedahl Petersen
f22db2a30b Python: One family to rule them all... 2021-04-07 08:32:21 +02:00
Rasmus Lerchedahl Petersen
a0e3e3afaf Python: adjust test expectations 2021-04-07 08:22:36 +02:00
Rasmus Lerchedahl Petersen
fb95c488e8 Python: format 2021-04-07 08:20:52 +02:00
Robert Marsh
e22ec50dee Merge pull request #5613 from github/hmakholm/pr/fix-redos
Fix ReDOS in cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql
2021-04-06 15:54:27 -07:00
Geoffrey White
a8193dac08 C++: Reintroduce the exprMightOverflowNegatively bit. 2021-04-06 22:36:59 +01:00
Geoffrey White
60e4faba4c C++: Add linear expression logic. 2021-04-06 22:28:36 +01:00
Geoffrey White
48ff8e237c C++: Rewrite the range analysis exclusion to be recursive and more robust. 2021-04-06 22:26:55 +01:00
Geoffrey White
3ecd13531f C++: Improve isGuarded. 2021-04-06 22:21:59 +01:00
Geoffrey White
59ff3f315b C++: Add test cases exploring issues and potential issues with the query (especially related to simple range analysis). 2021-04-06 22:21:25 +01:00
Rasmus Lerchedahl Petersen
094d2f3b7d Python: clean up tests 2021-04-06 22:59:58 +02:00
Rasmus Lerchedahl Petersen
a44490b470 Python: remove unused file 2021-04-06 22:56:07 +02:00
Rasmus Lerchedahl Petersen
0626684442 Python: small cleanups enabled by review 2021-04-06 22:55:32 +02:00
yoff
acf8fd0f03 Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-06 22:45:03 +02:00
Taus
a93132daae Merge branch 'python-allow-absolute-imports-from-source-directory' of https://github.com/tausbn/codeql into python-allow-absolute-imports-from-source-directory 2021-04-06 19:58:57 +00:00
Taus
43ae7462b4 Python: Only track modules that are imported
This greatly restricts the set of modules that have a new name under
this scheme.

One change to the tests was needed, which reflects the fact that the
two `main.py` files no longer have the name `main` (which makes sense,
since they're never imported under this name).
2021-04-06 21:56:12 +02:00
Taus
b44db460f6 Python: Only track modules that are imported 2021-04-06 19:55:43 +00:00
Henning Makholm
2d615ef503 Fix ReDOS in cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql
The sub-regex `(\s|.)*` aims to capture arbitrary string content
(in contrast to `.*` which doesn't match newlines), but it is
unsafe, since non-newline whitespace can match both alternatives.

This caused an evaluator crash in the wild.

Replace with `[\s\S]*`, which matches everything in a safe way.
2021-04-06 20:10:57 +02:00
yo-h
cc63563a88 Merge remote-tracking branch 'upstream-public/main' into yo-h/java16 2021-04-06 13:16:02 -04:00
Taus Brock-Nannestad
8e11abca40 Revert "Merge pull request #5552 from RasmusWL/revert-import-change"
This reverts commit 49d1937dc4, reversing
changes made to d4877a9038.
2021-04-06 17:39:41 +02:00
Tamas Vajk
ffcb345916 C#: Add Dapper support to SQL injection queries 2021-04-06 17:06:20 +02:00
Shati Patel
9a41c80626 Merge pull request #5574 from github/smowton/admin/update-supported-go-version
Update supported Go version to 1.16
2021-04-06 14:54:36 +01:00
Shati Patel
695b02a94c Docs: Mention telemetry in "customizing settings" 2021-04-06 14:30:17 +01:00
Erik Krogh Kristensen
2c1cc9ead6 use local variable instead of module.exports in example
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-04-06 15:17:31 +02:00
Tom Hvitved
f45916efda Merge pull request #5605 from hvitved/csharp/exclude-dependency-queries
C#: Remove mentions of `exclude-dependency-queries.yml`
2021-04-06 14:58:49 +02:00
Mathias Vorreiter Pedersen
8382e85901 C++: Add flow into the source of read step and out of the target of a store step for smart pointers in AST dataflow. 2021-04-06 14:05:55 +02:00
Mathias Vorreiter Pedersen
f07d844362 C++: Add a test containing missing read/store dataflow steps for smart pointers. 2021-04-06 13:59:27 +02:00
Tamas Vajk
98001c494f C#: Add Dapper stub and new SqlInjection test cases 2021-04-06 13:30:31 +02:00
Erik Krogh Kristensen
41b89669a9 add joined paths as a sink to js/shell-command-constructed-from-input 2021-04-06 12:14:00 +02:00
Rasmus Wriedt Larsen
bc49bc7095 Python: Add variable with underscore to __all__ tests 2021-04-06 11:54:25 +02:00
Tom Hvitved
e0e58b24ea C#: Remove mentions of exclude-dependency-queries.yml 2021-04-06 11:50:36 +02:00
Rasmus Wriedt Larsen
224d3790b5 Python: Highlight all_indirect.py is not super important
At least not in my mind
2021-04-06 11:50:04 +02:00
Rasmus Wriedt Larsen
b11703cc74 Python: all_dybamic2 => all_indirect 2021-04-06 11:49:55 +02:00
Mathias Vorreiter Pedersen
5eb1f8abbd C++: Add change-note. 2021-04-06 11:47:57 +02:00
Rasmus Wriedt Larsen
0ebb24ebeb Merge pull request #5398 from yoff/python-api-enhancements
Python: Add small api enhancements determined useful during documentation work
2021-04-06 11:44:51 +02:00
Tom Hvitved
667b26b5d9 Merge pull request #5540 from hvitved/csharp/ssa-impl-tweaks
C#: Performance tweaks in `SsaImplCommon.qll`
2021-04-06 11:43:08 +02:00
Mathias Vorreiter Pedersen
a5f4d43d61 C++: Fix false positive by adding another allow-list pattern in AssignWhereCompareMeant. 2021-04-06 11:01:38 +02:00
Mathias Vorreiter Pedersen
7045597139 C++: Add testcase with false positive from #5318. 2021-04-06 10:58:15 +02:00
Erik Krogh Kristensen
c194598d37 recognize headers/url from the HTTP request to a server WebSocket. 2021-04-06 10:11:27 +02:00
Tom Hvitved
e852540254 C#: Remove unique wrappers from DataFlow::Node::get(EnclosingCallable|ControlFlowNode) 2021-04-06 09:56:09 +02:00
Rasmus Lerchedahl Petersen
c777f1d8d7 Merge branch 'main' of github.com:github/codeql into python-api-enhancements 2021-04-06 09:31:26 +02:00
Mathias Vorreiter Pedersen
32a8b9a857 C++: Move copy constructor to its own line and accept test changes. 2021-04-06 08:56:14 +02:00
yoff
a23d8deb10 Merge pull request #5483 from RasmusWL/minor-fixup-django
Python: Better text for getSourceType in Django
2021-04-06 08:30:58 +02:00
intrigus
885044e331 [Java] Add tests for jwt signature check query. 2021-04-06 01:01:57 +02:00
intrigus
b7e49c78fe [Java] Add stubs for jwtk-jjwt-0.11.2 2021-04-06 01:01:23 +02:00
intrigus
d1462eda1c [Java] Add "missing jwt signature check" query. 2021-04-06 00:59:31 +02:00
Asger Feldthaus
32500c834d JS: Change note 2021-04-01 16:41:03 +01:00
Asger Feldthaus
acc28df785 JS: Bugfix in tsconfig file inclusion handling 2021-04-01 16:33:05 +01:00
Asger Feldthaus
564a6873f8 JS: Add baseUrl test 2021-04-01 16:33:05 +01:00
Asger Feldthaus
c4ab6fb7b4 JS: Add ImportGraph meta query 2021-04-01 16:33:05 +01:00
Asger Feldthaus
f07030ba97 JS: Update AdditionalFlowStep -> SharedFlowStep 2021-04-01 13:16:47 +01:00
Asger Feldthaus
a9566728b5 JS: Update an import of Unit type 2021-04-01 13:16:47 +01:00
Asger Feldthaus
7119eda009 JS: Add redux change note 2021-04-01 13:16:47 +01:00
Asger Feldthaus
86bc0eb853 JS: Autoformat 2021-04-01 13:16:47 +01:00
Asger Feldthaus
b43989e6a1 JS: Use API nodes to track dispatch/dispatched value sources 2021-04-01 13:16:47 +01:00
Asger Feldthaus
2850b8e952 JS: Fix RangeAnalysis after BasicBlock.dominates change 2021-04-01 13:16:47 +01:00
Asger Feldthaus
cbfa5ad303 JS: Change type of a parameter 2021-04-01 13:16:47 +01:00
Asger Feldthaus
cee1a12489 JS: Fix typo in qldoc 2021-04-01 13:16:47 +01:00
Asger Feldthaus
c926a47d50 JS: QLDoc and test for HeuristicConnectEntryPoint 2021-04-01 13:16:47 +01:00
Asger Feldthaus
cca38a64be JS: Add test for flow to a closure body under a type guard 2021-04-01 13:16:46 +01:00
Asger Feldthaus
53def60e4f JS: Add test for if-based type check 2021-04-01 13:16:46 +01:00
Asger Feldthaus
1ce7c3448f JS: Address some review comments 2021-04-01 13:16:46 +01:00
Asger Feldthaus
fd7cbd0c96 JS: Tweak BasicBlock.dominates and friends 2021-04-01 13:16:46 +01:00
Asger Feldthaus
8fa3fb0561 JS: Redux model 2021-04-01 13:16:46 +01:00
Asger Feldthaus
314839fc09 JS: Add @reduxjs/toolkit to composed functions 2021-04-01 13:16:46 +01:00
Asger Feldthaus
c1651ad30c JS: Factor out Unit type 2021-04-01 13:16:46 +01:00
Asger Feldthaus
125d1465c8 JS: Add DataFlow::functionForwardingStep 2021-04-01 13:16:46 +01:00
Asger Feldthaus
a3421e7ab2 JS: Add getALocalUse 2021-04-01 13:16:45 +01:00
CodeQL CI
20416ae034 Merge pull request #5585 from asgerf/js/more-metadata
Approved by esbena
2021-04-01 13:13:01 +01:00
Asger Feldthaus
c96ee8671e JS: Update more query metadata 2021-04-01 12:15:54 +01:00
Luke Cartey
480ce39618 C#: Exclude jump-to-def information for elements with too many locations
In databases which include multiple duplicated files, we can get an
explosion of definition locations that can cause this query to produce
too many results for the CodeQL toolchain. This commit restricts the
definitions.ql query to producing definition/uses for definitions with
fewer than 10 locations. This replicates the logic used in the C++
definitions.qll library which faces similar problems.
2021-04-01 11:23:31 +01:00
CodeQL CI
a1fab8ac52 Merge pull request #5581 from asgerf/js/dependency-info
Approved by esbena
2021-04-01 09:07:21 +01:00
Shati Patel
36bdee0e8b Merge pull request #5571 from github/docs/bug-fix
Docs: Typo fix
2021-03-31 21:59:43 +01:00
Mathias Vorreiter Pedersen
ecbce88ec7 C++: Fix comment. 2021-03-31 22:23:50 +02:00
Rasmus Wriedt Larsen
95ac2c8edd Python: Add another dynamic __all__ test 2021-03-31 17:31:55 +02:00
CodeQL CI
f08a0e5653 Merge pull request #5580 from asgerf/js/more-metadata-fix
Approved by esbena
2021-03-31 16:29:33 +01:00
Rasmus Wriedt Larsen
ab3edf37d7 Python: Handle __all__ assigned to a tuple
Examples where this is used in real code:

- 76c0b32f82/django/core/files/temp.py (L24)
- 76c0b32f82/django/contrib/gis/gdal/__init__.py (L44-L49)
2021-03-31 17:25:19 +02:00
Rasmus Wriedt Larsen
43306f4700 Python: Add tests for Module.declaredInAll 2021-03-31 17:24:17 +02:00
Asger Feldthaus
8c8e4e6a70 JS: Add test 2021-03-31 16:17:54 +01:00
Asger Feldthaus
068a9d88e7 JS: Ensure Dependency.info() exists even if version range could not be parsed 2021-03-31 16:08:08 +01:00
Asger Feldthaus
c541390c1b JS: Remove precision tag from ExternalDependencies.ql 2021-03-31 13:54:15 +01:00
Mathias Vorreiter Pedersen
9ff894bf83 C++: Add support for AST dataflow out of functions that take a smart pointer by value. 2021-03-31 13:54:32 +02:00
Mathias Vorreiter Pedersen
e9e93c0eea Merge pull request #5558 from geoffw0/replace-tostring
Replace toString use
2021-03-31 13:50:41 +02:00
Geoffrey White
85ecfe2723 Update cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-03-31 11:34:56 +01:00
Mathias Vorreiter Pedersen
8159098dc0 C++: Add test from issue #5190. 2021-03-31 11:32:01 +02:00
Calum Grant
49d1937dc4 Merge pull request #5552 from RasmusWL/revert-import-change
Python: Revert #5506 due to bad performance
2021-03-31 09:51:39 +01:00
Asger F
d4877a9038 Merge pull request #5572 from asgerf/js/remove-flow-summary-kinds
JS: Change kind of summary-extraction queries to table
2021-03-31 09:28:56 +01:00
Asger Feldthaus
57784dc746 JS: Update test output 2021-03-31 09:23:47 +01:00
Chris Smowton
4f9b6d1192 Update supported Go version to 1.16 2021-03-31 08:56:27 +01:00
Asger Feldthaus
bc5b477f79 JS: Change kind of summary-extraction queries to table 2021-03-30 21:26:58 +01:00
Dave Bartolomeo
0cc8eaf3b4 Merge pull request #5543 from MathiasVP/smart-ptr-like-class
C++: Add a class that models wrapped pointer types
2021-03-30 16:00:13 -04:00
Rasmus Wriedt Larsen
51c27de049 Merge branch 'main' into revert-import-change 2021-03-30 21:51:53 +02:00
Shati Patel
b9788eb53c Merge pull request #5568 from shati-patel/docs-binding-sets
Docs: Mention that binding sets are available for classes
2021-03-30 18:08:23 +01:00
Sarita Iyer
649286995a Merge pull request #5562 from saritai/saritai/cli-remove-1.23-references
Remove Enterprise 1.23 special instructions and replace references
2021-03-30 13:07:42 -04:00
Shati Patel
fb004bacc3 Describe predicates first 2021-03-30 17:31:20 +01:00
Shati Patel
67835ee273 Address review comments 2021-03-30 17:29:43 +01:00
Shati Patel
23df459c16 remove accidental punctuation 2021-03-30 17:23:33 +01:00
Mathias Vorreiter Pedersen
fe76b0849b Merge pull request #5569 from geoffw0/memoryfree
C++: Add a test of memory freed queries with strdup.
2021-03-30 17:22:18 +02:00
Mathias Vorreiter Pedersen
92839123ae Merge pull request #5570 from geoffw0/mutextest
C++: Add mutex test cases.
2021-03-30 17:16:19 +02:00
Geoffrey White
a8284d5b97 C++: Add mutex test case. 2021-03-30 15:39:21 +01:00
Sarah Edwards
e0a73ce797 Merge pull request #5560 from skedwards88/patch-1
download LGTM database from a project slug
2021-03-30 06:58:28 -07:00
Geoffrey White
244966e216 C++: Add a test with strdup. 2021-03-30 14:49:05 +01:00
Shati Patel
62de15cd22 Docs: Mention that binding sets are available for classes 2021-03-30 14:46:59 +01:00
Asger Feldthaus
f8bbda0cdc JS: Change note 2021-03-30 13:54:01 +01:00
Asger Feldthaus
9db235ac36 JS: Improve @google-cloud/spanner model 2021-03-30 13:54:00 +01:00
Asger Feldthaus
35f294f096 JS: Improve sequelize model 2021-03-30 13:54:00 +01:00
Mathias Vorreiter Pedersen
4b51e22bb4 Merge pull request #5565 from geoffw0/avrule79
C++: Test strdup with AV rule 79
2021-03-30 14:34:46 +02:00
Geoffrey White
ec952248a9 C++: Test strdup with AV Rule 79. 2021-03-30 12:58:04 +01:00
Geoffrey White
f27203cc43 C++: Test spacing. 2021-03-30 12:57:43 +01:00
luchua-bc
1349bf7b0b Create a .qll file to reuse the code and add check of Spring properties 2021-03-30 11:25:29 +00:00
Asger Feldthaus
93500bd95a JS: Improve mssql model 2021-03-30 11:34:01 +01:00
Asger Feldthaus
95937c9ac7 JS: Improve sqlite3 model 2021-03-30 11:34:01 +01:00
Asger Feldthaus
0b21b273ed JS: Improve pg model 2021-03-30 11:33:59 +01:00
Asger Feldthaus
937a620f4d JS: Improve mysql2 model 2021-03-30 11:33:42 +01:00
CodeQL CI
e8d7925084 Merge pull request #5555 from asgerf/js/misc-steps
Approved by esbena
2021-03-30 11:30:12 +01:00
CodeQL CI
25e26b9ac0 Merge pull request #5554 from asgerf/js/non-recursive-propref
Approved by esbena
2021-03-30 11:29:32 +01:00
CodeQL CI
6cceb73807 Merge pull request #5553 from asgerf/js/pg-promise
Approved by esbena
2021-03-30 11:28:24 +01:00
Geoffrey White
d2b991bcb5 Merge pull request #5541 from MathiasVP/definitions-for-unique_ptr
C++: Add shared_ptr and unique_ptr implementations
2021-03-30 09:47:56 +01:00
Mathias Vorreiter Pedersen
09ba25fe9b C++: Accept test changes. I'm actually not sure why we lose these results (and lose the field conflation, yay) It might be due to #3364. 2021-03-30 10:24:01 +02:00
Mathias Vorreiter Pedersen
8c95a9ae39 Merge branch 'main' into definitions-for-unique_ptr 2021-03-30 10:20:36 +02:00
Laura Coursen
2dadc752d6 Merge pull request #5563 from lecoursen/stronger-rec-to-use-lgtm.com-branch
Make stronger recommendations around the use of the lgtm.com branch
2021-03-29 14:29:24 -05:00
Laura Coursen
d57ec5d1ac Merge branch 'stronger-rec-to-use-lgtm.com-branch' of https://github.com/lecoursen/codeql into stronger-rec-to-use-lgtm.com-branch 2021-03-29 14:05:46 -05:00
Laura Coursen
e3b052199a Suggest lgtm.com branch first 2021-03-29 14:04:59 -05:00
Laura Coursen
eb01ffbdae Use correct terminology
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
2021-03-29 14:03:30 -05:00
Ethan Palm
2f98212eca Merge pull request #5561 from ethanpalm/fix-broken-links
Fix broken links
2021-03-29 14:28:49 -04:00
Laura Coursen
8f1c7c57a8 Add 💅 2021-03-29 12:53:16 -05:00
Ethan P
909dc84bb6 Update broken link 2021-03-29 13:46:45 -04:00
Laura Coursen
a18cd74756 Fix typo 2021-03-29 12:42:09 -05:00
Laura Coursen
21576387f3 Add 💅 2021-03-29 12:41:48 -05:00
Laura Coursen
50523e0ac0 Clarify use cases for lgtm.com branch 2021-03-29 12:40:31 -05:00
Ethan P
d126c0a1d3 Fix broken links 2021-03-29 13:38:04 -04:00
Sarita Iyer
3db5dd4661 removed 1.23 instructions and replaced references
Removed special instructions for LGTM 1.23, and replaced leftover references to 1.23 with 1.27.
2021-03-29 13:37:55 -04:00
Sarah Edwards
108bcef104 download LGTM database from a project slug 2021-03-29 10:37:00 -07:00
Henry Mercer
0f710b1981 Merge pull request #5545 from github/henrymercer/ql-pack-version-doc-update
CodeQL CLI Docs: Mention that QL packs use SemVer versioning
2021-03-29 18:18:45 +01:00
Calum Grant
c26d05b1d5 Merge pull request #5532 from RasmusWL/python-cleanup
Python: Delete filter queries, code duplication library, and precision tag from metric queries
2021-03-29 17:16:43 +01:00
Mathias Vorreiter Pedersen
5a4efab742 C++: Add tests for shared_ptr. 2021-03-29 18:04:20 +02:00
Rasmus Wriedt Larsen
96a66fa4ee Python: Apply suggestions from code review 2021-03-29 17:02:56 +02:00
Asger Feldthaus
67ad6d9a0f JS: Update test output 2021-03-29 15:30:29 +01:00
Asger Feldthaus
faf07dac91 JS: Autoformat 2021-03-29 14:52:37 +01:00
Asger Feldthaus
3e26236648 JS: Add recursion guard test 2021-03-29 14:32:13 +01:00
Asger Feldthaus
2770a53d38 JS: More babel.transform steps 2021-03-29 13:00:23 +01:00
Asger Feldthaus
c103939c2d JS: Fix handling of createRequire 2021-03-29 12:47:23 +01:00
Asger Feldthaus
49ca88957c JS: Use types 2021-03-29 12:25:15 +01:00
Asger Feldthaus
603843e698 JS: Add task tests 2021-03-29 12:05:47 +01:00
CodeQL CI
3613ceb07f Merge pull request #5535 from tausbn/python-prevent-bad-TCs
Approved by yoff
2021-03-29 12:03:08 +01:00
Asger F
f1d0b50670 Update javascript/ql/src/semmle/javascript/frameworks/SQL.qll
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-03-29 11:54:45 +01:00
Asger Feldthaus
f453fe26c6 JS: Autoformat 2021-03-29 11:28:46 +01:00
Asger Feldthaus
b381f4826c JS: Add change note 2021-03-29 11:25:28 +01:00
Asger Feldthaus
149af57eac JS: Add model of pg-promise 2021-03-29 11:25:28 +01:00
Asger Feldthaus
88fee2748e JS: Add change note 2021-03-29 11:21:03 +01:00
haby0
0775d35591 update VerificationMethodFlowConfig, add if test 2021-03-29 12:02:37 +08:00
ihsinme
3f215d0954 Update OperatorPrecedenceLogicErrorWhenUseBoolType.ql 2021-03-28 23:43:22 +03:00
ihsinme
093c63ea3b Update OperatorPrecedenceLogicErrorWhenUseBoolType.expected 2021-03-28 23:42:36 +03:00
luchua-bc
5ce3f9d6ff Update qldoc and enhance the query 2021-03-28 16:10:35 +00:00
Rasmus Wriedt Larsen
92e0e195a4 Revert "Merge pull request #5506 from tausbn/python-allow-absolute-imports-from-source-directory"
This reverts commit 8d15680af4, reversing
changes made to 63831cc62b.

This PR caused performance problems, so reverting now to clear up immediate
problems.
2021-03-27 18:08:20 +01:00
Rasmus Lerchedahl Petersen
6d72b4fd39 Python: Limit pretty printing to relevant nodes 2021-03-27 03:10:43 +01:00
Rasmus Lerchedahl Petersen
16902c2f56 Python: handle default argument 2021-03-27 02:40:13 +01:00
Rasmus Lerchedahl Petersen
7a511c5682 Python: update naming 2021-03-27 02:20:59 +01:00
luchua-bc
a53cbc1631 Update qldoc and make the query more readable 2021-03-27 00:11:01 +00:00
Rasmus Lerchedahl Petersen
bd86388447 Python: Add typetracker to constrain attribute. 2021-03-27 01:07:15 +01:00
Rasmus Lerchedahl Petersen
bf81122fc6 Python: fix typo and add linebreaks 2021-03-26 23:37:19 +01:00
Rasmus Lerchedahl Petersen
e0352fe763 Python: remove deprecated section of qhelp file 2021-03-26 23:26:24 +01:00
Geoffrey White
c6e7b8d4fd C++: Repair test. 2021-03-26 19:12:09 +00:00
Geoffrey White
4100d68a71 C++: Test failures. 2021-03-26 18:21:05 +00:00
Geoffrey White
725122decc C++: Replace toString logic. 2021-03-26 17:29:05 +00:00
luchua-bc
a72b1340eb Add a comment on how to run the query 2021-03-26 16:51:43 +00:00
Rasmus Lerchedahl Petersen
44d62df3f7 Python: Fix model of TLS and add reference 2021-03-26 17:51:18 +01:00
Rasmus Lerchedahl Petersen
470b4d8658 Python: Add missing qldoc 2021-03-26 17:35:36 +01:00
Rasmus Lerchedahl Petersen
98dfe1a00a Python: Elaborate qldoc and renames to match 2021-03-26 17:27:43 +01:00
Taus Brock-Nannestad
f17bbd9982 Python: Fix another bad TC.
This one is a bit awkward, since the previous version was supposed to
improve indexing. Unfortunately this is vastly outweighed by the slow
convergence of the TC. Right now we pay the cost of inverting the
`hasFlowSource` relation, but this is still cheaper.
2021-03-26 16:38:13 +01:00
Henry Mercer
c83daa66e7 CodeQL CLI Docs: Mention that QL packs use SemVer versioning 2021-03-26 15:30:23 +00:00
Mathias Vorreiter Pedersen
b466f0515d C++: Respond to more review comments. (1) Use getClassAndName to ensure a good join order, and (2) unify the two abstract predicates on PointerWrapper. 2021-03-26 16:16:23 +01:00
Rasmus Lerchedahl Petersen
8155334fa7 Python: More elaborate qldoc
also refactor code to match
2021-03-26 15:57:07 +01:00
Rasmus Lerchedahl Petersen
7d7cbc49db Fix comments.
This induced fixing the code, since things were wired up wrongly.
Currently the only implementation of `insecure_connection_creation`
is `ssl.wrap_socket`,
which is also the sole target of  py/insecure-default-protocol`,
so perhaps this part should be turned off?
2021-03-26 14:20:38 +01:00
Mathias Vorreiter Pedersen
0ce08617ba C++: Respond to review comments. 2021-03-26 13:42:18 +01:00
Tom Hvitved
e345064a53 C#: Performance tweaks in SsaImplCommon.qll 2021-03-26 13:24:34 +01:00
Rasmus Lerchedahl Petersen
2e948da3b4 Python: suggested refactor 2021-03-26 13:08:45 +01:00
Rasmus Lerchedahl Petersen
1be2be843d Python: update test expectations 2021-03-26 13:08:23 +01:00
Jonas Jensen
7f16c52217 Merge pull request #3364 from github/rdmarsh/cpp/use-taint-configuration-dtt
C++: use TaintTracking::Configuration in DefaultTaintTracking
2021-03-26 12:39:25 +01:00
Alexander Eyers-Taylor
b21672c81c Apply suggestions from code review
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-03-26 11:15:46 +00:00
Tom Hvitved
1dbfe2369d Merge pull request #5542 from hvitved/csharp/update-suites
C#: Remove deleted queries from suites
2021-03-26 12:13:09 +01:00
CodeQL CI
f584ff9acf Merge pull request #5533 from asgerf/js/fix-query-metadata
Approved by esbena
2021-03-26 11:09:54 +00:00
Mathias Vorreiter Pedersen
8dc7b6403a C++: Add shared_ptr and unique_ptr implementations. Also add some very basic tests. 2021-03-26 12:03:59 +01:00
Mathias Vorreiter Pedersen
d20a0c9e82 C++: Add a class that models wrapped pointer types. 2021-03-26 11:50:06 +01:00
Asger Feldthaus
cc2a531684 JS: Cache PropRef.getBase 2021-03-26 10:48:25 +00:00
Tom Hvitved
9d1ef21d85 C#: Remove deleted queries from suites 2021-03-26 11:17:27 +01:00
Mathias Vorreiter Pedersen
c7c65736a9 C++: Accept test changes. These happened because of the incorrect usage of multiple configurations in 6c1ec6d96b. 2021-03-26 10:57:58 +01:00
Jonas Jensen
86755c6a98 Merge pull request #5515 from criemen/fix-query-metadata
C++: Fix query metadata warnings.
2021-03-26 10:19:46 +01:00
Anders Schack-Mulligen
506c95d098 Merge pull request #5372 from smowton/smowton/feature/commons-lang-models-to-csv
Java: Convert existing Commons Lang models to CSV
2021-03-26 10:18:23 +01:00
Tom Hvitved
d4ce42ac4f Merge pull request #5416 from hvitved/csharp/rework-summaries
C#: Rework flow summary implementation
2021-03-26 09:47:15 +01:00
Tom Hvitved
e93b72d563 Merge pull request #5459 from hvitved/csharp/update-nuget
C#: Update more nuget packages
2021-03-26 09:28:09 +01:00
Mathias Vorreiter Pedersen
983b64a05f Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-26 09:11:12 +01:00
Tom Hvitved
57fd2e3578 C#: Rename parameter in fieldOf() 2021-03-26 08:49:06 +01:00
Rasmus Lerchedahl Petersen
e936540863 Python: remove internal import 2021-03-26 08:22:09 +01:00
Rasmus Lerchedahl Petersen
f1619f1ee8 Python: "source" -> "contextOrigin" 2021-03-26 08:18:11 +01:00
Rasmus Lerchedahl Petersen
f14fb3bf9e Merge branch 'python-port-insecure-protocol' of github.com:yoff/codeql into python-port-insecure-protocol 2021-03-26 08:06:51 +01:00
yoff
936757b4bf Update python/ql/src/Security/CWE-327/FluentApiModel.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-26 08:05:51 +01:00
luchua-bc
d33b04cd96 Query to detect plaintext credentials in Java properties files 2021-03-26 02:33:40 +00:00
Rasmus Lerchedahl Petersen
9488b8bb18 Python: actually rename 2021-03-26 00:31:56 +01:00
Rasmus Lerchedahl Petersen
554404575d Python: fix typo and name. 2021-03-26 00:29:40 +01:00
Rasmus Lerchedahl Petersen
c93e0c08fd Merge branch 'python-port-insecure-protocol' of github.com:yoff/codeql into python-port-insecure-protocol 2021-03-26 00:26:33 +01:00
yoff
54dad57cf4 Update python/ql/test/query-tests/Security/CWE-327/pyOpenSSL_fluent.py
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-26 00:25:40 +01:00
Rasmus Lerchedahl Petersen
2b257318f1 Python: more precise comment 2021-03-25 23:22:24 +01:00
yoff
62a0775cf6 Update python/ql/src/Security/CWE-327/examples/secure_protocol.py
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-25 23:09:11 +01:00
Porcuiney Hairs
2ca95166d9 Java : add query to detect insecure loading of Dex File 2021-03-26 01:59:11 +05:30
yoff
208d5157fa Merge pull request #5500 from RasmusWL/django-forms
Python: Model RemoteFlowSources on Django forms/fields
2021-03-25 20:43:19 +01:00
alexet
2576c86ebf Docs: Update the language specification for changes to super. 2021-03-25 18:16:13 +00:00
Taus Brock-Nannestad
c2f112cb92 Python: Filter _before_ the cartesian product
It's always a sad thing to see a good plan go wrong:

86860032 ~0%      {4} r26 = JOIN r19 WITH DataFlowPublic::TupleElementContent#class#ff CARTESIAN PRODUCT OUTPUT Lhs.0 'nodeFrom', Lhs.1 'nodeTo', Rhs.0, Rhs.1
129256   ~3%      {4} r27 = SELECT r26 ON In.3 <= 7
129256   ~0%      {3} r28 = SCAN r27 OUTPUT In.0 'nodeFrom', In.2 'c', In.1 'nodeTo'

Happily, now it looks like this:

129256  ~0%      {3} r20 = JOIN r19 WITH DataFlowPrivate::small_tuple#f CARTESIAN PRODUCT OUTPUT Lhs.0 'nodeFrom', Rhs.0, Lhs.1 'nodeTo'
2021-03-25 19:06:05 +01:00
Erik Krogh Kristensen
5e59f6d558 Update javascript/ql/src/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironmentCustomizations.qll
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-03-25 19:03:37 +01:00
Taus Brock-Nannestad
8734df334b Python: Slight cleanup 2021-03-25 18:35:16 +01:00
Taus Brock-Nannestad
229250dc54 Python: Limit size of TupleElementContent
A more principled approach is possible here, but in the short term
this will prevent an explosion.

For reference, openstack/cinder has roughly 19000 `ForTarget`s and
tuples of size up to 5300, and we were calculating the cartesian
product of these.
2021-03-25 18:28:49 +01:00
yoff
716e0f1404 Merge pull request #5517 from tausbn/python-prevent-potentially-bad-join-order
Python: Prevent potentially bad join order
2021-03-25 18:14:47 +01:00
Tom Hvitved
f100c8a9c0 C++: Make Windows autobuilder tests pass again 2021-03-25 17:43:48 +01:00
Tom Hvitved
ed78acb1d4 C#: Update more nuget packages 2021-03-25 17:32:12 +01:00
Taus Brock-Nannestad
dbef36cbbb Python: Prevent bad TC and add a bit of caching
Using `simpleLocalFlowStep+` with the first argument specialised to
`CfgNode` was causing the compiler to turn this into a very slowly
converging manual TC computation.

Instead, we use `simpleLocalFlowStep*` (which is fast) and then join
that with a single step from any `CfgNode`. This should amount to the
same thing.

I also noticed that the charpred for `LocalSourceNode` was getting
recomputed a lot, so this is now cached. (The recomputation was
especially bad since it relied on `simpleLocalFlowStep+`, but anyway
it's a good idea not to recompute this.)
2021-03-25 17:28:37 +01:00
Chris Smowton
eaa2d4d831 Stop using wildcard Argument
All instances are replaced with a specific Argument or range.
2021-03-25 15:42:35 +00:00
Chris Smowton
2f34588770 Constructor models: use Argument[-1] for the result, not ReturnValue 2021-03-25 15:23:08 +00:00
Asger Feldthaus
a456458a38 JS: Add change note for code duplication library removal 2021-03-25 15:21:48 +00:00
Asger Feldthaus
446ad5ec9e JS: Remove code duplication library 2021-03-25 15:20:59 +00:00
Asger Feldthaus
c812bd948a JS: Add @problem.severity to an example query 2021-03-25 15:14:48 +00:00
Asger Feldthaus
7aae51c876 JS: Add change note for filter query removal 2021-03-25 15:13:51 +00:00
Anders Schack-Mulligen
28fb0edfbe Merge pull request #4920 from luchua-bc/java/hash-without-salt
Java: Query to detect hash without salt
2021-03-25 16:13:26 +01:00
Asger Feldthaus
6cab85712f JS: Delete filter queries 2021-03-25 15:12:35 +00:00
Asger Feldthaus
1c27ca610a JS: Remove precision atags from metric queries 2021-03-25 15:12:09 +00:00
Chris Smowton
a5220bf616 Convert StrBuilder models to CSV 2021-03-25 15:11:52 +00:00
Chris Smowton
25a0e09130 Convert StringUtils models to CSV 2021-03-25 15:11:52 +00:00
Chris Smowton
1beac06236 Translate ArrayUtils models to CSV 2021-03-25 15:11:51 +00:00
Chris Smowton
7fb5bd0cab Add tests for and slightly expand models of Commons Lang's ArrayUtils class 2021-03-25 15:11:51 +00:00
Rasmus Wriedt Larsen
9abe02f419 Python: Fix query metadata for old queries that have been ported
I'm not sure even I want to keep these around much longer. They seem to be
causing more problem than they are doing good.
2021-03-25 16:01:56 +01:00
Jonas Jensen
bc9682c22d Merge pull request #5528 from MathiasVP/fix-join-order-in-avrule-79
C++: Fix join order in AV rule 79
2021-03-25 15:45:41 +01:00
Rasmus Wriedt Larsen
ed2cb739c5 Merge pull request #5486 from yoff/python-document-api-import-node
Python, doc: Note ephemeral nature of import nodes
2021-03-25 15:45:10 +01:00
Anders Schack-Mulligen
344c2d3c3d Update java/ql/src/experimental/Security/CWE/CWE-759/HashWithoutSalt.ql 2021-03-25 15:42:57 +01:00
Tom Hvitved
90868a4788 Merge pull request #5524 from hvitved/csharp/cleanup
C#: Remove legacy queries and `@precision` tags from metric queries
2021-03-25 15:36:12 +01:00
Rasmus Wriedt Larsen
203b0e3d88 Python: Add change note 2021-03-25 15:34:09 +01:00
Tom Hvitved
cdd613358b C#: Sync SSA files 2021-03-25 15:33:06 +01:00
Tom Hvitved
7e20829f36 Merge remote-tracking branch 'upstream/main' into csharp/rework-summaries 2021-03-25 15:32:32 +01:00
Tom Hvitved
6a3859fc83 C#: Remove unnecessary pre call in FlowSummaryImpl.qll 2021-03-25 15:31:43 +01:00
Rasmus Wriedt Larsen
bd4934380a Python: Remove code duplication library 2021-03-25 15:27:55 +01:00
Tom Hvitved
33c990f6b0 Merge pull request #5440 from hvitved/csharp/cil/ssa
C#: Add CIL SSA library
2021-03-25 15:22:40 +01:00
Erik Krogh Kristensen
3d49b8cb91 consider quoted string concatenations as sanitizers for js/shell-command-injection-from-environment 2021-03-25 15:17:02 +01:00
yo-h
0fe4baec34 Merge pull request #5525 from aschackmull/java/cleanup
Java: Delete filter queries, code duplication library, and precision tag from metric queries.
2021-03-25 10:09:41 -04:00
Rasmus Wriedt Larsen
09fbf480db Python: Remove precision tag from metric queries 2021-03-25 15:06:47 +01:00
Rasmus Wriedt Larsen
e3b2e0a1de Python: Delete filter queries 2021-03-25 15:06:46 +01:00
Erik Krogh Kristensen
3b82452d76 detect fs modules that pass through a reduce call 2021-03-25 14:47:43 +01:00
Anders Schack-Mulligen
75afa011ff Java: Add metadata to several more experimental queries. 2021-03-25 13:09:26 +01:00
CodeQL CI
e90035a5a5 Merge pull request #5439 from erik-krogh/topPack
Approved by esbena
2021-03-25 11:49:03 +00:00
Mathias Vorreiter Pedersen
24360d3a4c C++: Fix join order in AV rule 79 by joining with GVN after the recursive call. 2021-03-25 12:00:49 +01:00
Erik Krogh Kristensen
77ba7b473d Merge branch 'main' into topPack 2021-03-25 11:52:58 +01:00
CodeQL CI
0511e72520 Merge pull request #5458 from erik-krogh/shellTrue
Approved by asgerf
2021-03-25 10:49:24 +00:00
luchua-bc
57bd3f3c14 Optimize the taint flow source 2021-03-25 10:44:26 +00:00
Tom Hvitved
6bfc49c069 C#: Address review comments 2021-03-25 11:43:25 +01:00
yoff
32b264bdee Apply suggestions from code review
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2021-03-25 10:48:59 +01:00
Anders Schack-Mulligen
d53c334488 Merge branch 'java/fix-experimental-query-metadata' into java/cleanup 2021-03-25 10:36:36 +01:00
Anders Schack-Mulligen
28ff3f412d Java: Add severity and precision metadata to experimental queries. 2021-03-25 10:29:47 +01:00
Cornelius Riemenschneider
867471b122 C++: Delete old queries. 2021-03-25 10:23:17 +01:00
CodeQL CI
9d52db3ca7 Merge pull request #5507 from erik-krogh/joins
Approved by asgerf
2021-03-25 09:18:26 +00:00
Anders Schack-Mulligen
5b905cfe18 Java: Add change note for code duplication library removal. 2021-03-25 10:12:58 +01:00
Anders Schack-Mulligen
1564aee57a Java: Add change note for filter query removal. 2021-03-25 10:11:30 +01:00
Anders Schack-Mulligen
c82b5eb040 Java: Remove code duplication library. 2021-03-25 10:06:10 +01:00
Asger Feldthaus
dbc6cf63c2 JS: Fix bad join order in PropertyProjection 2021-03-25 09:00:10 +00:00
Asger Feldthaus
bd3f6d1234 JS: Add o[o.length] = y taint step 2021-03-25 09:00:10 +00:00
Asger Feldthaus
51f489211b JS: Support react-native-base64 2021-03-25 09:00:10 +00:00
Asger Feldthaus
5d9778c64d JS: Step through babel.transform 2021-03-25 09:00:10 +00:00
Asger Feldthaus
3e67ebacb0 JS: Support lodash-es 2021-03-25 09:00:10 +00:00
Erik Krogh Kristensen
3b6b40489f Merge branch 'main' into topPack 2021-03-25 09:58:15 +01:00
Anders Schack-Mulligen
4b7440d4d5 Java: Remove precision tag from metric queries. 2021-03-25 09:52:05 +01:00
Tom Hvitved
419fbe77ab C#: Remove @precision tags from metric queries 2021-03-25 09:50:24 +01:00
Tom Hvitved
b83da2255c C#: Add change note 2021-03-25 09:50:24 +01:00
Tom Hvitved
b94c189946 C#: Remove VulnerablePackage.ql query 2021-03-25 09:50:24 +01:00
Tom Hvitved
7e33b571c9 C#: Add change note 2021-03-25 09:50:24 +01:00
Tom Hvitved
eeb8c74666 C#: Remove filter and external queries
These are legacy queries that are no longer used.
2021-03-25 09:50:01 +01:00
Anders Schack-Mulligen
70824b3f0b Java: Delete filter queries. 2021-03-25 09:47:31 +01:00
Esben Sparre Andreasen
801eb538db Merge pull request #5514 from github/aibaars/fix-javascript-metadata
Javascript: remove bad QLDoc tag
2021-03-25 08:56:08 +01:00
luchua-bc
fe0e7f5eac Change method check to taint flow 2021-03-25 01:45:13 +00:00
luchua-bc
08c3bf26d5 Update the query to accommodate more cases 2021-03-24 23:32:27 +00:00
Taus Brock-Nannestad
0ae8b69102 Python: Prevent joining on scope in PointsToContext::appliesTo
One of those cases where I _wish_ `pragma[inline]` also meant "don't
join on the stuff inside this predicate -- it's inlined for a reason".

Unsurprisingly, joining on the scope first works poorly.
2021-03-24 23:12:48 +01:00
Taus Brock-Nannestad
28d6cad3d0 Python: Prevent joining on name as the first thing
Many instances of `lookup` are restricted by the presence of
`attributeRequired`, but this does not work well if we join on
`name`. A few instances of `only_bind_into` prevents this.
2021-03-24 23:11:09 +01:00
yo-h
72ae902e0d Merge pull request #5371 from aschackmull/java/framework-coverage
Java: Add query for CSV framework coverage.
2021-03-24 17:36:13 -04:00
Erik Krogh Kristensen
c146b27c1a Merge branch 'main' into shellTrue 2021-03-24 20:09:23 +01:00
CodeQL CI
8ff9c98d26 Merge pull request #5449 from erik-krogh/asExec
Approved by esbena
2021-03-24 19:04:30 +00:00
Aditya Sharad
32dc894d54 Merge pull request #5516 from github/adityasharad/actions/remove-docs-review-workflow
Actions: Remove docs-review workflow
2021-03-24 11:48:03 -07:00
Aditya Sharad
a0465d20cb Actions: Remove docs-review workflow
Being replaced by internal automation that polls the repo for open labelled PRs, since this workflow currently cannot tag the docs team in a comment.
2021-03-24 11:26:00 -07:00
Taus Brock-Nannestad
ed8ffab356 Python: Prevent potentially bad join order
This has no effect on the current compilation (indeed,
`ssa_filter_definition_bool` is not currently inlined), but will
prevent this from ever occurring, should the heuristics for inlining
ever change...
2021-03-24 19:20:19 +01:00
Cornelius Riemenschneider
47530d7526 C++: Fix query metadata warnings. 2021-03-24 18:01:21 +01:00
Arthur Baars
b25dc03dac Javascript: remove bad QLDoc tag 2021-03-24 16:47:27 +01:00
Asger Feldthaus
e13a9c9716 JS: Avoid recursion through SourceNode::Range, again 2021-03-24 15:26:50 +00:00
Anders Schack-Mulligen
d3485cac34 Merge pull request #5512 from aschackmull/java/csv-argument-ranges
Java: Support argument and parameter ranges in CSV models.
2021-03-24 15:03:22 +01:00
yoff
8d15680af4 Merge pull request #5506 from tausbn/python-allow-absolute-imports-from-source-directory
Python: Allow absolute imports in directories with scripts
2021-03-24 14:42:14 +01:00
Anders Schack-Mulligen
4955f95f64 Apply suggestions from code review
Clarify documentation.

Co-authored-by: Chris Smowton <smowton@github.com>
2021-03-24 14:32:18 +01:00
Anders Schack-Mulligen
63831cc62b Merge pull request #5099 from porcupineyhairs/javaLogInjection
Java : Add Log Injection Vulnerability
2021-03-24 14:30:34 +01:00
yoff
b023d73016 Merge pull request #5504 from RasmusWL/type-tracking-first-predicate-private
Python: Ensure first type-tracking predicate is private
2021-03-24 14:23:27 +01:00
Rasmus Wriedt Larsen
1473778bb8 Merge pull request #5493 from yoff/python-add-experimental-structure
Python: Add stub structure to `experimental` for external contributions
2021-03-24 14:11:13 +01:00
Rasmus Wriedt Larsen
70974ea197 Python: Fix grammar in QLDoc
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-03-24 14:06:06 +01:00
Taus Brock-Nannestad
47686a6e4c Python: Disregard all files matching .py% 2021-03-24 14:03:00 +01:00
Taus Brock-Nannestad
8d30ee5c3c Python: Include unmarked Python file in snapshot
Sadly, it seems we're not interpreting this as Python code, even if we
explicitly ask to have it included.
2021-03-24 14:01:13 +01:00
Anders Schack-Mulligen
a1ccbcdaf1 Merge pull request #5260 from artem-smotrakov/spring-http-invoker
Java: Query for detecting unsafe deserialization with Spring exporters
2021-03-24 13:57:17 +01:00
Asger Feldthaus
de879c0707 JS: Make PropRef.getBase non-recursive 2021-03-24 12:57:16 +00:00
Asger Feldthaus
2f2d72f282 JS: Improve react-router support 2021-03-24 12:53:26 +00:00
Asger Feldthaus
88932a495c JS: Handle redux-form HOCs 2021-03-24 12:53:26 +00:00
Rasmus Wriedt Larsen
59200386a7 Python: Fix mistake in refactor 2021-03-24 13:51:29 +01:00
Tom Hvitved
f2fb26df37 C#: Document input/output stack restrictions 2021-03-24 13:48:32 +01:00
CodeQL CI
e3ab94fc6b Merge pull request #5498 from asgerf/js/flow-through-accessors
Approved by erik-krogh, max-schaefer
2021-03-24 12:46:05 +00:00
Anders Schack-Mulligen
41168e2b36 Java: Support argument and parameter ranges. 2021-03-24 13:32:30 +01:00
Anders Schack-Mulligen
234f62fd05 Java: Merge packages that likely belong to the same framework. 2021-03-24 13:17:04 +01:00
Taus Brock-Nannestad
6d86239929 Python: Test all cases
Note that the test in `no_py_extension` isn't complete, since we're
not extracting the `main` file there.
2021-03-24 13:15:59 +01:00
Erik Krogh Kristensen
9610ed163a remove SourceNode type to preserve behavior 2021-03-24 11:59:56 +01:00
CodeQL CI
12a6410a0a Merge pull request #5478 from asgerf/js/shared-flow-step
Approved by erik-krogh
2021-03-24 10:58:30 +00:00
Tom Hvitved
c5c80204d5 C#: Rework flow summary implementation 2021-03-24 11:27:01 +01:00
Tom Hvitved
c96b8301ed C#: Add change note 2021-03-24 09:58:44 +01:00
haby0
3df23eecb6 Merge remote-tracking branch 'upstream/main' into JsonHijacking 2021-03-24 15:52:01 +08:00
Anders Schack-Mulligen
02a5c0875e Merge pull request #5502 from smowton/smowton/fix/less-fluent-method-inferred-edges
Java: partial revert: only introduce inferred taint edges from callsite-crossing value edges if an original taint edge targets the *start* of the value edge.
2021-03-24 08:41:51 +01:00
Rasmus Lerchedahl Petersen
a9af135d7e Python: Remove getALocalTaintSource
and `taintFlowsTo` for now..
2021-03-24 01:22:21 +01:00
yoff
ac0430883a Update docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-24 01:08:12 +01:00
yoff
61cff8faed Update python/ql/src/experimental/semmle/python/Concepts.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-24 01:06:03 +01:00
Erik Krogh Kristensen
b8bfdcc719 improve performance in ServiceDefinitions by inlining, and refactoring away a SourceNode 2021-03-23 19:13:40 +01:00
Erik Krogh Kristensen
93bcc3724a use pragma to improve 2 join-orders in TaintTracking 2021-03-23 19:12:33 +01:00
Taus Brock-Nannestad
17d1768259 Python: Allow absolute imports in directories with scripts
Fixes the import logic to account for absolute imports.

We do this by classifying which files and folders may serve as the
entry point for execution, based on a few simple heuristics. If the
file `module.py` is in the same folder as a file `main.py` that may be
executed directly, then we allow `module` to be a valid name for
`module.py` so that `import module` will work as expected.
2021-03-23 18:32:17 +01:00
Taus Brock-Nannestad
4289e358bf Python: Add module import test case
This one will require some explanation...

First, the file structure. This commit adds a test consisting
representing a few different kinds of imports.

- Absolute imports, from `module.py` to `main.py` when the latter is
  executed directly.
- A package (contained in the `package` folder)
- A namespace package (contained in the `namespace_package` folder)

All of these are inside a folder called `code` for reasons I will
detail later.

The file `main.py` is identified as a script, by the presence of the
`!#` comment in its first line.

The files themselves are executable, and `python3 main.py` will print
out all modules in the order they are imported.

The test itself is very simple. It simply lists all modules and their
corresponding names. As is plainly visible, without modification we
only pick up `package` and its component modules as having names. This
is the bit that needs to be fixed.

Convincing the test runner to extract this test in a way that mimics
reality is, unfortunately, a bit complicated. By default, the test
runner itself includes any Python files in the test directory as
modules in the invocation of the extractor, and so we must hide
everything in the `code` subdirectory.

Secondly, a `--path` argument (set to the test directory) is
automatically added, and this would also interfere with extraction,
and hence we must prevent this. Luckily, if we supply our own `--path`
argument -- even if it doesn't make any sense -- then the other
argument is left out.

Finally, we must actually tell the extractor to extract the files (or
it would just happily pass the test with zero files extracted), so the
`-R .` argument ensures that we recurse over the files in the test
directory after all.
2021-03-23 18:21:58 +01:00
Tom Hvitved
6d6150d051 C#: Change some data-flow toString()s 2021-03-23 16:42:58 +01:00
Rasmus Wriedt Larsen
deefbefffc Python: Minor refactor to use CallCfgNode 2021-03-23 16:42:41 +01:00
Rasmus Wriedt Larsen
1f5e52e822 Python: Cleanup "first" type-tracking predicate to be private
Since it's exposed nicely in the version that doesn't have a
`DataFlow::TypeTracker` parameter, these should be private.

Also found one instance where I had accidentially used DataFlow::Node instead of
LocalSourceNode
2021-03-23 16:40:56 +01:00
Asger Feldthaus
98cee7d339 JS: Update Collection step test and its output 2021-03-23 14:53:15 +00:00
Asger Feldthaus
c067d519d9 JS: Inline some public predicates in GlobalAccessPaths 2021-03-23 14:53:15 +00:00
Asger Feldthaus
61e89d4841 JS: Cache StepSummary and PropertyName 2021-03-23 14:53:14 +00:00
Asger Feldthaus
0056c39bdd JS: Deprecate AdditionalFlowStep 2021-03-23 14:53:14 +00:00
Asger Feldthaus
9e6aac8ef4 JS: Deprecate CollectionFlowStep 2021-03-23 14:53:14 +00:00
Asger Feldthaus
f8f3770a58 JS: BadRandomness can just use type-tracking now 2021-03-23 14:53:14 +00:00
Asger Feldthaus
52c2e37aca JS: Update CollectionStep usage in HTTP 2021-03-23 14:53:14 +00:00
Asger Feldthaus
2759d53f42 JS: SetKeys 2021-03-23 14:53:14 +00:00
Asger Feldthaus
c5ddd40dc3 JS: MapAndSetValues 2021-03-23 14:53:14 +00:00
Asger Feldthaus
9abaad65c6 JS: MapSet 2021-03-23 14:53:14 +00:00
Asger Feldthaus
530be38b84 JS: MapGet 2021-03-23 14:53:14 +00:00
Asger Feldthaus
4a45731c85 JS: SetMapForEach 2021-03-23 14:53:14 +00:00
Asger Feldthaus
c9c99464cf JS: ForOfStep (unify with Arrays version) 2021-03-23 14:53:13 +00:00
Asger Feldthaus
1a5eede39f JS: SetConstructor 2021-03-23 14:53:13 +00:00
Asger Feldthaus
5c9a239776 JS: SetAdd 2021-03-23 14:53:13 +00:00
Asger Feldthaus
98398a9efd JS: add two-prop version of loadStoreStep and infer pseudo properties
Initial step towards migrating CollectionFlowStep to PreCallGraphStep
2021-03-23 14:53:13 +00:00
Asger Feldthaus
67ec5d325c JS: Stop caching AdditionalFlowStep 2021-03-23 14:53:13 +00:00
Asger Feldthaus
adaf3234ec JS: IteratorExceptionStep 2021-03-23 14:53:13 +00:00
Asger Feldthaus
7021be05c5 JS: FlowStepThroughImport 2021-03-23 14:53:13 +00:00
Asger Feldthaus
52279d4bea JS: Rename some test predicates to reflect reality 2021-03-23 14:53:13 +00:00
Asger Feldthaus
fae907df65 JS: Update some uses in tests 2021-03-23 14:53:13 +00:00
Asger Feldthaus
bda074835e JS: Replace uses in ExternalApiUsedWithUntrustedData 2021-03-23 14:53:12 +00:00
Asger Feldthaus
2012e97842 JS: NextJSStaticReactComponentPropsStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
64c7d4e597 JS: NextJSStaticPropsStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
0035defd72 JS: ExceptionStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
5051f10586 JS: ImmutableConstructionStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
3e54136086 JS: Rename EventEmitterFlowStep to reflect reality 2021-03-23 14:53:12 +00:00
Asger Feldthaus
5fe3c1a0a9 JS: EventEmitterTaintStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
3a2f87f0a7 JS: AdditionalTypeTrackingStep -> SharedTypeTrackingStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
b8049f19e2 JS: SharedFlowStepFromPreCallGraph 2021-03-23 14:53:12 +00:00
Asger Feldthaus
8f750d4ad3 JS: UrlSearchParamsTaintStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
f84a05526d JS: ArraySliceStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
633152940c JS: ArrayConcatStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
17d1e6d614 JS: ArraySpliceStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
5d6c6b4b9b JS: ArrayCreationStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
5bfd2ad07f JS: ArrayPopStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
36a8134490 JS: ArrayIndexingAccess 2021-03-23 14:53:11 +00:00
Asger Feldthaus
b7ae62c3a3 JS: ArrayAppendStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
1c815f12da JS: ArrayCopySpread 2021-03-23 14:53:11 +00:00
Asger Feldthaus
151420fd0f JS: ArrayFrom 2021-03-23 14:53:11 +00:00
Asger Feldthaus
e42f8439de JS: Replace uses of AdditionalFlowStep with SharedFlowStep 2021-03-23 14:53:10 +00:00
Asger Feldthaus
24539dc0ee JS: Remove unneeded default case in loadStoreStep 2021-03-23 14:53:10 +00:00
CodeQL CI
a43bb1fb6d Merge pull request #5499 from asgerf/js/non-recursive-sourcenode
Approved by erik-krogh
2021-03-23 14:52:10 +00:00
Asger Feldthaus
23d2f11840 JS: Handle inheritance 2021-03-23 14:39:37 +00:00
Chris Smowton
fa90655dd0 Partial revert: only introduce inferred taint edges from callsite-crossing value edges if an original taint edge targets the *start* of the value edge.
Previously we would also take a taint edge targeting a result and a value-preserving edge propagating another argument to the result to imply a taint edge targeting that argument.
2021-03-23 14:35:03 +00:00
Asger Feldthaus
3d94ccf5dd JS: Support accessor-calls in object literals via local flow 2021-03-23 14:16:06 +00:00
Mathias Vorreiter Pedersen
ce638096de Merge pull request #5492 from geoffw0/samateissue
C++: Test taint regression
2021-03-23 14:01:03 +01:00
Rasmus Wriedt Larsen
f2bc413318 Python: remove single commented out line of code 2021-03-23 14:00:38 +01:00
Tom Hvitved
3c26779f40 Merge pull request #5415 from tamasvajk/feature/async-flow
C#: add store step for return statements inside async methods
2021-03-23 13:59:19 +01:00
Rasmus Wriedt Larsen
a4924856a2 Python: Model known form/field subclasses in Django
I used some ad-hoc QL queries to help me find all these extra instances, but not
quite ready to share that code yet :P
2021-03-23 13:57:39 +01:00
Rasmus Wriedt Larsen
8d0f6086af Python: Model django forms/fields
I'm not feeling 100% confident about `SelfRefMixin`, but since I needed it for
both DjangoViewClass and DjangoFormClass, I wanted to avoid copy-pasting this
code around. However, I'm not so opitimistic about it that I want to add it to a
sharable utility qll file :D
2021-03-23 13:57:38 +01:00
Anders Schack-Mulligen
27408fefe2 Merge pull request #5008 from torque59/cwe-346
Java: Queries to detect remote source flow origins to CORS header.
2021-03-23 13:54:00 +01:00
Anders Schack-Mulligen
9a56601dd3 Merge pull request #5164 from luchua-bc/java/insecure-ldap-endpoint
Java: CWE-297 Query to detect insecure LDAP endpoint configuration
2021-03-23 13:53:51 +01:00
Asger Feldthaus
b5be9d07aa JS: Add change note 2021-03-23 12:51:14 +00:00
Geoffrey White
b38a9d51e6 C++: Effect of 'Don't override getParameterSizeIndex in the model for Accept'... 2021-03-23 12:26:59 +00:00
Geoffrey White
13eb9e0833 C++: Fix the test. 2021-03-23 12:26:58 +00:00
Geoffrey White
30e1b88b7f C++: Extend test. 2021-03-23 12:26:58 +00:00
Asger Feldthaus
6c8b4a82c1 JS: Autoformat 2021-03-23 11:55:37 +00:00
Geoffrey White
da08c6e63e Merge pull request #5496 from MathiasVP/accept-model-getParameterSizeIndex-should-be-none
C++: Don't override getParameterSizeIndex in Accept
2021-03-23 11:42:50 +00:00
Asger Feldthaus
98143b071d JS: Autoformat 2021-03-23 11:26:29 +00:00
Anders Schack-Mulligen
1e6b5391d6 Merge pull request #4994 from haby0/main
Java: CWE-652: Improper Neutralization of Data within XQuery Expressions ('XQuery Injection')
2021-03-23 12:05:53 +01:00
Taus
b46a3616d8 Merge pull request #5490 from RasmusWL/private-imports
Python: Make import private for better auto-complete
2021-03-23 12:00:35 +01:00
Mathias Vorreiter Pedersen
585606a933 C++: Respond to review comments. 2021-03-23 11:14:29 +01:00
Mathias Vorreiter Pedersen
0b4650a4c9 C++: Accept test changes. 2021-03-23 10:27:19 +01:00
Tom Hvitved
20aa05b090 C#: Add CIL SSA library 2021-03-23 10:07:36 +01:00
Mathias Vorreiter Pedersen
7d0cfc69f1 C++: Don't override getParameterSizeIndex in the model for Accept. This fixes IR construction of calls to accept. 2021-03-23 09:53:09 +01:00
Mathias Vorreiter Pedersen
0ff7cc845c C++: Add reduced testcase that broke IR construction in #5492. 2021-03-23 09:53:04 +01:00
yoff
921b560e89 Merge pull request #5489 from tausbn/python-make-getacall-return-a-callcfgnode
Python: Make `API::Node::getACall` return a `CallCfgNode`
2021-03-23 09:31:38 +01:00
Rasmus Lerchedahl Petersen
198a4ca79b Python: Add files to experimental 2021-03-22 21:42:06 +01:00
Taus Brock-Nannestad
7cdf439b83 Python: Clean up basicStoreStep
Moves the `flowsTo` logic into the shared implementation, so that
`TypeTrackingPrivate` only has to define the shape of immediate store
steps.

Also cleans up the documentation to talk a bit more about what
`content` can represent, and what caveats there are.
2021-03-22 18:42:24 +01:00
Taus Brock-Nannestad
0e81fd2624 Python: Move Boolean into TypeTrackerPrivate
In general, this may be defined already for other languages, so moving
it in here will avoid potential clashes.
2021-03-22 18:41:22 +01:00
Marcono1234
993999f64f Java: Add test for negative numeric literals 2021-03-22 17:43:34 +01:00
Asger Feldthaus
6b19e69d30 JS: Fix some join orders 2021-03-22 16:17:19 +00:00
Rasmus Wriedt Larsen
1890e63d4c Python: Make import private for better auto-complete
With the non-private imports, auto-completing on `API::` gave ALL results
available from `import python`, as well as the ones specified in the `API`
module.

The non-private import in Attributes.qll did the same for `DataFlow::`.
2021-03-22 16:45:44 +01:00
Taus Brock-Nannestad
4a6589d0ae Python: Make API::Node::getACall return a CallCfgNode
This should eliminate the need for explicit casting to
`CallCfgNode` (which does not appear in our code as far as I can see,
but was observed in an external contribution).
2021-03-22 16:37:24 +01:00
Asger Feldthaus
42e6c7eb2e JS: Remove field from InvokeNode 2021-03-22 15:19:31 +00:00
Asger Feldthaus
c03e9d6c75 JS: Address review comments 2021-03-22 15:19:31 +00:00
Asger Feldthaus
5bfdca895b JS: Remove recursive def of SourceNode::Range 2021-03-22 15:07:38 +00:00
Asger Feldthaus
230b9cf5d3 JS: Avoid recursion in SourceNode::Range 2021-03-22 15:07:38 +00:00
Rasmus Lerchedahl Petersen
c1e3ccfb6c Python, doc: Note ephemeral nature of import nodes 2021-03-22 15:07:51 +01:00
Rasmus Wriedt Larsen
c8a6e837b5 Python: Model QuerySet chains in django 2021-03-22 14:38:54 +01:00
Tamas Vajk
7a0bfd1a69 Skip through any stub preamble 2021-03-22 12:29:13 +01:00
Asger Feldthaus
54a91c73b0 JS: Tweak summarizedHigherOrderCall 2021-03-22 10:56:03 +00:00
Mathias Vorreiter Pedersen
d09458a486 C++: Add another taint tracking copy to identical-files.json 2021-03-22 11:35:59 +01:00
Mathias Vorreiter Pedersen
7ec86b5e7f C++: AdjustedConfiguration should not extend the same dataflow configuration as FromGlobalVarTaintTrackingCfg as this causes multiple configurations to be in scope for dataflow. 2021-03-22 11:35:29 +01:00
haby0
fe046ec71e Merge remote-tracking branch 'upstream/main' into main 2021-03-22 17:25:37 +08:00
Rasmus Wriedt Larsen
3a83ecf067 Python: Add test for taint in django forms/fields 2021-03-22 10:03:32 +01:00
Rasmus Wriedt Larsen
f800bf243f Python: Better text for getSourceType in Django 2021-03-22 01:39:19 +01:00
Rasmus Wriedt Larsen
701b935564 Python: Add example of QuerySet chain (django) 2021-03-22 00:57:43 +01:00
Marcono1234
1534b387bb Java: Improve documentation regarding minus in front of numeric literals 2021-03-22 00:54:14 +01:00
Artem Smotrakov
6c24699403 Cover both javax.el and jakarta.el packages 2021-03-21 21:19:39 +03:00
Artem Smotrakov
adb1ed380a Added tests for Jakarta expression injection 2021-03-21 21:19:39 +03:00
Artem Smotrakov
73e940de74 Added query for Jakarta EL injections
- Added JakartaExpressionInjection.ql
- Added a qhelp file with examples
2021-03-21 21:19:39 +03:00
yo-h
0200aedc2e Java 16: adjust test options 2021-03-21 12:55:25 -04:00
ihsinme
26bac9f425 Apply suggestions from code review
Co-authored-by: Robert Marsh <rdmarsh2@gmail.com>
2021-03-21 15:25:29 +03:00
Asger Feldthaus
a54e810804 JS: Include accessor-calls in CallGraph.ql 2021-03-20 13:59:38 +00:00
Asger Feldthaus
f4a476ea4e JS: Change type ValueNode -> Node 2021-03-20 09:05:04 +00:00
Dilan
1385b22642 pr fixes, typo in qhelp file and helper method for queries 2021-03-19 16:43:29 -07:00
yoff
164b383fda Update python/ql/test/query-tests/Security/CWE-327/pyOpenSSL_fluent.py
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-19 19:12:13 +01:00
Asger Feldthaus
405c1f3fc7 JS: Update test suite 2021-03-19 16:45:31 +00:00
Asger Feldthaus
fa2ae1420a JS: Rename Diagnostics folder to Summary 2021-03-19 16:43:23 +00:00
Asger Feldthaus
347cbe422d JS: Remove the other summary queries 2021-03-19 16:42:43 +00:00
Asger Feldthaus
0c0556bb38 JS: Update LinesOfCode.ql to match the style from C++ 2021-03-19 16:42:05 +00:00
Asger Feldthaus
6ca425f033 JS: Implement new metric queries for line counting 2021-03-19 16:34:29 +00:00
Asger Feldthaus
ea8c8df653 JS: Fix bad join orders in summarizedHigherOrderCall 2021-03-19 15:30:49 +00:00
Mathias Vorreiter Pedersen
6c1ec6d96b C++: Accept test changes. 2021-03-19 16:09:05 +01:00
Erik Krogh Kristensen
8949b9eb0a add shell interpreted arrays as sinks for js/shell-command-constructed-from-input 2021-03-19 15:59:06 +01:00
Asger Feldthaus
01fd00de56 JS: Fix join order in argumentPassing 2021-03-19 11:49:06 +00:00
Asger F
2f3d516413 JS: Track flow into ES accessors 2021-03-19 11:11:25 +00:00
Asger F
4f46908224 JS: Add test with ES getters/setters 2021-03-19 11:07:15 +00:00
Tamas Vajk
79d6731ed8 C#: Adjust make_stubs.py to use codeql instead of odasa 2021-03-19 11:01:28 +01:00
Erik Krogh Kristensen
36b0ab1de5 Apply suggestions from code review
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-03-19 10:29:38 +01:00
Erik Krogh Kristensen
a28a36ab29 add change-note 2021-03-19 10:10:56 +01:00
Erik Krogh Kristensen
e90fb1a225 reuse classes modelling standard library functions 2021-03-19 10:09:33 +01:00
Rasmus Lerchedahl Petersen
e0e6d5724e Merge branch 'main' of github.com:github/codeql into python-port-insecure-protocol 2021-03-18 23:34:53 +01:00
Erik Krogh Kristensen
d489d63b8e recognize object transformations in module.exports when looking for library inputs 2021-03-18 20:54:33 +01:00
Erik Krogh Kristensen
28ad667578 add model for async-execute 2021-03-18 19:40:46 +01:00
Erik Krogh Kristensen
af5a61782c also look for main modules in a lib folder 2021-03-18 14:51:11 +01:00
Erik Krogh Kristensen
0e98ea0c10 remove spurious import of PackageExports 2021-03-18 14:09:08 +01:00
Erik Krogh Kristensen
67a5831ac0 update expected output 2021-03-18 13:59:44 +01:00
Erik Krogh Kristensen
c0bb169342 recognize a src/index.js file as a main module for a package 2021-03-18 13:41:36 +01:00
Erik Krogh Kristensen
add0c88530 loosen the requirement that the package.json file must be the top-most package.json 2021-03-18 13:39:12 +01:00
Erik Krogh Kristensen
d998d06b94 add link to source in alert-message for js/shell-command-constructed-from-input 2021-03-18 13:37:18 +01:00
Porcuiney Hairs
a88c3682ff remove sanitiserGuards 2021-03-18 16:12:00 +05:30
Porcuiney Hairs
84c9137152 Include suggestions from review 2021-03-18 16:12:00 +05:30
porcupineyhairs
f27d2bdf6d Update java/ql/src/experimental/semmle/code/java/Logging.qll
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-03-18 16:12:00 +05:30
Porcuiney Hairs
d0c82d3756 Add flogger and android logging support 2021-03-18 16:12:00 +05:30
Porcuiney Hairs
17d7ba8049 Add Log Injection Vulnerability 2021-03-18 16:12:00 +05:30
Rasmus Lerchedahl Petersen
b3ff3f7ee7 PythonÆ adjust test expectations
I suspect it has to do with ParameterNode being a LocalSourceNode,
but I really have no idea...
2021-03-17 15:11:17 +01:00
Rasmus Lerchedahl Petersen
8f467003d2 Python: More review suggestions 2021-03-17 15:11:17 +01:00
yoff
63b732ce1f Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2021-03-17 15:11:17 +01:00
Rasmus Lerchedahl Petersen
4d856d4461 Python: Add small api enhancements
determined useful during documentation work.
2021-03-17 15:11:17 +01:00
Mathias Vorreiter Pedersen
3914a93504 C++: Remove commonTaintStep from DefaultTaintTracking. 2021-03-17 11:56:59 +01:00
haby0
c516d69b98 Merge remote-tracking branch 'upstream/main' into main 2021-03-17 16:42:48 +08:00
Tamas Vajk
0b1705f302 C#: Adjust Callable::canReturn to handle Task-like async return types 2021-03-17 09:25:57 +01:00
haby0
15206fd2ce JsonpInjection.ql autoformatted 2021-03-17 15:52:05 +08:00
haby0
98204a15a6 Fix the problem 2021-03-17 15:28:04 +08:00
Mathias Vorreiter Pedersen
43fbcc1c8a C++: Convert all the dataflow configurations to taint configurations. 2021-03-16 22:36:17 +01:00
Mathias Vorreiter Pedersen
dd6b27df24 C++: Fix test annotation. 2021-03-16 22:35:47 +01:00
Tamas Vajk
cd820917bc Remove duplicate yield return entries from global dataflow test 2021-03-16 21:28:58 +01:00
Tamas Vajk
2541e9cb6a C#: Handle async data flow in expression bodied callables 2021-03-16 16:32:47 +01:00
Tamas Vajk
048c72a0f2 C#: Remove YieldReturnKind 2021-03-16 16:20:04 +01:00
Tamas Vajk
aa2abf76ba Make ReturnNodes disjoint (normal, yield, async) 2021-03-16 16:17:27 +01:00
Tamas Vajk
732ef92830 C#: add store step for return statements inside async methods 2021-03-16 15:18:00 +01:00
Tamas Vajk
c684b74b3d C#: Add async dataflow tests 2021-03-16 14:46:16 +01:00
Rasmus Lerchedahl Petersen
6fff746b16 Merge branch 'main' of github.com:github/codeql into python-port-insecure-protocol 2021-03-15 17:37:28 +01:00
Rasmus Lerchedahl Petersen
9a96230523 Python: Add changenote 2021-03-15 17:35:30 +01:00
Rasmus Lerchedahl Petersen
514a69c47a Python: Support ssl.PROTOCOL_TLS_SERVER
and `ssl.PROTOCOL_TLS_CLIENT`
2021-03-15 17:30:01 +01:00
Rasmus Lerchedahl Petersen
87f3ba2684 Python: add tests for ssl.PROTOCOL_TLS_SERVER
and `ssl.PROTOCOL_TLS_CLIENT`
2021-03-15 17:24:39 +01:00
Rasmus Lerchedahl Petersen
731f4559b4 Python: update test expectations 2021-03-15 17:23:58 +01:00
Rasmus Lerchedahl Petersen
4094b18407 Python: Clean up tests 2021-03-15 16:28:08 +01:00
Mathias Vorreiter Pedersen
0ffb80e3b1 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-15 09:42:32 +01:00
Rasmus Lerchedahl Petersen
41c9394b4b Python: update qhelp and example 2021-03-14 09:22:47 +01:00
Taus Brock-Nannestad
f05313435d Python: Move typePreservingStep into Private 2021-03-12 14:06:39 +01:00
Taus Brock-Nannestad
9b8056371f Python: Make the type tracking implementation shareable 2021-03-12 13:51:24 +01:00
luchua-bc
1a2e341b7c Refactor the business logic of the query into a separate predicate 2021-03-12 12:19:37 +00:00
luchua-bc
c8b1bc3a89 Enhance the query 2021-03-11 21:41:34 +00:00
Mathias Vorreiter Pedersen
5667901a2a C++: Accept test changes after merge from main (which changed the path explanations). 2021-03-11 21:16:57 +01:00
luchua-bc
0a35feef76 Exclude CSRF cookies to reduce FPs 2021-03-11 17:28:07 +00:00
luchua-bc
57953c523c Update qldoc 2021-03-11 17:16:36 +00:00
Mathias Vorreiter Pedersen
a2d75c4fed Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-11 18:06:37 +01:00
luchua-bc
eeac7e322a Query to detect insecure configuration of Spring Boot Actuator 2021-03-11 13:46:32 +00:00
Artem Smotrakov
4b7c57c077 Added a comment for getBeanIdentifier()
Co-authored-by: Chris Smowton <smowton@github.com>
2021-03-11 11:52:07 +01:00
Artem Smotrakov
0a5d58ed8a Cover more configurations in UnsafeSpringExporterInConfigurationClass.ql 2021-03-10 21:15:19 +03:00
luchua-bc
a0a1ddee86 Update class name 2021-03-10 17:07:31 +00:00
Mathias Vorreiter Pedersen
bc36e0db43 C++: Accept more test changes. 2021-03-10 16:51:13 +01:00
Mathias Vorreiter Pedersen
cc592b124b Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-10 15:59:48 +01:00
Mathias Vorreiter Pedersen
0b6589c8be C++: Accept test changes. 2021-03-10 15:47:06 +01:00
luchua-bc
f0ddfc9283 Minor qldoc changes 2021-03-10 12:18:55 +00:00
luchua-bc
72f28513eb Move test check to the sink 2021-03-10 12:12:27 +00:00
Anders Schack-Mulligen
4941d9b7bf Java: Add query for CSV framework coverage. 2021-03-10 12:03:44 +01:00
Artem Smotrakov
df60268023 Split qhelp files 2021-03-10 10:49:47 +03:00
luchua-bc
48975fa7d2 Replace sanitizers 2021-03-10 00:17:26 +00:00
Mathias Vorreiter Pedersen
19d08d7b40 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-09 12:35:44 +01:00
Artem Smotrakov
a78f2115f2 Split SpringExporterUnsafeDeserialization.ql 2021-03-09 00:06:38 +03:00
Mathias Vorreiter Pedersen
bb53780ba9 C++: Add flow through unary instructions and pointer/indirection conflation for parameters. These rules are copy/pasted from DefaultTaintTracking. The conflation rules will hopefully be removed as part of #5089. 2021-03-08 09:42:47 +01:00
luchua-bc
0ef3eee4ed Revamp the source and the sink of the query 2021-03-06 22:41:54 +00:00
Artem Smotrakov
891b975899 Use correct file names in SpringExporterUnsafeDeserialization.qhelp 2021-03-06 22:07:43 +01:00
Artem Smotrakov
bda223771b Added another example for SpringExporterUnsafeDeserialization.ql 2021-03-06 22:05:00 +01:00
Artem Smotrakov
82cb4a8d68 Renamed SpringHttpInvokerUnsafeDeserialization.ql 2021-03-06 21:48:35 +01:00
Artem Smotrakov
dcabce679a Cover beans from XML configs in SpringHttpInvokerUnsafeDeserialization.ql 2021-03-06 21:40:35 +01:00
luchua-bc
31eaa80f5b Revamp the source 2021-03-06 00:56:15 +00:00
Rasmus Lerchedahl Petersen
7d556b354d Python: Update test annotation and expectation 2021-03-05 09:16:35 +01:00
haby0
ecdadd1826 move the query to experimental folder 2021-03-05 14:38:04 +08:00
luchua-bc
a93aabab40 Add the toString() method 2021-03-05 03:05:49 +00:00
luchua-bc
919c6b4b0a Optimize flow steps 2021-03-05 02:50:54 +00:00
Francis Alexander
abdebc29f9 Move to experimental and review feedback 2021-03-05 07:26:29 +05:30
Mathias Vorreiter Pedersen
23876cb581 C++: Only allow taint to a FieldAddressInstruction if it's a union type. 2021-03-04 16:29:44 +01:00
ihsinme
10cc574289 Add files via upload 2021-03-04 16:15:26 +03:00
ihsinme
01c13c4703 Add files via upload 2021-03-04 16:14:11 +03:00
haby0
c5577cb09a Fix the problem 2021-03-04 19:54:49 +08:00
Rasmus Lerchedahl Petersen
d02c529872 Python: Update annotation 2021-03-04 00:06:36 +01:00
Rasmus Lerchedahl Petersen
de9469bbfc Python: complete ssl.create_default_context 2021-03-04 00:01:44 +01:00
Rasmus Lerchedahl Petersen
ee03837357 Python: small refactor 2021-03-03 23:46:18 +01:00
Rasmus Lerchedahl Petersen
cbbc7b2bcd Python: support unrestrictions
Also pyOpenSSL allows SSL 2 and SSL 3 on `SSLv23`
2021-03-03 23:42:48 +01:00
luchua-bc
1784c202a7 Clean up the query 2021-03-03 17:03:37 +00:00
Rasmus Lerchedahl Petersen
97d26687fe Python: Improve logic of bit fields 2021-03-03 17:50:47 +01:00
Rasmus Lerchedahl Petersen
7a1d953fca Python: More tests 2021-03-03 17:50:47 +01:00
Rasmus Lerchedahl Petersen
60525ec301 Python: Also track offending call
update test expectations at this point
2021-03-03 17:50:47 +01:00
Rasmus Lerchedahl Petersen
9e696ff0fb Python: Add false negative to test 2021-03-03 17:50:47 +01:00
Rasmus Lerchedahl Petersen
d5171fc043 Python: Comment everything 2021-03-03 17:50:47 +01:00
Rasmus Lerchedahl Petersen
3b856010f2 Python: add TODO comment 2021-03-03 17:50:46 +01:00
Rasmus Lerchedahl Petersen
ea8c6f04e2 Python: Update old test and qlhelp 2021-03-03 17:50:46 +01:00
Rasmus Lerchedahl Petersen
87e1a062ea Python: fluent api tests 2021-03-03 17:50:46 +01:00
Rasmus Lerchedahl Petersen
186db7f43e Python: factor into modules and files 2021-03-03 17:50:46 +01:00
Rasmus Lerchedahl Petersen
7ed018aff6 Python: refactor into modules
and turn on the pyOpenSSL module
2021-03-03 17:50:46 +01:00
Rasmus Lerchedahl Petersen
72b37a5b1b Python: factor out barrier 2021-03-03 17:50:46 +01:00
Rasmus Lerchedahl Petersen
86dde6eab1 Python: start of port 2021-03-03 17:50:46 +01:00
luchua-bc
502cf38fcc Use concise API 2021-03-03 14:07:43 +00:00
luchua-bc
1b1c3f953b Remove localflow from the source 2021-03-03 13:54:26 +00:00
luchua-bc
b366ffa69e Revamp source of the query 2021-03-03 13:38:18 +00:00
Artem Smotrakov
617ba65ef5 Improved docs for SpringHttpInvokerUnsafeDeserialization.ql 2021-03-02 21:36:14 +01:00
Mathias Vorreiter Pedersen
eb4f1e1ba0 C++: Restore some of the lost test results by doing operand -> instruction taint steps in IR TaintTracking. 2021-03-02 15:45:40 +01:00
Mathias Vorreiter Pedersen
23d3109071 C++: Use taintedWithPath in more tests. This is the predicate that's currently hooked up to the new IR taint tracking library. 2021-03-02 13:40:39 +01:00
Mathias Vorreiter Pedersen
6ba35f4aac C++: Fix function renaming and accept test change. 2021-03-02 11:31:24 +01:00
Mathias Vorreiter Pedersen
9f02c144a8 C++: Remove files that were incorrectly added when resolving merge conflicts. 2021-03-02 11:14:49 +01:00
Mathias Vorreiter Pedersen
ffc6af73b7 C++: Accept test changes. 2021-03-02 11:00:43 +01:00
Mathias Vorreiter Pedersen
748f5344ff Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-02 10:43:37 +01:00
luchua-bc
95d1994196 Query to check sensitive cookies without the HttpOnly flag set 2021-03-01 22:06:52 +00:00
Artem Smotrakov
15a43ffe36 Simplified returnsRemoteInvocationSerializingExporter() 2021-02-27 13:41:20 +01:00
haby0
f795d5e0d3 update JSONP Injection ql 2021-02-27 16:25:17 +08:00
haby0
0521ef87da Merge remote-tracking branch 'upstream/main' into JsonHijacking 2021-02-25 16:31:14 +08:00
Artem Smotrakov
e02b51f42b Improved SpringHttpInvokerUnsafeDeserialization.qhelp 2021-02-24 22:35:20 +01:00
Artem Smotrakov
aac0c27dcd Added tests for SpringHttpInvokerUnsafeDeserialization.ql 2021-02-24 22:35:20 +01:00
Artem Smotrakov
95284ad71d Added SpringHttpInvokerUnsafeDeserialization.qhelp and example 2021-02-24 22:35:20 +01:00
Artem Smotrakov
476309af6d Added SpringHttpInvokerUnsafeDeserialization.ql 2021-02-24 22:35:20 +01:00
haby0
6fe8bafc7d *)update 2021-02-24 20:59:51 +08:00
haby0
872a000a33 *)update to JSONP injection 2021-02-24 20:36:12 +08:00
Francis Alexander
45bdb22db8 Switch from sanitizer to tainttracking, formatting and qldoc changes 2021-02-21 16:45:48 +05:30
haby0
8119fd2ad1 *)add JsonHijacking ql query 2021-02-18 18:11:10 +08:00
Francis Alexander
2baf2aa5c1 Apply suggestions from code review - improved sanitizer checks.
Co-authored-by: Alvaro Muñoz <pwntester@github.com>
2021-02-17 18:58:32 +05:30
Francis Alexander
40f4e71b86 Merge branch 'main' into cwe-346 2021-02-17 18:55:31 +05:30
Francis Alexander
58971f9f4e Switch qualified name to available CollectionType 2021-02-17 16:01:27 +05:30
Francis Alexander
520ba47293 Sanitizer improvements from code review 2021-02-17 08:35:50 +05:30
luchua-bc
e698ee77f7 Update qldoc and test method 2021-02-16 14:11:39 +00:00
haby0
2c96e6cf96 Merge remote-tracking branch 'upstream/main' into main 2021-02-16 17:54:01 +08:00
luchua-bc
5ce3af0591 Enhance the query and update qldoc 2021-02-15 21:38:54 +00:00
haby0
92c00cb741 Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-02-16 00:09:21 +08:00
haby0
f1e44bce4a Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-02-16 00:07:44 +08:00
luchua-bc
a03e6faf37 Optimize the query and update qldoc 2021-02-15 14:10:17 +00:00
Francis Alexander
409d95c522 Sanitizer checks to decrease FP 2021-02-15 14:01:14 +05:30
luchua-bc
23f620d255 Query to detect insecure LDAP endpoint configuration 2021-02-15 05:31:29 +00:00
luchua-bc
6a6727fc80 Reduce the scope of the query to reduce FPs 2021-02-14 15:01:06 +00:00
haby0
6901cd4899 Merge branch 'main' of https://github.com/haby0/codeql into main 2021-02-12 11:18:33 +08:00
haby0
22e741c7a3 *)add XQExpression.executeCommand(0) sink 2021-02-12 11:17:42 +08:00
haby0
dbb3d458f5 *)add XQExpression.executeCommand(0) sink 2021-02-12 10:47:41 +08:00
haby0
a6a0fa28c4 *)add XQExpression.executeQuery(0) sink 2021-02-11 16:05:48 +08:00
haby0
97690b4eb7 Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.qhelp
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2021-02-08 19:15:28 +08:00
luchua-bc
ff1ed3a012 Revamp the query to use three configurations to detect password hash without salt 2021-01-29 03:39:02 +00:00
haby0
81c56b9bed Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-27 19:47:12 +08:00
haby0
31deca016f Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-27 19:46:45 +08:00
haby0
ca2e6587fe Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-27 19:46:15 +08:00
haby0
b5ae417851 *)update CWE-652 qhelp references 2021-01-27 10:19:04 +08:00
haby0
b76854a384 *)add CWE-652 test case 2021-01-27 10:14:33 +08:00
Francis Alexander
19872e9aed More Feedback integration 2021-01-26 17:24:17 +05:30
Francis Alexander
985d3d469a PR feedback integration 2021-01-25 23:26:36 +05:30
haby0
42f55e1ebe Merge pull request #1 from smowton/smowton/admin/rewrite-xquery
Rewrite XQuery injection to use an additional taint step instead of multiple configurations
2021-01-25 19:49:20 +08:00
Chris Smowton
d34233b44f Rewrite XQuery injection to use an additional taint step instead of multiple configurations.
Also remove a needless barrier -- the method in question doesn't conduct taint by default, so excluding particular instances of that call is not necessary.
2021-01-25 11:18:45 +00:00
haby0
16308fe557 Update java/ql/src/Security/CWE/CWE-652/XQueryInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-25 19:16:18 +08:00
haby0
14a23eed4f Update java/ql/src/Security/CWE/CWE-652/XQueryInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-25 19:15:59 +08:00
Francis Alexander
75b79039a1 Example fixes 2021-01-24 20:46:37 +05:30
Francis Alexander
81e372d078 Formatting changes 2021-01-24 20:44:21 +05:30
Francis Alexander
a64fc2b24e Java: Queries to detect remote source flow to CORS header 2021-01-24 18:58:39 +05:30
haby0
0b326aae20 *)update XQueryInjectionLib.qll 2021-01-23 18:27:38 +08:00
haby0
44d99f8cd4 *)update XQueryInjection.ql 2021-01-23 18:26:58 +08:00
haby0
ec4c155043 *)update XQueryInjection.qhelp 2021-01-23 18:26:15 +08:00
haby0
a56dd60baa *)add CWE-652 XQueryInjection detection 2021-01-21 19:18:10 +08:00
luchua-bc
b9809b071e Update the query to work with wrapper classes 2021-01-18 19:22:34 +00:00
luchua-bc
048167d39a Revamp the query to reduce FPs introduced by wrapper calls 2021-01-18 04:23:30 +00:00
luchua-bc
3af8773dd6 Add more cases 2021-01-15 16:20:31 +00:00
luchua-bc
86c04e6971 Detect the scenario of passwords concatenated with a salt to reduce FPs 2021-01-11 16:59:57 +00:00
luchua-bc
39103af718 Remove additional taint step 2021-01-08 13:02:57 +00:00
luchua-bc
b56fe2b25f Remove specific method name in additional taint step 2021-01-07 16:31:21 +00:00
luchua-bc
19ff00bad4 Enhance the additional step flow and update qldoc 2021-01-07 13:15:30 +00:00
luchua-bc
ce2db21f15 Query to detect hash without salt 2021-01-06 17:30:04 +00:00
Robert Marsh
77729918c1 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Update for submodule pointer
2020-11-18 13:09:02 -08:00
Robert Marsh
5aed82a210 C++: Autoformat more 2020-11-17 13:44:20 -08:00
Robert Marsh
04641a3f2d Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2020-11-17 12:55:12 -08:00
Robert Marsh
c2e44fa180 C++: autoformat 2020-11-17 09:28:39 -08:00
Robert Marsh
db8766ca69 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2020-11-16 17:46:20 -08:00
Robert Marsh
525aeb6551 C++: autoformat 2020-11-13 16:14:07 -08:00
Robert Marsh
29eacbd28b Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Update for submodule bump
2020-11-13 12:22:41 -08:00
Robert Marsh
bd00988c37 C++: accept test output for DefaultTaintTracking 2020-11-12 14:38:53 -08:00
Robert Marsh
68040b717e C++: autoformat 2020-11-12 14:32:19 -08:00
Robert Marsh
275d75295c Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Fix test conflict
2020-11-12 13:28:10 -08:00
Robert Marsh
049bff09e6 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Make this branch a valid taget for a submodule bump
2020-11-10 14:25:05 -08:00
Robert Marsh
2a6ba40a93 C++: Accept more test changes 2020-11-10 13:59:35 -08:00
Robert Marsh
04ad94d1cc C++: model taint from pointers to aliased buffers 2020-11-09 13:52:08 -08:00
Robert Marsh
afbeca0d54 C++: Accept test outputs 2020-11-09 13:24:31 -08:00
Robert Marsh
95ed5465de C++: improve handling of function arguments in DTT 2020-11-09 13:02:06 -08:00
Robert Marsh
fbe857d1fa C++: require that other operands be predictable
This brings back a constraint that was lost when switching
DefaultTaintTracking to use a TaintTracking::Configuration
2020-11-09 13:00:55 -08:00
Robert Marsh
7d79be71d1 C++: taint tracking conf in DefaultTaintTracking
Switch from using additional flow steps with a DataFlow::Configuration
in DefaultTaintTracking to using a TaintTracking::Configuration. This
makes future improvements to TaintTracking::Configuration reflected in
DefaultTaintTracking without further effort. It also removes the
predictability constraint in DefaultTaintTracking, which increases the
number of results, with both new true positives and new false positives.
Those may need to be addressed on a per-query basis.

There are some additional regressions from losing pointer/object
conflation for arguments. Those can be worked around by adding that
conflation to TaintTracking::Configuration until precise indirect
parameter flow is ready.
2020-11-09 13:00:55 -08:00
dilanbhalla
26b030f8cc fixed pr suggestions 2020-07-07 10:52:26 -07:00
dilanbhalla
dc73fcc4e8 moved to experimental 2020-07-01 09:54:58 -07:00
dilanbhalla
dc58f6fa87 function/class synatax 2020-06-25 11:39:09 -07:00
1555 changed files with 56657 additions and 23528 deletions

30
.github/workflows/close-stale.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Mark stale issues
on:
workflow_dispatch:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
if: github.repository == 'github/codeql'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Comment or remove the `Stale` label in order to avoid having this issue closed in 7 days.'
close-issue-message: 'This issue was closed because it has been inactive for 7 days.'
days-before-stale: 14
days-before-close: 7
only-labels: awaiting-response
# do not mark PRs as stale
days-before-pr-stale: -1
days-before-pr-close: -1
# Uncomment for dry-run
# debug-only: true
# operations-per-run: 1000

View File

@@ -19,13 +19,18 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@main
# Override language selection by uncommenting this and choosing your languages
with:
languages: csharp
@@ -34,7 +39,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@main
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -48,4 +53,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@main

View File

@@ -1,29 +0,0 @@
# When a PR is labelled with 'ready-for-docs-review',
# this workflow comments on the PR to notify the GitHub CodeQL docs team.
name: Request docs review
on:
# Runs in the context of the base repo.
# This gives the workflow write access to comment on PRs.
# The workflow should not check out or build the given ref,
# or use untrusted data from the event payload in a command line.
pull_request_target:
types: [labeled]
jobs:
request-docs-review:
name: Request docs review
# Run only on labelled PRs to the main repository.
# Do not run on PRs to forks.
if:
github.event.label.name == 'ready-for-docs-review'
&& github.event.pull_request.draft == false
&& github.event.pull_request.base.repo.full_name == 'github/codeql'
runs-on: ubuntu-latest
steps:
- name: Comment to request docs review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
gh pr comment "$PR_NUMBER" --repo "github/codeql" \
--body "Hello @github/docs-content-codeql - this PR is ready for docs review."

View File

@@ -5,6 +5,7 @@
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll",
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll",
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll",
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll",
@@ -36,6 +37,7 @@
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
@@ -55,6 +57,10 @@
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
],
"DataFlow Java/C# Flow Summaries": [
"java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll"
],
"SsaReadPosition Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
@@ -376,7 +382,6 @@
],
"DuplicationProblems.inc.qhelp": [
"cpp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp",
"csharp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp",
"javascript/ql/src/Metrics/DuplicationProblems.inc.qhelp",
"python/ql/src/Metrics/DuplicationProblems.inc.qhelp"
],
@@ -429,10 +434,15 @@
"SSA C#": [
"csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll"
"csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll"
],
"CryptoAlgorithms Python/JS": [
"javascript/ql/src/semmle/javascript/security/CryptoAlgorithms.qll",
"python/ql/src/semmle/crypto/Crypto.qll"
],
"SensitiveDataHeuristics Python/JS": [
"javascript/ql/src/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
"python/ql/src/semmle/python/security/internal/SensitiveDataHeuristics.qll"
]
}

View File

@@ -5,6 +5,7 @@ using System;
using System.Linq;
using Microsoft.Build.Construction;
using System.Xml;
using System.IO;
namespace Semmle.Autobuild.Cpp.Tests
{
@@ -43,6 +44,8 @@ namespace Semmle.Autobuild.Cpp.Tests
public IDictionary<string, int> RunProcess = new Dictionary<string, int>();
public IDictionary<string, string> RunProcessOut = new Dictionary<string, string>();
public IDictionary<string, string> RunProcessWorkingDirectory = new Dictionary<string, string>();
public HashSet<string> CreateDirectories { get; } = new HashSet<string>();
public HashSet<(string, string)> DownloadFiles { get; } = new HashSet<(string, string)>();
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? env, out IList<string> stdOut)
{
@@ -135,6 +138,14 @@ namespace Semmle.Autobuild.Cpp.Tests
string IBuildActions.GetFullPath(string path) => path;
string? IBuildActions.GetFileName(string? path) => Path.GetFileName(path?.Replace('\\', '/'));
public string? GetDirectoryName(string? path)
{
var dir = Path.GetDirectoryName(path?.Replace('\\', '/'));
return dir is null ? path : path?.Substring(0, dir.Length);
}
void IBuildActions.WriteAllText(string filename, string contents)
{
}
@@ -153,6 +164,18 @@ namespace Semmle.Autobuild.Cpp.Tests
s = s.Replace($"%{kvp.Key}%", kvp.Value);
return s;
}
public void CreateDirectory(string path)
{
if (!CreateDirectories.Contains(path))
throw new ArgumentException($"Missing CreateDirectory, {path}");
}
public void DownloadFile(string address, string fileName)
{
if (!DownloadFiles.Contains((address, fileName)))
throw new ArgumentException($"Missing DownloadFile, {address}, {fileName}");
}
}
/// <summary>
@@ -213,6 +236,7 @@ namespace Semmle.Autobuild.Cpp.Tests
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_SOURCE_ARCHIVE_DIR"] = "";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_ROOT"] = $@"C:\codeql\{codeqlUpperLanguage.ToLowerInvariant()}";
Actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
Actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = "win64";
Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa";
Actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java";
Actions.GetEnvironmentVariable["SEMMLE_PLATFORM_TOOLS"] = @"C:\odasa\tools";
@@ -273,7 +297,8 @@ namespace Semmle.Autobuild.Cpp.Tests
[Fact]
public void TestCppAutobuilderSuccess()
{
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test.sln"] = 1;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /p:UseSharedCompilation=false /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
@@ -286,11 +311,13 @@ namespace Semmle.Autobuild.Cpp.Tests
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = true;
Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.slx";
Actions.EnumerateDirectories[@"C:\Project"] = "";
Actions.CreateDirectories.Add(@"C:\Project\.nuget");
Actions.DownloadFiles.Add(("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", @"C:\Project\.nuget\nuget.exe"));
var autobuilder = CreateAutoBuilder(true);
var solution = new TestSolution(@"C:\Project\test.sln");
autobuilder.ProjectsOrSolutionsToBuild.Add(solution);
TestAutobuilderScript(autobuilder, 0, 2);
TestAutobuilderScript(autobuilder, 0, 3);
}
}
}

View File

@@ -0,0 +1,2 @@
lgtm
* The `cpp/tainted-arithmetic`, `cpp/arithmetic-with-extreme-values`, and `cpp/uncontrolled-arithmetic` queries now recognize more functions as returning the absolute value of their input. As a result, they produce fewer false positives.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The 'Assignment where comparison was intended' (cpp/assign-where-compare-meant) query has been improved to flag fewer benign assignments in conditionals.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The 'Unsigned difference expression compared to zero' (cpp/unsigned-difference-expression-compared-zero) query has been improved to produce fewer false positive results.

View File

@@ -0,0 +1,2 @@
lgtm
* The queries cpp/tainted-arithmetic, cpp/uncontrolled-arithmetic, and cpp/arithmetic-with-extreme-values have been improved to produce fewer false positives.

View File

@@ -0,0 +1,2 @@
codescanning
* The 'Pointer to stack object used as return value' (cpp/return-stack-allocated-object) query has been deprecated, and any uses should be replaced with `Returning stack-allocated memory` (cpp/return-stack-allocated-memory).

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The 'Comparison with wider type' (cpp/comparison-with-wider-type) query has been improved to produce fewer false positives.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The `exprMightOverflowPositively` and `exprMightOverflowNegatively` predicates from the `SimpleRangeAnalysis` library now recognize more expressions that might overflow.

View File

@@ -39,7 +39,7 @@ then replace all the relevant occurrences in the code.</p>
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, published by Prentice Hall PTR (1997).
Chapter 5: Object Life Cycle, Rec 5.4 (<a href="http://mongers.org/industrial-c++/">PDF</a>).
Chapter 5: Object Life Cycle, Rec 5.4 (<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">PDF</a>).
</li>
<li>
<a href="https://www.securecoding.cert.org/confluence/display/c/DCL06-C.+Use+meaningful+symbolic+constants+to+represent+literal+values">DCL06-C. Use meaningful symbolic constants to represent literal values</a>

View File

@@ -38,7 +38,7 @@ constant.</p>
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, published by Prentice Hall PTR (1997).
Chapter 5: Object Life Cycle, Rec 5.4 (<a href="http://mongers.org/industrial-c++/">PDF</a>).
Chapter 5: Object Life Cycle, Rec 5.4 (<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">PDF</a>).
</li>
<li>
<a href="https://www.securecoding.cert.org/confluence/display/c/DCL06-C.+Use+meaningful+symbolic+constants+to+represent+literal+values">DCL06-C. Use meaningful symbolic constants to represent literal values</a>

View File

@@ -21,7 +21,7 @@ Review the purpose of the each global variable flagged by this rule and update e
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, published by Prentice Hall PTR (1997).
Chapter 1: Naming, Rec 1.1 (<a href="http://mongers.org/industrial-c++/">PDF</a>).
Chapter 1: Naming, Rec 1.1 (<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">PDF</a>).
</li>
<li>
<a href="http://www.learncpp.com/cpp-tutorial/42-global-variables/">Global variables</a>.

View File

@@ -45,7 +45,7 @@ this rule.
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, Rule 4.6. Prentice Hall PTR, 1997.
(<a href="http://mongers.org/industrial-c++/">PDF</a>).
(<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">PDF</a>).
</li>
<li>
cplusplus.com: <a href="http://www.cplusplus.com/doc/tutorial/control/">Control Structures</a>.

View File

@@ -7,6 +7,8 @@
* @tags reliability
* security
* external/cwe/cwe-562
* @deprecated This query is not suitable for production use and has been deprecated. Use
* cpp/return-stack-allocated-memory instead.
*/
import semmle.code.cpp.pointsto.PointsTo

View File

@@ -32,7 +32,7 @@ Check the return value of functions that return status information.
<references>
<li>
M. Henricson and E. Nyquist, <i>Industrial Strength C++</i>, Chapter 12: Error handling. Prentice Hall PTR, 1997 (<a href="http://mongers.org/industrial-c++/">available online</a>).
M. Henricson and E. Nyquist, <i>Industrial Strength C++</i>, Chapter 12: Error handling. Prentice Hall PTR, 1997 (<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">available online</a>).
</li>
<li>
The CERT C Secure Coding Standard: <a href="https://www.securecoding.cert.org/confluence/display/perl/EXP32-PL.+Do+not+ignore+function+return+values">EXP32-PL. Do not ignore function return values</a>.

View File

@@ -9,6 +9,8 @@
* @id cpp/signed-overflow-check
* @tags correctness
* security
* external/cwe/cwe-128
* external/cwe/cwe-190
*/
import cpp

View File

@@ -7,12 +7,12 @@
* @kind path-problem
* @problem.severity warning
* @precision high
* @id cpp/upcast-array-pointer-arithmetic
* @tags correctness
* reliability
* security
* external/cwe/cwe-119
* external/cwe/cwe-843
* @id cpp/upcast-array-pointer-arithmetic
*/
import cpp

View File

@@ -8,6 +8,8 @@
* @tags reliability
* correctness
* security
* external/cwe/cwe-190
* external/cwe/cwe-253
*/
import cpp

View File

@@ -9,6 +9,7 @@
* @tags reliability
* correctness
* security
* external/cwe/cwe-234
* external/cwe/cwe-685
*/

View File

@@ -54,7 +54,7 @@ class BooleanControllingAssignmentInExpr extends BooleanControllingAssignment {
override predicate isWhitelisted() {
this.getConversion().(ParenthesisExpr).isParenthesised()
or
// whitelist this assignment if all comparison operations in the expression that this
// Allow this assignment if all comparison operations in the expression that this
// assignment is part of, are not parenthesized. In that case it seems like programmer
// is fine with unparenthesized comparison operands to binary logical operators, and
// the parenthesis around this assignment was used to call it out as an assignment.
@@ -62,6 +62,21 @@ class BooleanControllingAssignmentInExpr extends BooleanControllingAssignment {
forex(ComparisonOperation op | op = getComparisonOperand*(this.getParent+()) |
not op.isParenthesised()
)
or
// Match a pattern like:
// ```
// if((a = b) && use_value(a)) { ... }
// ```
// where the assignment is meant to update the value of `a` before it's used in some other boolean
// subexpression that is guarenteed to be evaluate _after_ the assignment.
this.isParenthesised() and
exists(LogicalAndExpr parent, Variable var, VariableAccess access |
var = this.getLValue().(VariableAccess).getTarget() and
access = var.getAnAccess() and
not access.isUsedAsLValue() and
parent.getRightOperand() = access.getParent*() and
parent.getLeftOperand() = this.getParent*()
)
}
}

View File

@@ -26,7 +26,7 @@ indication that there may be cases unhandled by the <code>switch</code> statemen
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/switch-statement-cpp">switch statement (C++)</a>
</li>
<li>
M. Henricson and E. Nyquist, <i>Industrial Strength C++</i>, Chapter 4: Control Flow, Rec 4.5. Prentice Hall PTR, 1997 (<a href="http://mongers.org/industrial-c++/">available online</a>).
M. Henricson and E. Nyquist, <i>Industrial Strength C++</i>, Chapter 4: Control Flow, Rec 4.5. Prentice Hall PTR, 1997 (<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">available online</a>).
</li>

View File

@@ -8,6 +8,7 @@
* @id cpp/pointer-overflow-check
* @tags reliability
* security
* external/cwe/cwe-758
*/
import cpp

View File

@@ -13,6 +13,7 @@
import cpp
import semmle.code.cpp.dataflow.EscapesTree
import semmle.code.cpp.models.interfaces.PointerWrapper
import semmle.code.cpp.dataflow.DataFlow
/**
@@ -39,6 +40,10 @@ predicate hasNontrivialConversion(Expr e) {
e instanceof ParenthesisExpr
)
or
// A smart pointer can be stack-allocated while the data it points to is heap-allocated.
// So we exclude such "conversions" from this predicate.
e = any(PointerWrapper wrapper).getAnUnwrapperFunction().getACallToThisFunction()
or
hasNontrivialConversion(e.getConversion())
}

View File

@@ -10,6 +10,7 @@
* @tags correctness
* language-features
* security
* external/cwe/cwe-670
*/
import cpp

View File

@@ -12,6 +12,8 @@
* @tags correctness
* maintainability
* security
* external/cwe/cwe-234
* external/cwe/cwe-685
*/
import cpp

View File

@@ -5,7 +5,6 @@
* @kind treemap
* @treemap.warnOn highValues
* @metricType externalDependency
* @precision medium
* @id cpp/external-dependencies
* @tags modularity
*/

View File

@@ -7,7 +7,6 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
* @precision very-high
* @id cpp/lines-of-code-in-files
* @tags maintainability
* complexity

View File

@@ -5,7 +5,6 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
* @precision high
* @id cpp/lines-of-commented-out-code-in-files
* @tags documentation
*/

View File

@@ -7,7 +7,6 @@
* @treemap.warnOn lowValues
* @metricType file
* @metricAggregate avg sum max
* @precision very-high
* @id cpp/lines-of-comments-in-files
* @tags maintainability
* documentation

View File

@@ -8,7 +8,6 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
* @precision high
* @id cpp/duplicated-lines-in-files
* @tags testability
* modularity

View File

@@ -5,7 +5,6 @@
* @treemap.warnOn lowValues
* @metricType file
* @metricAggregate avg sum max
* @precision medium
* @id cpp/tests-in-files
* @tags maintainability
*/

View File

@@ -29,7 +29,7 @@ build time: the more included files, the longer the compilation time.</p>
<a href="http://www.drdobbs.com/cpp/decoupling-c-header-files/212701130">Decoupling C Header Files</a>
</li>
<li>
<a href="https://wiki.hsr.ch/Prog3/files/overload72-FINAL_DesigningHeaderFiles.pdf">C++ Best Practice -
<a href="https://accu.org/journals/overload/14/72/griffiths_1995/">C++ Best Practice -
Designing Header Files</a>
</li>

View File

@@ -35,7 +35,7 @@ they are contributing to unnecessarily long build times and creating artificial
<a href="http://www.drdobbs.com/cpp/decoupling-c-header-files/212701130">Decoupling C Header Files</a>
</li>
<li>
<a href="https://wiki.hsr.ch/Prog3/files/overload72-FINAL_DesigningHeaderFiles.pdf">C++ Best Practice -
<a href="https://accu.org/journals/overload/14/72/griffiths_1995/">C++ Best Practice -
Designing Header Files</a>
</li>
</references>

View File

@@ -49,7 +49,9 @@ where
small = rel.getLesserOperand() and
large = rel.getGreaterOperand() and
rel = l.getCondition().getAChild*() and
upperBound(large).log2() > getComparisonSize(small) * 8 and
forall(Expr conv | conv = large.getConversion*() |
upperBound(conv).log2() > getComparisonSize(small) * 8
) and
// Ignore cases where the smaller type is int or larger
// These are still bugs, but you should need a very large string or array to
// trigger them. We will want to disable this for some applications, but it's

View File

@@ -28,6 +28,7 @@ predicate outOfBoundsExpr(Expr expr, string kind) {
from Expr use, Expr origin, string kind
where
not use.getUnspecifiedType() instanceof PointerType and
outOfBoundsExpr(use, kind) and
tainted(origin, use) and
origin != use and

View File

@@ -12,29 +12,60 @@
import cpp
import semmle.code.cpp.commons.Exclusions
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
import semmle.code.cpp.controlflow.Guards
import semmle.code.cpp.dataflow.DataFlow
/** Holds if `sub` is guarded by a condition which ensures that `left >= right`. */
/**
* Holds if `sub` is guarded by a condition which ensures that
* `left >= right`.
*/
pragma[noinline]
predicate isGuarded(SubExpr sub, Expr left, Expr right) {
exists(GuardCondition guard |
guard.controls(sub.getBasicBlock(), true) and
guard.ensuresLt(left, right, 0, sub.getBasicBlock(), false)
exists(GuardCondition guard, int k |
guard.controls(sub.getBasicBlock(), _) and
guard.ensuresLt(left, right, k, sub.getBasicBlock(), false) and
k >= 0
)
}
/** Holds if `sub` will never be negative. */
predicate nonNegative(SubExpr sub) {
not exprMightOverflowNegatively(sub.getFullyConverted())
/**
* Holds if `n` is known or suspected to be less than or equal to
* `sub.getLeftOperand()`.
*/
predicate exprIsSubLeftOrLess(SubExpr sub, DataFlow::Node n) {
n.asExpr() = sub.getLeftOperand()
or
// The subtraction is guarded by a check of the form `left >= right`.
exists(GVN left, GVN right |
// This is basically a poor man's version of a directional unbind operator.
strictcount([left, globalValueNumber(sub.getLeftOperand())]) = 1 and
strictcount([right, globalValueNumber(sub.getRightOperand())]) = 1 and
isGuarded(sub, left.getAnExpr(), right.getAnExpr())
exists(DataFlow::Node other |
// dataflow
exprIsSubLeftOrLess(sub, other) and
(
DataFlow::localFlowStep(n, other) or
DataFlow::localFlowStep(other, n)
)
)
or
exists(DataFlow::Node other |
// guard constraining `sub`
exprIsSubLeftOrLess(sub, other) and
isGuarded(sub, other.asExpr(), n.asExpr()) // other >= n
)
or
exists(DataFlow::Node other, float p, float q |
// linear access of `other`
exprIsSubLeftOrLess(sub, other) and
linearAccess(n.asExpr(), other.asExpr(), p, q) and // n = p * other + q
p <= 1 and
q <= 0
)
or
exists(DataFlow::Node other, float p, float q |
// linear access of `n`
exprIsSubLeftOrLess(sub, other) and
linearAccess(other.asExpr(), n.asExpr(), p, q) and // other = p * n + q
p >= 1 and
q >= 0
)
}
@@ -45,5 +76,6 @@ where
ro.getLesserOperand().getValue().toInt() = 0 and
ro.getGreaterOperand() = sub and
sub.getFullyConverted().getUnspecifiedType().(IntegralType).isUnsigned() and
not nonNegative(sub)
exprMightOverflowNegatively(sub.getFullyConverted()) and // generally catches false positives involving constants
not exprIsSubLeftOrLess(sub, DataFlow::exprNode(sub.getRightOperand())) // generally catches false positives where there's a relation between the left and right operands
select ro, "Unsigned subtraction can never be negative."

View File

@@ -93,7 +93,7 @@ class QuotedCommandInCreateProcessFunctionConfiguration extends DataFlow2::Confi
bindingset[s]
predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) {
s.regexpMatch("\"([^\"])*\"(\\s|.)*") // The first element (path) is quoted
s.regexpMatch("\"([^\"])*\"[\\s\\S]*") // The first element (path) is quoted
or
s.regexpMatch("[^\\s]+") // There are no spaces in the string
}

View File

@@ -0,0 +1,14 @@
while(intIndex > 2)
{
...
intIndex--;
...
} // GOOD: correct cycle
...
while(intIndex > 2)
{
...
int intIndex;
intIndex--;
...
} // BAD: the variable used in the condition does not change.

View File

@@ -0,0 +1,26 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using variables with the same name is dangerous. However, such a situation inside the while loop can create an infinite loop exhausting resources. Requires the attention of developers.</p>
</overview>
<recommendation>
<p>We recommend not to use local variables inside a loop if their names are the same as the variables in the condition of this loop.</p>
</recommendation>
<example>
<p>The following example demonstrates an erroneous and corrected use of a local variable within a loop.</p>
<sample src="DeclarationOfVariableWithUnnecessarilyWideScope.c" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL01-C.+Do+not+reuse+variable+names+in+subscopes">DCL01-C. Do not reuse variable names in subscopes</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,60 @@
/**
* @name Errors When Using Variable Declaration Inside Loop
* @description Using variables with the same name is dangerous.
* However, such a situation inside the while loop can create an infinite loop exhausting resources.
* Requires the attention of developers.
* @kind problem
* @id cpp/errors-when-using-variable-declaration-inside-loop
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-1126
*/
import cpp
/**
* Errors when using a variable declaration inside a loop.
*/
class DangerousWhileLoop extends WhileStmt {
Expr exp;
Declaration dl;
DangerousWhileLoop() {
this = dl.getParentScope().(BlockStmt).getParent*() and
exp = this.getCondition().getAChild*() and
not exp instanceof PointerFieldAccess and
not exp instanceof ValueFieldAccess and
exp.(VariableAccess).getTarget().getName() = dl.getName() and
not exp.getParent*() instanceof FunctionCall
}
Declaration getDeclaration() { result = dl }
/** Holds when there are changes to the variables involved in the condition. */
predicate isUseThisVariable() {
exists(Variable v |
this.getCondition().getAChild*().(VariableAccess).getTarget() = v and
(
exists(Assignment aexp |
this = aexp.getEnclosingStmt().getParentStmt*() and
(
aexp.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = v
or
aexp.getLValue().(VariableAccess).getTarget() = v
)
)
or
exists(CrementOperation crm |
this = crm.getEnclosingStmt().getParentStmt*() and
crm.getOperand().(VariableAccess).getTarget() = v
)
)
)
}
}
from DangerousWhileLoop lp
where not lp.isUseThisVariable()
select lp.getDeclaration(), "A variable with this name is used in the $@ condition.", lp, "loop"

View File

@@ -0,0 +1,43 @@
// BAD: the allocation will throw an unhandled exception
// instead of returning a null pointer.
void bad1(std::size_t length) noexcept {
int* dest = new int[length];
if(!dest) {
return;
}
std::memset(dest, 0, length);
// ...
}
// BAD: the allocation won't throw an exception, but
// instead return a null pointer.
void bad2(std::size_t length) noexcept {
try {
int* dest = new(std::nothrow) int[length];
std::memset(dest, 0, length);
// ...
} catch(std::bad_alloc&) {
// ...
}
}
// GOOD: the allocation failure is handled appropiately.
void good1(std::size_t length) noexcept {
try {
int* dest = new int[length];
std::memset(dest, 0, length);
// ...
} catch(std::bad_alloc&) {
// ...
}
}
// GOOD: the allocation failure is handled appropiately.
void good2(std::size_t length) noexcept {
int* dest = new int[length];
if(!dest) {
return;
}
std::memset(dest, 0, length);
// ...
}

View File

@@ -0,0 +1,31 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Different overloads of the <code>new</code> operator handle allocation failures in different ways.
If <code>new T</code> fails for some type <code>T</code>, it throws a <code>std::bad_alloc</code> exception,
but <code>new(std::nothrow) T</code> returns a null pointer. If the programmer does not use the corresponding
method of error handling, allocation failure may go unhandled and could cause the program to behave in
unexpected ways.</p>
</overview>
<recommendation>
<p>Make sure that exceptions are handled appropriately if <code>new T</code> is used. On the other hand,
make sure to handle the possibility of null pointers if <code>new(std::nothrow) T</code> is used.</p>
</recommendation>
<example>
<sample src="IncorrectAllocationErrorHandling.cpp" />
</example>
<references>
<li>
CERT C++ Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/MEM52-CPP.+Detect+and+handle+memory+allocation+errors">MEM52-CPP. Detect and handle memory allocation errors</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,224 @@
/**
* @name Incorrect allocation-error handling
* @description `operator new` throws an exception on allocation failures, while `operator new(std::nothrow)` returns a null pointer. Mixing up these two failure conditions can result in unexpected behavior.
* @kind problem
* @id cpp/incorrect-allocation-error-handling
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-570
*/
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.controlflow.Guards
/**
* A C++ `delete` or `delete[]` expression.
*/
class DeleteOrDeleteArrayExpr extends Expr {
DeleteOrDeleteArrayExpr() { this instanceof DeleteExpr or this instanceof DeleteArrayExpr }
DeallocationFunction getDeallocator() {
result = [this.(DeleteExpr).getDeallocator(), this.(DeleteArrayExpr).getDeallocator()]
}
Destructor getDestructor() {
result = [this.(DeleteExpr).getDestructor(), this.(DeleteArrayExpr).getDestructor()]
}
}
/** Gets the `Constructor` invoked when `newExpr` allocates memory. */
Constructor getConstructorForAllocation(NewOrNewArrayExpr newExpr) {
result.getACallToThisFunction() = newExpr.getInitializer()
}
/** Gets the `Destructor` invoked when `deleteExpr` deallocates memory. */
Destructor getDestructorForDeallocation(DeleteOrDeleteArrayExpr deleteExpr) {
result = deleteExpr.getDestructor()
}
/** Holds if the evaluation of `newExpr` may throw an exception. */
predicate newMayThrow(NewOrNewArrayExpr newExpr) {
functionMayThrow(newExpr.getAllocator()) or
functionMayThrow(getConstructorForAllocation(newExpr))
}
/** Holds if the evaluation of `deleteExpr` may throw an exception. */
predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) {
functionMayThrow(deleteExpr.getDeallocator()) or
functionMayThrow(getDestructorForDeallocation(deleteExpr))
}
/**
* Holds if the function may throw an exception when called. That is, if the body of the function looks
* like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier.
*/
predicate functionMayThrow(Function f) {
(not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) and
not f.isNoExcept() and
not f.isNoThrow()
}
/** Holds if the evaluation of `stmt` may throw an exception. */
predicate stmtMayThrow(Stmt stmt) {
stmtMayThrow(stmt.(BlockStmt).getAStmt())
or
convertedExprMayThrow(stmt.(ExprStmt).getExpr())
or
convertedExprMayThrow(stmt.(DeclStmt).getADeclaration().(Variable).getInitializer().getExpr())
or
exists(IfStmt ifStmt | ifStmt = stmt |
convertedExprMayThrow(ifStmt.getCondition()) or
stmtMayThrow([ifStmt.getThen(), ifStmt.getElse()])
)
or
exists(ConstexprIfStmt constIfStmt | constIfStmt = stmt |
stmtMayThrow([constIfStmt.getThen(), constIfStmt.getElse()])
)
or
exists(Loop loop | loop = stmt |
convertedExprMayThrow(loop.getCondition()) or
stmtMayThrow(loop.getStmt())
)
or
// The case for `Loop` already checked the condition and the statement.
convertedExprMayThrow(stmt.(RangeBasedForStmt).getUpdate())
or
// The case for `Loop` already checked the condition and the statement.
exists(ForStmt forStmt | forStmt = stmt |
stmtMayThrow(forStmt.getInitialization())
or
convertedExprMayThrow(forStmt.getUpdate())
)
or
exists(SwitchStmt switchStmt | switchStmt = stmt |
convertedExprMayThrow(switchStmt.getExpr()) or
stmtMayThrow(switchStmt.getStmt())
)
or
// NOTE: We don't include `TryStmt` as those exceptions are not "observable" outside the function.
stmtMayThrow(stmt.(Handler).getBlock())
or
convertedExprMayThrow(stmt.(CoReturnStmt).getExpr())
or
convertedExprMayThrow(stmt.(ReturnStmt).getExpr())
}
/** Holds if the evaluation of `e` (including conversions) may throw an exception. */
predicate convertedExprMayThrow(Expr e) {
exprMayThrow(e)
or
convertedExprMayThrow(e.getConversion())
}
/** Holds if the evaluation of `e` may throw an exception. */
predicate exprMayThrow(Expr e) {
e instanceof DynamicCast
or
e instanceof TypeidOperator
or
e instanceof ThrowExpr
or
newMayThrow(e)
or
deleteMayThrow(e)
or
convertedExprMayThrow(e.(UnaryOperation).getOperand())
or
exists(BinaryOperation binOp | binOp = e |
convertedExprMayThrow([binOp.getLeftOperand(), binOp.getRightOperand()])
)
or
exists(Assignment assign | assign = e |
convertedExprMayThrow([assign.getLValue(), assign.getRValue()])
)
or
exists(CommaExpr comma | comma = e |
convertedExprMayThrow([comma.getLeftOperand(), comma.getRightOperand()])
)
or
exists(StmtExpr stmtExpr | stmtExpr = e |
convertedExprMayThrow(stmtExpr.getResultExpr()) or
stmtMayThrow(stmtExpr.getStmt())
)
or
convertedExprMayThrow(e.(Conversion).getExpr())
or
exists(FunctionCall fc | fc = e |
not exists(fc.getTarget()) or
functionMayThrow(fc.getTarget()) or
convertedExprMayThrow(fc.getAnArgument())
)
}
/** An allocator that might throw an exception. */
class ThrowingAllocator extends Function {
ThrowingAllocator() {
exists(NewOrNewArrayExpr newExpr |
newExpr.getAllocator() = this and
functionMayThrow(this)
)
}
}
/** The `std::bad_alloc` exception and its `bsl` variant. */
class BadAllocType extends Class {
BadAllocType() { this.hasGlobalOrStdOrBslName("bad_alloc") }
}
/**
* A catch block that catches a `std::bad_alloc` (or any of its superclasses), or a catch
* block that catches every exception (i.e., `catch(...)`).
*/
class BadAllocCatchBlock extends CatchBlock {
BadAllocCatchBlock() {
this.getParameter().getUnspecifiedType().stripType() =
any(BadAllocType badAlloc).getABaseClass*()
or
not exists(this.getParameter())
}
}
/**
* Holds if `newExpr` is embedded in a `try` statement with a catch block `catchBlock` that
* catches a `std::bad_alloc` exception, but nothing in the `try` block (including the `newExpr`)
* will throw that exception.
*/
predicate noThrowInTryBlock(NewOrNewArrayExpr newExpr, BadAllocCatchBlock catchBlock) {
exists(TryStmt try |
not stmtMayThrow(try.getStmt()) and
try.getACatchClause() = catchBlock and
newExpr.getEnclosingBlock().getEnclosingBlock*() = try.getStmt()
)
}
/**
* Holds if `newExpr` is handles allocation failures by throwing an exception, yet
* the guard condition `guard` compares the result of `newExpr` to a null value.
*/
predicate nullCheckInThrowingNew(NewOrNewArrayExpr newExpr, GuardCondition guard) {
newExpr.getAllocator() instanceof ThrowingAllocator and
(
// Handles null comparisons.
guard.ensuresEq(globalValueNumber(newExpr).getAnExpr(), any(NullValue null), _, _, _)
or
// Handles `if(ptr)` and `if(!ptr)` cases.
guard = globalValueNumber(newExpr).getAnExpr()
)
}
from NewOrNewArrayExpr newExpr, Element element, string msg, string elementString
where
not newExpr.isFromUninstantiatedTemplate(_) and
(
noThrowInTryBlock(newExpr, element) and
msg = "This allocation cannot throw. $@ is unnecessary." and
elementString = "This catch block"
or
nullCheckInThrowingNew(newExpr, element) and
msg = "This allocation cannot return null. $@ is unnecessary." and
elementString = "This check"
)
select newExpr, msg, element, elementString

View File

@@ -1,35 +0,0 @@
// BAD: on memory allocation error, the program terminates.
void badFunction(const int *source, std::size_t length) noexcept {
int * dest = new int[length];
std::memset(dest, 0, length);
// ..
}
// GOOD: memory allocation error will be handled.
void goodFunction(const int *source, std::size_t length) noexcept {
try {
int * dest = new int[length];
} catch(std::bad_alloc) {
// ...
}
std::memset(dest, 0, length);
// ..
}
// BAD: memory allocation error will not be handled.
void badFunction(const int *source, std::size_t length) noexcept {
try {
int * dest = new (std::nothrow) int[length];
} catch(std::bad_alloc) {
// ...
}
std::memset(dest, 0, length);
// ..
}
// GOOD: memory allocation error will be handled.
void goodFunction(const int *source, std::size_t length) noexcept {
int * dest = new (std::nothrow) int[length];
if (!dest) {
return;
}
std::memset(dest, 0, length);
// ..
}

View File

@@ -1,27 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>When using the <code>new</code> operator to allocate memory, you need to pay attention to the different ways of detecting errors. <code>::operator new(std::size_t)</code> throws an exception on error, whereas <code>::operator new(std::size_t, const std::nothrow_t &amp;)</code> returns zero on error. The programmer can get confused and check the error that occurs when allocating memory incorrectly. That can lead to an unhandled program termination or to a violation of the program logic.</p>
</overview>
<recommendation>
<p>Use the correct error detection method corresponding with the memory allocation.</p>
</recommendation>
<example>
<p>The following example demonstrates various approaches to detecting memory allocation errors using the <code>new</code> operator.</p>
<sample src="WrongInDetectingAndHandlingMemoryAllocationErrors.cpp" />
</example>
<references>
<li>
CERT C++ Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/MEM52-CPP.+Detect+and+handle+memory+allocation+errors">MEM52-CPP. Detect and handle memory allocation errors</a>.
</li>
</references>
</qhelp>

View File

@@ -1,87 +0,0 @@
/**
* @name Detect And Handle Memory Allocation Errors
* @description --::operator new(std::size_t) throws an exception on error, and ::operator new(std::size_t, const std::nothrow_t &) returns zero on error.
* --the programmer can get confused when check the error that occurs when allocating memory incorrectly.
* @kind problem
* @id cpp/detect-and-handle-memory-allocation-errors
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-570
*/
import cpp
/**
* Lookup if condition compare with 0
*/
class IfCompareWithZero extends IfStmt {
IfCompareWithZero() {
this.getCondition().(EQExpr).getAChild().getValue() = "0"
or
this.getCondition().(NEExpr).getAChild().getValue() = "0" and
this.hasElse()
or
this.getCondition().(NEExpr).getAChild().getValue() = "0" and
this.getThen().getAChild*() instanceof ReturnStmt
}
}
/**
* lookup for calls to `operator new`, with incorrect error handling.
*/
class WrongCheckErrorOperatorNew extends FunctionCall {
Expr exp;
WrongCheckErrorOperatorNew() {
this = exp.(NewOrNewArrayExpr).getAChild().(FunctionCall) and
(
this.getTarget().hasGlobalOrStdName("operator new")
or
this.getTarget().hasGlobalOrStdName("operator new[]")
)
}
/**
* Holds if handler `try ... catch` exists.
*/
predicate isExistsTryCatchBlock() {
exists(TryStmt ts | this.getEnclosingStmt() = ts.getStmt().getAChild*())
}
/**
* Holds if results call `operator new` check in `operator if`.
*/
predicate isExistsIfCondition() {
exists(IfCompareWithZero ifc, AssignExpr aex, Initializer it |
// call `operator new` directly from the condition of `operator if`.
this = ifc.getCondition().getAChild*()
or
// check results call `operator new` with variable appropriation
postDominates(ifc, this) and
aex.getAChild() = exp and
ifc.getCondition().getAChild().(VariableAccess).getTarget() =
aex.getLValue().(VariableAccess).getTarget()
or
// check results call `operator new` with declaration variable
postDominates(ifc, this) and
exp = it.getExpr() and
it.getDeclaration() = ifc.getCondition().getAChild().(VariableAccess).getTarget()
)
}
/**
* Holds if `(std::nothrow)` exists in call `operator new`.
*/
predicate isExistsNothrow() { this.getAChild().toString() = "nothrow" }
}
from WrongCheckErrorOperatorNew op
where
// use call `operator new` with `(std::nothrow)` and checking error using `try ... catch` block and not `operator if`
op.isExistsNothrow() and not op.isExistsIfCondition() and op.isExistsTryCatchBlock()
or
// use call `operator new` without `(std::nothrow)` and checking error using `operator if` and not `try ... catch` block
not op.isExistsNothrow() and not op.isExistsTryCatchBlock() and op.isExistsIfCondition()
select op, "memory allocation error check is incorrect or missing"

View File

@@ -0,0 +1,17 @@
while(flagsLoop)
{
...
if(flagsIf) break;
...
}while(flagsLoop); // BAD: when exiting through `break`, it is possible to get into an eternal loop.
...
while(flagsLoop)
{
...
if(flagsIf) break;
...
} // GOOD: correct cycle
...
if(intA+intB) return 1; // BAD: possibly no comparison
...
if(intA+intB>intC) return 1; // GOOD: correct comparison

View File

@@ -0,0 +1,28 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>In some situations, after code refactoring, parts of the old constructs may remain. They are correctly accepted by the compiler, but can critically affect program execution. For example, if you switch from `do {...} while ();` to `while () {...}` forgetting to remove the old construct completely, you get `while(){...}while();` which may be vulnerable. These code snippets look suspicious and require the developer's attention.</p>
</overview>
<recommendation>
<p>We recommend that you use more explicit code transformations.</p>
</recommendation>
<example>
<p>The following example demonstrates the erroneous and corrected sections of the code.</p>
<sample src="InsufficientControlFlowManagementAfterRefactoringTheCode.c" />
</example>
<references>
<li>
CWE Common Weakness Enumeration:
<a href="https://cwe.mitre.org/data/definitions/691.html"> CWE-691: Insufficient Control Flow Management</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,119 @@
/**
* @name Errors After Refactoring
* @description --In some situations, after code refactoring, parts of the old constructs may remain.
* --They are correctly accepted by the compiler, but can critically affect program execution.
* --For example, if you switch from `do {...} while ();` to `while () {...}` with errors, you run the risk of running out of resources.
* --These code snippets look suspicious and require the developer's attention.
* @kind problem
* @id cpp/errors-after-refactoring
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-691
*/
import cpp
import semmle.code.cpp.valuenumbering.HashCons
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* Using `while` directly after the body of another` while`.
*/
class UsingWhileAfterWhile extends WhileStmt {
/**
* Using a loop call after another loop has finished running can result in an eternal loop.
* For example, perhaps as a result of refactoring, the `do ... while ()` loop was incorrectly corrected.
* Even in the case of deliberate use of such an expression, it is better to correct it.
*/
UsingWhileAfterWhile() {
exists(WhileStmt wh1 |
wh1.getStmt().getAChild*().(BreakStmt).(ControlFlowNode).getASuccessor().getASuccessor() =
this and
hashCons(wh1.getCondition()) = hashCons(this.getCondition()) and
this.getStmt() instanceof EmptyStmt
)
or
exists(ForStmt fr1 |
fr1.getStmt().getAChild*().(BreakStmt).(ControlFlowNode).getASuccessor().getASuccessor() =
this and
hashCons(fr1.getCondition()) = hashCons(this.getCondition()) and
this.getStmt() instanceof EmptyStmt
)
}
}
/**
* Using arithmetic in a condition.
*/
class UsingArithmeticInComparison extends BinaryArithmeticOperation {
/**
* Using arithmetic operations in a comparison operation can be dangerous.
* For example, part of the comparison may have been lost as a result of refactoring.
* Even if you deliberately use such an expression, it is better to add an explicit comparison.
*/
UsingArithmeticInComparison() {
this.getParent*() instanceof IfStmt and
not this.getAChild*().isConstant() and
not this.getParent*() instanceof Call and
not this.getParent*() instanceof AssignExpr and
not this.getParent*() instanceof ArrayExpr and
not this.getParent*() instanceof RemExpr and
not this.getParent*() instanceof AssignBitwiseOperation and
not this.getParent*() instanceof AssignArithmeticOperation and
not this.getParent*() instanceof EqualityOperation and
not this.getParent*() instanceof RelationalOperation
}
/** Holds when the expression is inside the loop body. */
predicate insideTheLoop() { exists(Loop lp | lp.getStmt().getAChild*() = this.getParent*()) }
/** Holds when the expression is used in binary operations. */
predicate workingWithValue() {
this.getParent*() instanceof BinaryBitwiseOperation or
this.getParent*() instanceof NotExpr
}
/** Holds when the expression contains a pointer. */
predicate workingWithPointer() {
this.getAChild*().getFullyConverted().getType() instanceof DerivedType
}
/** Holds when a null comparison expression exists. */
predicate compareWithZero() {
exists(Expr exp |
exp instanceof ComparisonOperation and
(
globalValueNumber(exp.getAChild*()) = globalValueNumber(this) or
hashCons(exp.getAChild*()) = hashCons(this)
) and
(
exp.(ComparisonOperation).getLeftOperand().getValue() = "0" or
exp.(ComparisonOperation).getRightOperand().getValue() = "0"
)
)
}
/** Holds when a comparison expression exists. */
predicate compareWithOutZero() {
exists(Expr exp |
exp instanceof ComparisonOperation and
(
globalValueNumber(exp.getAChild*()) = globalValueNumber(this) or
hashCons(exp.getAChild*()) = hashCons(this)
)
)
}
}
from Expr exp
where
exp instanceof UsingArithmeticInComparison and
not exp.(UsingArithmeticInComparison).workingWithValue() and
not exp.(UsingArithmeticInComparison).workingWithPointer() and
not exp.(UsingArithmeticInComparison).insideTheLoop() and
not exp.(UsingArithmeticInComparison).compareWithZero() and
exp.(UsingArithmeticInComparison).compareWithOutZero()
or
exists(WhileStmt wst | wst instanceof UsingWhileAfterWhile and exp = wst.getCondition())
select exp, "this expression needs your attention"

View File

@@ -0,0 +1,4 @@
if(len>0 & memset(buf,0,len)) return 1; // BAD: `memset` will be called regardless of the value of the `len` variable. moreover, one cannot be sure that it will happen after verification
...
if(len>0 && memset(buf,0,len)) return 1; // GOOD: `memset` will be called after the `len` variable has been checked.
...

View File

@@ -0,0 +1,28 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using bitwise operations can be a mistake in some situations. For example, if parameters are evaluated in an expression and the function should be called only upon certain test results. These bitwise operations look suspicious and require developer attention.</p>
</overview>
<recommendation>
<p>We recommend that you evaluate the correctness of using the specified bit operations.</p>
</recommendation>
<example>
<p>The following example demonstrates the erroneous and fixed use of bit and logical operations.</p>
<sample src="InsufficientControlFlowManagementWhenUsingBitOperations.c" />
</example>
<references>
<li>
CWE Common Weakness Enumeration:
<a href="https://cwe.mitre.org/data/definitions/691.html"> CWE-691: Insufficient Control Flow Management</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,78 @@
/**
* @name Errors When Using Bit Operations
* @description Unlike the binary operations `||` and `&&`, there is no sequence point after evaluating an
* operand of a bitwise operation like `|` or `&`. If left-to-right evaluation is expected this may be confusing.
* @kind problem
* @id cpp/errors-when-using-bit-operations
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-691
*/
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* Dangerous uses of bit operations.
* For example: `if(intA>0 & intA<10 & charBuf&myFunc(charBuf[intA]))`.
* In this case, the function will be called in any case, and even the sequence of the call is not guaranteed.
*/
class DangerousBitOperations extends BinaryBitwiseOperation {
FunctionCall bfc;
/**
* The assignment indicates the conscious use of the bit operator.
* Use in comparison, conversion, or return value indicates conscious use of the bit operator.
* The use of shifts and bitwise operations on any element of an expression indicates a conscious use of the bitwise operator.
*/
DangerousBitOperations() {
bfc = this.getRightOperand() and
not this.getParent*() instanceof Assignment and
not this.getParent*() instanceof Initializer and
not this.getParent*() instanceof ReturnStmt and
not this.getParent*() instanceof EqualityOperation and
not this.getParent*() instanceof UnaryLogicalOperation and
not this.getParent*() instanceof BinaryLogicalOperation and
not this.getAChild*() instanceof BitwiseXorExpr and
not this.getAChild*() instanceof LShiftExpr and
not this.getAChild*() instanceof RShiftExpr
}
/** Holds when part of a bit expression is used in a logical operation. */
predicate useInLogicalOperations() {
exists(BinaryLogicalOperation blop, Expr exp |
blop.getAChild*() = exp and
exp.(FunctionCall).getTarget() = bfc.getTarget() and
not exp.getParent() instanceof ComparisonOperation and
not exp.getParent() instanceof BinaryBitwiseOperation
)
}
/** Holds when part of a bit expression is used as part of another supply. For example, as an argument to another function. */
predicate useInOtherCalls() {
bfc.hasQualifier() or
bfc.getTarget() instanceof Operator or
exists(FunctionCall fc | fc.getAnArgument().getAChild*() = this) or
bfc.getTarget() instanceof BuiltInFunction
}
/** Holds when the bit expression contains both arguments and a function call. */
predicate dangerousArgumentChecking() {
not this.getLeftOperand() instanceof Call and
globalValueNumber(this.getLeftOperand().getAChild*()) = globalValueNumber(bfc.getAnArgument())
}
/** Holds when function calls are present in the bit expression. */
predicate functionCallsInBitsExpression() {
this.getLeftOperand().getAChild*() instanceof FunctionCall
}
}
from DangerousBitOperations dbo
where
not dbo.useInOtherCalls() and
dbo.useInLogicalOperations() and
(not dbo.functionCallsInBitsExpression() or dbo.dangerousArgumentChecking())
select dbo, "This bitwise operation appears in a context where a Boolean operation is expected."

View File

@@ -0,0 +1,11 @@
if(len=funcReadData()==0) return 1; // BAD: variable `len` will not equal the value returned by function `funcReadData()`
...
if((len=funcReadData())==0) return 1; // GOOD: variable `len` equal the value returned by function `funcReadData()`
...
bool a=true;
a++;// BAD: variable `a` does not change its meaning
bool b;
b=-a;// BAD: variable `b` equal `true`
...
a=false;// GOOD: variable `a` equal `false`
b=!a;// GOOD: variable `b` equal `false`

View File

@@ -0,0 +1,28 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Finding places of confusing use of boolean type. For example, a unary minus does not work before a boolean type and an increment always gives true.</p>
</overview>
<recommendation>
<p>we recommend making the code simpler.</p>
</recommendation>
<example>
<p>The following example demonstrates erroneous and fixed methods for using a boolean data type.</p>
<sample src="OperatorPrecedenceLogicErrorWhenUseBoolType.c" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP00-C.+Use+parentheses+for+precedence+of+operation">EXP00-C. Use parentheses for precedence of operation</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,54 @@
/**
* @name Operator Precedence Logic Error When Use Bool Type
* @description --Finding places of confusing use of boolean type.
* --For example, a unary minus does not work before a boolean type and an increment always gives true.
* @kind problem
* @id cpp/operator-precedence-logic-error-when-use-bool-type
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-783
* external/cwe/cwe-480
*/
import cpp
import semmle.code.cpp.valuenumbering.HashCons
/** Holds if `exp` increments a boolean value. */
predicate incrementBoolType(IncrementOperation exp) {
exp.getOperand().getType() instanceof BoolType
}
/** Holds if `exp` applies the unary minus operator to a boolean type. */
predicate revertSignBoolType(UnaryMinusExpr exp) {
exp.getAnOperand().getType() instanceof BoolType and
exp.getFullyConverted().getType() instanceof BoolType
}
/** Holds, if this is an expression, uses comparison and assignment outside of execution precedence. */
predicate assignBoolType(Expr exp) {
exists(ComparisonOperation co |
exp.(AssignExpr).getRValue() = co and
exp.isCondition() and
not co.isParenthesised() and
not exp.(AssignExpr).getLValue().getType() instanceof BoolType and
not exists(Expr exbl |
hashCons(exbl.(AssignExpr).getLValue()) = hashCons(exp.(AssignExpr).getLValue()) and
not exbl.isCondition() and
exbl.(AssignExpr).getRValue().getType() instanceof BoolType and
exbl.(AssignExpr).getLValue().getType() = exp.(AssignExpr).getLValue().getType()
) and
co.getLeftOperand() instanceof FunctionCall and
not co.getRightOperand().getType() instanceof BoolType and
not co.getRightOperand().getValue() = "0" and
not co.getRightOperand().getValue() = "1"
)
}
from Expr exp
where
incrementBoolType(exp) or
revertSignBoolType(exp) or
assignBoolType(exp)
select exp, "this expression needs attention"

View File

@@ -3,7 +3,7 @@
* @description The expression `buffer [strlen (buffer)] = 0` is potentially dangerous, if the variable `buffer` does not have a terminal zero, then access beyond the bounds of the allocated memory is possible, which will lead to undefined behavior.
* If terminal zero is present, then the specified expression is meaningless.
* @kind problem
* @id cpp/access-memory-location-after-end-buffer
* @id cpp/access-memory-location-after-end-buffer-strlen
* @problem.severity warning
* @precision medium
* @tags correctness

View File

@@ -2,7 +2,7 @@
* @name Access Of Memory Location After The End Of A Buffer Using Strncat
* @description Calls of the form `strncat(dest, source, sizeof (dest) - strlen (dest))` set the third argument to one more than possible. So when `dest` is full, the expression `sizeof(dest) - strlen (dest)` will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the `dest` buffer.
* @kind problem
* @id cpp/access-memory-location-after-end-buffer
* @id cpp/access-memory-location-after-end-buffer-strncat
* @problem.severity warning
* @precision medium
* @tags correctness
@@ -11,54 +11,32 @@
*/
import cpp
import semmle.code.cpp.models.implementations.Strcat
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* A call to `strncat` of the form `strncat(buff, str, someExpr - strlen(buf))`, for some expression `someExpr` equal to `sizeof(buff)`.
* Holds if `call` is a call to `strncat` such that `sizeArg` and `destArg` are the size and
* destination arguments, respectively.
*/
class WrongCallStrncat extends FunctionCall {
Expr leftsomeExpr;
WrongCallStrncat() {
this.getTarget().hasGlobalOrStdName("strncat") and
// the expression of the first argument in `strncat` and `strnlen` is identical
globalValueNumber(this.getArgument(0)) =
globalValueNumber(this.getArgument(2).(SubExpr).getRightOperand().(StrlenCall).getStringExpr()) and
// using a string constant often speaks of manually calculating the length of the required buffer.
(
not this.getArgument(1) instanceof StringLiteral and
not this.getArgument(1) instanceof CharLiteral
) and
// for use in predicates
leftsomeExpr = this.getArgument(2).(SubExpr).getLeftOperand()
}
/**
* Holds if the left side of the expression `someExpr` equal to `sizeof(buf)`.
*/
predicate isExpressionEqualSizeof() {
// the left side of the expression `someExpr` is `sizeof(buf)`.
globalValueNumber(this.getArgument(0)) =
globalValueNumber(leftsomeExpr.(SizeofExprOperator).getExprOperand())
or
// value of the left side of the expression `someExpr` equal `sizeof(buf)` value, and `buf` is array.
leftsomeExpr.getValue().toInt() = this.getArgument(0).getType().getSize()
}
/**
* Holds if the left side of the expression `someExpr` equal to variable containing the length of the memory allocated for the buffer.
*/
predicate isVariableEqualValueSizegBuffer() {
// the left side of expression `someExpr` is the variable that was used in the function of allocating memory for the buffer`.
exists(AllocationExpr alc |
leftsomeExpr.(VariableAccess).getTarget() =
alc.(FunctionCall).getArgument(0).(VariableAccess).getTarget()
)
}
predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
exists(StrcatFunction strcat |
strcat = call.getTarget() and
sizeArg = call.getArgument(strcat.getParamSize()) and
destArg = call.getArgument(strcat.getParamDest())
)
}
from WrongCallStrncat sc
from FunctionCall call, Expr sizeArg, Expr destArg, SubExpr sub, int n
where
sc.isExpressionEqualSizeof() or
sc.isVariableEqualValueSizegBuffer()
select sc, "if the used buffer is full, writing out of the buffer is possible"
interestringCallWithArgs(call, sizeArg, destArg) and
// The destination buffer is an array of size n
destArg.getUnspecifiedType().(ArrayType).getSize() = n and
// The size argument is equivalent to a subtraction
globalValueNumber(sizeArg).getAnExpr() = sub and
// ... where the left side of the subtraction is the constant n
globalValueNumber(sub.getLeftOperand()).getAnExpr().getValue().toInt() = n and
// ... and the right side of the subtraction is a call to `strlen` where the argument is the
// destination buffer.
globalValueNumber(sub.getRightOperand()).getAnExpr().(StrlenCall).getStringExpr() =
globalValueNumber(destArg).getAnExpr()
select call, "Possible out-of-bounds write due to incorrect size argument."

View File

@@ -1,12 +0,0 @@
/**
* @name Defect filter
* @description Only include results in large files (200) lines of code, and change the message.
* @tags filter
*/
import cpp
import external.DefectFilter
from DefectResult res
where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200
select res, "Large files: " + res.getMessage()

View File

@@ -1,18 +0,0 @@
/**
* @name Defect from external data
* @description Insert description here...
* @kind problem
* @problem.severity warning
* @tags external-data
*/
import cpp
import external.ExternalArtifact
from ExternalData d, File u
where
d.getQueryPath() = "external-data.ql" and
u.getShortName() = d.getField(0)
select u,
d.getField(5) + ", " + d.getFieldAsDate(1) + ", " + d.getField(2) + ", " + d.getFieldAsFloat(3) +
", " + d.getFieldAsInt(4) + ": " + d.getNumFields()

View File

@@ -1,12 +0,0 @@
/**
* @name Metric filter
* @description Only include results in large files (200) lines of code.
* @tags filter
*/
import cpp
import external.MetricFilter
from MetricResult res
where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200
select res, res.getValue()

View File

@@ -1,16 +0,0 @@
/**
* @name Filter: exclude results from files that are autogenerated
* @description Use this filter to return results only if they are
* located in files that are maintained manually.
* @kind problem
* @id cpp/autogenerated-filter
* @tags filter
*/
import cpp
import semmle.code.cpp.AutogeneratedFile
import external.DefectFilter
from DefectResult res
where not res.getFile() instanceof AutogeneratedFile
select res, res.getMessage()

View File

@@ -1,16 +0,0 @@
/**
* @name Metric filter: exclude results from files that are autogenerated
* @description Use this filter to return results only if they are
* located in files that are maintained manually.
* @kind treemap
* @id cpp/autogenerated-for-metric-filter
* @tags filter
*/
import cpp
import semmle.code.cpp.AutogeneratedFile
import external.MetricFilter
from MetricResult res
where not res.getFile() instanceof AutogeneratedFile
select res, res.getValue()

View File

@@ -1,16 +0,0 @@
/**
* @name Filter: exclude results from files for which we do not have
* source code
* @description Use this filter to return results only if they are
* located in files for which we have source code.
* @kind problem
* @id cpp/from-source-filter
* @tags filter
*/
import cpp
import external.DefectFilter
from DefectResult res
where res.getFile().fromSource()
select res, res.getMessage()

View File

@@ -1,36 +0,0 @@
/**
* @name Filter: exclude results on lines covered by a macro expansion
* @description Use this filter to return results only when there is no
* macro expansion whose location spans all the lines of
* the result's location.
* @kind problem
* @id cpp/macros-filter
* @tags filter
*/
import cpp
import external.DefectFilter
predicate macroLocation(File f, int startLine, int endLine) {
exists(MacroInvocation mi, Location l |
l = mi.getLocation() and
l.getFile() = f and
l.getStartLine() = startLine and
l.getEndLine() = endLine
)
}
predicate macroCovering(DefectResult r) {
exists(File f, int macroStart, int macroEnd, int defectStart, int defectEnd |
f = r.getFile() and
defectStart = r.getStartLine() and
defectEnd = r.getEndLine() and
macroLocation(f, macroStart, macroEnd) and
macroStart <= defectStart and
macroEnd >= defectEnd
)
}
from DefectResult res
where not macroCovering(res)
select res, res.getMessage()

View File

@@ -91,16 +91,17 @@ private predicate exprReleases(Expr e, Expr released, string kind) {
// `e` is a call to a release function and `released` is the released argument
releaseExpr(e, released, kind)
or
exists(Function f, int arg |
exists(int arg, VariableAccess access, Function f |
// `e` is a call to a function that releases one of it's parameters,
// and `released` is the corresponding argument
(
e.(FunctionCall).getTarget() = f or
e.(FunctionCall).getTarget().(MemberFunction).getAnOverridingFunction+() = f
) and
access = f.getParameter(arg).getAnAccess() and
e.(FunctionCall).getArgument(arg) = released and
exprReleases(_,
exprOrDereference(globalValueNumber(f.getParameter(arg).getAnAccess()).getAnExpr()), kind)
pragma[only_bind_into](exprOrDereference(globalValueNumber(access).getAnExpr())), kind)
)
or
exists(Function f, ThisExpr innerThis |
@@ -112,7 +113,7 @@ private predicate exprReleases(Expr e, Expr released, string kind) {
) and
e.(FunctionCall).getQualifier() = exprOrDereference(released) and
innerThis.getEnclosingFunction() = f and
exprReleases(_, globalValueNumber(innerThis).getAnExpr(), kind)
exprReleases(_, pragma[only_bind_into](globalValueNumber(innerThis).getAnExpr()), kind)
)
}

View File

@@ -33,7 +33,7 @@ the break statement only exits from one level of the loop.</p>
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, published by Prentice Hall PTR (1997).
Chapter 4: Control Flow, Rule 4.6 (<a href="http://mongers.org/industrial-c++/">PDF</a>).
Chapter 4: Control Flow, Rule 4.6 (<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">PDF</a>).
</li>
<li>
<a href="http://www.cplusplus.com/doc/tutorial/control/">www.cplusplus.com Control Structures</a>

View File

@@ -39,7 +39,7 @@ loop if the loop requires more complicated variable iteration.
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, published by Prentice Hall PTR (1997).
Chapter 4: Control Flow, Rule 4.1 (<a href="http://mongers.org/industrial-c++/">PDF</a>).
Chapter 4: Control Flow, Rule 4.1 (<a href="https://web.archive.org/web/20190919025638/https://mongers.org/industrial-c++/">PDF</a>).
</li>

View File

@@ -72,6 +72,7 @@ class Location extends @location {
}
/** Holds if `this` comes on a line strictly before `l`. */
pragma[inline]
predicate isBefore(Location l) {
this.getFile() = l.getFile() and this.getEndLine() < l.getStartLine()
}

View File

@@ -101,6 +101,7 @@ class Type extends Locatable, @type {
*
* For example, starting with `const i64* const` in the context of `typedef long long i64;`, this predicate will return `long long*`.
*/
pragma[nomagic]
Type getUnspecifiedType() { unspecifiedtype(underlyingElement(this), unresolveElement(result)) }
/**

View File

@@ -14,6 +14,7 @@ import cpp
* In rare cases, the same node is used in multiple control-flow scopes. This
* confuses the dominance analysis, so this predicate is used to exclude them.
*/
pragma[noinline]
private predicate hasMultiScopeNode(Function f) {
exists(ControlFlowNode node |
node.getControlFlowScope() = f and

View File

@@ -1307,7 +1307,8 @@ private predicate conditionJumps(Expr test, boolean truth, Node n2, Pos p2) {
)
}
// Factored out for performance. See QL-796.
// Pulled out for performance. See
// https://github.com/github/codeql-coreql-team/issues/1044.
private predicate normalGroupMemberBaseCase(Node memberNode, Pos memberPos, Node atNode) {
memberNode = atNode and
memberPos.isAt() and

View File

@@ -104,9 +104,43 @@ private predicate loopConditionAlwaysUponEntry(ControlFlowNode loop, Expr condit
)
}
/**
* This relation is the same as the `el instanceof Function`, only obfuscated
* so the optimizer will not understand that any `FunctionCall.getTarget()`
* should be in this relation.
*/
pragma[noinline]
private predicate isFunction(Element el) {
el instanceof Function
or
el.(Expr).getParent() = el
}
/**
* Holds if `fc` is a `FunctionCall` with no return value for `getTarget`. This
* can happen in case of rare database inconsistencies.
*/
pragma[noopt]
private predicate callHasNoTarget(@funbindexpr fc) {
exists(Function f |
funbind(fc, f) and
not isFunction(f)
)
}
// Pulled out for performance. See
// https://github.com/github/codeql-coreql-team/issues/1044.
private predicate potentiallyReturningFunctionCall_base(FunctionCall fc) {
fc.isVirtual()
or
callHasNoTarget(fc)
}
/** A function call that *may* return; if in doubt, we assume it may. */
private predicate potentiallyReturningFunctionCall(FunctionCall fc) {
potentiallyReturningFunction(fc.getTarget()) or fc.isVirtual()
potentiallyReturningFunctionCall_base(fc)
or
potentiallyReturningFunction(fc.getTarget())
}
/** A function that *may* return; if in doubt, we assume it may. */

View File

@@ -15,6 +15,7 @@
*/
private import cpp
private import semmle.code.cpp.models.interfaces.PointerWrapper
/**
* Holds if `f` is an instantiation of the `std::move` or `std::forward`
@@ -94,6 +95,12 @@ private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) {
private predicate lvalueToReferenceStep(Expr lvalueIn, Expr referenceOut) {
lvalueIn.getConversion() = referenceOut.(ReferenceToExpr)
or
exists(PointerWrapper wrapper, Call call | call = referenceOut |
referenceOut.getUnspecifiedType() instanceof ReferenceType and
call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and
lvalueIn = call.getQualifier().getFullyConverted()
)
}
private predicate referenceToLvalueStep(Expr referenceIn, Expr lvalueOut) {
@@ -106,6 +113,13 @@ private predicate referenceToPointerStep(Expr referenceIn, Expr pointerOut) {
stdAddressOf(call.getTarget()) and
referenceIn = call.getArgument(0).getFullyConverted()
)
or
exists(CopyConstructor copy, Call call | call = pointerOut |
copy.getDeclaringType() instanceof PointerWrapper and
call.getTarget() = copy and
// The 0'th argument is the value being copied.
referenceIn = call.getArgument(0).getFullyConverted()
)
}
private predicate referenceToReferenceStep(Expr referenceIn, Expr referenceOut) {
@@ -190,6 +204,19 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
// See the `lvalueToUpdate` case for an explanation of this conjunct.
call.getType().isDeeplyConstBelow()
)
or
// Pointer wrappers behave as raw pointers for dataflow purposes.
outer = call.getAnArgument().getFullyConverted() and
exists(PointerWrapper wrapper | wrapper = outer.getType().stripTopLevelSpecifiers() |
not wrapper.pointsToConst()
)
or
outer = call.getQualifier().getFullyConverted() and
outer.getUnspecifiedType() instanceof PointerWrapper and
not (
call.getTarget().hasSpecifier("const") and
call.getType().isDeeplyConstBelow()
)
)
or
exists(PointerFieldAccess fa |
@@ -218,7 +245,9 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
not stdIdentityFunction(call.getTarget()) and
not stdAddressOf(call.getTarget()) and
exists(ReferenceType rt | rt = outer.getType().stripTopLevelSpecifiers() |
not rt.getBaseType().isConst()
not rt.getBaseType().isConst() or
rt.getBaseType().getUnspecifiedType() =
any(PointerWrapper wrapper | not wrapper.pointsToConst())
)
) and
reference = outer

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -31,26 +31,26 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
* currently excludes read-steps, store-steps, and flow-through.
*
* The analysis uses non-linear recursion: When computing a flow path in or out
* of a call, we use the results of the analysis recursively to resolve lamba
* of a call, we use the results of the analysis recursively to resolve lambda
* calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly.
*/
private module LambdaFlow {
private predicate viableParamNonLambda(DataFlowCall call, int i, ParameterNode p) {
private predicate viableParamNonLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallable(call), i)
}
private predicate viableParamLambda(DataFlowCall call, int i, ParameterNode p) {
private predicate viableParamLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), i)
}
private predicate viableParamArgNonLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) {
private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamNonLambda(call, i, p) and
arg.argumentOf(call, i)
)
}
private predicate viableParamArgLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) {
private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamLambda(call, i, p) and
arg.argumentOf(call, i)
@@ -118,8 +118,8 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
if node instanceof CastNode or node instanceof ArgumentNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeType(node))
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()
}
@@ -129,7 +129,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
lambdaCall(lambdaCall, kind, node) and
t = getNodeType(node) and
t = getNodeDataFlowType(node) and
toReturn = false and
toJump = false and
lastCall = TDataFlowCallNone()
@@ -146,7 +146,7 @@ private module LambdaFlow {
getNodeEnclosingCallable(node) = getNodeEnclosingCallable(mid)
|
preservesValue = false and
t = getNodeType(node)
t = getNodeDataFlowType(node)
or
preservesValue = true and
t = t0
@@ -160,7 +160,7 @@ private module LambdaFlow {
toJump = true and
lastCall = TDataFlowCallNone()
|
jumpStep(node, mid) and
jumpStepCached(node, mid) and
t = t0
or
exists(boolean preservesValue |
@@ -168,7 +168,7 @@ private module LambdaFlow {
getNodeEnclosingCallable(node) != getNodeEnclosingCallable(mid)
|
preservesValue = false and
t = getNodeType(node)
t = getNodeDataFlowType(node)
or
preservesValue = true and
t = t0
@@ -176,7 +176,7 @@ private module LambdaFlow {
)
or
// flow into a callable
exists(ParameterNode p, DataFlowCallOption lastCall0, DataFlowCall call |
exists(ParamNode p, DataFlowCallOption lastCall0, DataFlowCall call |
revLambdaFlowIn(lambdaCall, kind, p, t, toJump, lastCall0) and
(
if lastCall0 = TDataFlowCallNone() and toJump = false
@@ -227,7 +227,7 @@ private module LambdaFlow {
pragma[nomagic]
predicate revLambdaFlowIn(
DataFlowCall lambdaCall, LambdaCallKind kind, ParameterNode p, DataFlowType t, boolean toJump,
DataFlowCall lambdaCall, LambdaCallKind kind, ParamNode p, DataFlowType t, boolean toJump,
DataFlowCallOption lastCall
) {
revLambdaFlow(lambdaCall, kind, p, t, false, toJump, lastCall)
@@ -242,6 +242,89 @@ private DataFlowCallable viableCallableExt(DataFlowCall call) {
cached
private module Cached {
/**
* If needed, call this predicate from `DataFlowImplSpecific.qll` in order to
* force a stage-dependency on the `DataFlowImplCommon.qll` stage and therby
* collapsing the two stages.
*/
cached
predicate forceCachingInSameStage() { any() }
cached
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = n.getEnclosingCallable() }
cached
predicate callEnclosingCallable(DataFlowCall call, DataFlowCallable c) {
c = call.getEnclosingCallable()
}
cached
predicate nodeDataFlowType(Node n, DataFlowType t) { t = getNodeType(n) }
cached
predicate jumpStepCached(Node node1, Node node2) { jumpStep(node1, node2) }
cached
predicate clearsContentCached(Node n, Content c) { clearsContent(n, c) }
cached
predicate isUnreachableInCallCached(Node n, DataFlowCall call) { isUnreachableInCall(n, call) }
cached
predicate outNodeExt(Node n) {
n instanceof OutNode
or
n.(PostUpdateNode).getPreUpdateNode() instanceof ArgNode
}
cached
predicate hiddenNode(Node n) { nodeIsHidden(n) }
cached
OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) {
result = getAnOutNode(call, k.(ValueReturnKind).getKind())
or
exists(ArgNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, k.(ParamUpdateReturnKind).getPosition())
)
}
cached
predicate returnNodeExt(Node n, ReturnKindExt k) {
k = TValueReturn(n.(ReturnNode).getKind())
or
exists(ParamNode p, int pos |
parameterValueFlowsToPreUpdate(p, n) and
p.isParameterOf(_, pos) and
k = TParamUpdate(pos)
)
}
cached
predicate castNode(Node n) { n instanceof CastNode }
cached
predicate castingNode(Node n) {
castNode(n) or
n instanceof ParamNode or
n instanceof OutNodeExt or
// For reads, `x.f`, we want to check that the tracked type after the read (which
// is obtained by popping the head of the access path stack) is compatible with
// the type of `x.f`.
read(_, _, n)
}
cached
predicate parameterNode(Node n, DataFlowCallable c, int i) {
n.(ParameterNode).isParameterOf(c, i)
}
cached
predicate argumentNode(Node n, DataFlowCall call, int pos) {
n.(ArgumentNode).argumentOf(call, pos)
}
/**
* Gets a viable target for the lambda call `call`.
*
@@ -261,7 +344,7 @@ private module Cached {
* The instance parameter is considered to have index `-1`.
*/
pragma[nomagic]
private predicate viableParam(DataFlowCall call, int i, ParameterNode p) {
private predicate viableParam(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableExt(call), i)
}
@@ -270,11 +353,11 @@ private module Cached {
* dispatch into account.
*/
cached
predicate viableParamArg(DataFlowCall call, ParameterNode p, ArgumentNode arg) {
predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParam(call, i, p) and
arg.argumentOf(call, i) and
compatibleTypes(getNodeType(arg), getNodeType(p))
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p))
)
}
@@ -312,7 +395,7 @@ private module Cached {
* `read` indicates whether it is contents of `p` that can flow to `node`.
*/
pragma[nomagic]
private predicate parameterValueFlowCand(ParameterNode p, Node node, boolean read) {
private predicate parameterValueFlowCand(ParamNode p, Node node, boolean read) {
p = node and
read = false
or
@@ -325,30 +408,30 @@ private module Cached {
// read
exists(Node mid |
parameterValueFlowCand(p, mid, false) and
readStep(mid, _, node) and
read(mid, _, node) and
read = true
)
or
// flow through: no prior read
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArgCand(p, arg, false) and
argumentValueFlowsThroughCand(arg, node, read)
)
or
// flow through: no read inside method
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArgCand(p, arg, read) and
argumentValueFlowsThroughCand(arg, node, false)
)
}
pragma[nomagic]
private predicate parameterValueFlowArgCand(ParameterNode p, ArgumentNode arg, boolean read) {
private predicate parameterValueFlowArgCand(ParamNode p, ArgNode arg, boolean read) {
parameterValueFlowCand(p, arg, read)
}
pragma[nomagic]
predicate parameterValueFlowsToPreUpdateCand(ParameterNode p, PostUpdateNode n) {
predicate parameterValueFlowsToPreUpdateCand(ParamNode p, PostUpdateNode n) {
parameterValueFlowCand(p, n.getPreUpdateNode(), false)
}
@@ -360,7 +443,7 @@ private module Cached {
* `read` indicates whether it is contents of `p` that can flow to the return
* node.
*/
predicate parameterValueFlowReturnCand(ParameterNode p, ReturnKind kind, boolean read) {
predicate parameterValueFlowReturnCand(ParamNode p, ReturnKind kind, boolean read) {
exists(ReturnNode ret |
parameterValueFlowCand(p, ret, read) and
kind = ret.getKind()
@@ -369,9 +452,9 @@ private module Cached {
pragma[nomagic]
private predicate argumentValueFlowsThroughCand0(
DataFlowCall call, ArgumentNode arg, ReturnKind kind, boolean read
DataFlowCall call, ArgNode arg, ReturnKind kind, boolean read
) {
exists(ParameterNode param | viableParamArg(call, param, arg) |
exists(ParamNode param | viableParamArg(call, param, arg) |
parameterValueFlowReturnCand(param, kind, read)
)
}
@@ -382,14 +465,14 @@ private module Cached {
*
* `read` indicates whether it is contents of `arg` that can flow to `out`.
*/
predicate argumentValueFlowsThroughCand(ArgumentNode arg, Node out, boolean read) {
predicate argumentValueFlowsThroughCand(ArgNode arg, Node out, boolean read) {
exists(DataFlowCall call, ReturnKind kind |
argumentValueFlowsThroughCand0(call, arg, kind, read) and
out = getAnOutNode(call, kind)
)
}
predicate cand(ParameterNode p, Node n) {
predicate cand(ParamNode p, Node n) {
parameterValueFlowCand(p, n, _) and
(
parameterValueFlowReturnCand(p, _, _)
@@ -416,21 +499,21 @@ private module Cached {
* If a read step was taken, then `read` captures the `Content`, the
* container type, and the content type.
*/
predicate parameterValueFlow(ParameterNode p, Node node, ReadStepTypesOption read) {
predicate parameterValueFlow(ParamNode p, Node node, ReadStepTypesOption read) {
parameterValueFlow0(p, node, read) and
if node instanceof CastingNode
then
// normal flow through
read = TReadStepTypesNone() and
compatibleTypes(getNodeType(p), getNodeType(node))
compatibleTypes(getNodeDataFlowType(p), getNodeDataFlowType(node))
or
// getter
compatibleTypes(read.getContentType(), getNodeType(node))
compatibleTypes(read.getContentType(), getNodeDataFlowType(node))
else any()
}
pragma[nomagic]
private predicate parameterValueFlow0(ParameterNode p, Node node, ReadStepTypesOption read) {
private predicate parameterValueFlow0(ParamNode p, Node node, ReadStepTypesOption read) {
p = node and
Cand::cand(p, _) and
read = TReadStepTypesNone()
@@ -447,7 +530,7 @@ private module Cached {
readStepWithTypes(mid, read.getContainerType(), read.getContent(), node,
read.getContentType()) and
Cand::parameterValueFlowReturnCand(p, _, true) and
compatibleTypes(getNodeType(p), read.getContainerType())
compatibleTypes(getNodeDataFlowType(p), read.getContainerType())
)
or
parameterValueFlow0_0(TReadStepTypesNone(), p, node, read)
@@ -455,34 +538,32 @@ private module Cached {
pragma[nomagic]
private predicate parameterValueFlow0_0(
ReadStepTypesOption mustBeNone, ParameterNode p, Node node, ReadStepTypesOption read
ReadStepTypesOption mustBeNone, ParamNode p, Node node, ReadStepTypesOption read
) {
// flow through: no prior read
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArg(p, arg, mustBeNone) and
argumentValueFlowsThrough(arg, read, node)
)
or
// flow through: no read inside method
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArg(p, arg, read) and
argumentValueFlowsThrough(arg, mustBeNone, node)
)
}
pragma[nomagic]
private predicate parameterValueFlowArg(
ParameterNode p, ArgumentNode arg, ReadStepTypesOption read
) {
private predicate parameterValueFlowArg(ParamNode p, ArgNode arg, ReadStepTypesOption read) {
parameterValueFlow(p, arg, read) and
Cand::argumentValueFlowsThroughCand(arg, _, _)
}
pragma[nomagic]
private predicate argumentValueFlowsThrough0(
DataFlowCall call, ArgumentNode arg, ReturnKind kind, ReadStepTypesOption read
DataFlowCall call, ArgNode arg, ReturnKind kind, ReadStepTypesOption read
) {
exists(ParameterNode param | viableParamArg(call, param, arg) |
exists(ParamNode param | viableParamArg(call, param, arg) |
parameterValueFlowReturn(param, kind, read)
)
}
@@ -496,18 +577,18 @@ private module Cached {
* container type, and the content type.
*/
pragma[nomagic]
predicate argumentValueFlowsThrough(ArgumentNode arg, ReadStepTypesOption read, Node out) {
predicate argumentValueFlowsThrough(ArgNode arg, ReadStepTypesOption read, Node out) {
exists(DataFlowCall call, ReturnKind kind |
argumentValueFlowsThrough0(call, arg, kind, read) and
out = getAnOutNode(call, kind)
|
// normal flow through
read = TReadStepTypesNone() and
compatibleTypes(getNodeType(arg), getNodeType(out))
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(out))
or
// getter
compatibleTypes(getNodeType(arg), read.getContainerType()) and
compatibleTypes(read.getContentType(), getNodeType(out))
compatibleTypes(getNodeDataFlowType(arg), read.getContainerType()) and
compatibleTypes(read.getContentType(), getNodeDataFlowType(out))
)
}
@@ -516,7 +597,7 @@ private module Cached {
* value-preserving steps and a single read step, not taking call
* contexts into account, thus representing a getter-step.
*/
predicate getterStep(ArgumentNode arg, Content c, Node out) {
predicate getterStep(ArgNode arg, Content c, Node out) {
argumentValueFlowsThrough(arg, TReadStepTypesSome(_, c, _), out)
}
@@ -529,7 +610,7 @@ private module Cached {
* container type, and the content type.
*/
private predicate parameterValueFlowReturn(
ParameterNode p, ReturnKind kind, ReadStepTypesOption read
ParamNode p, ReturnKind kind, ReadStepTypesOption read
) {
exists(ReturnNode ret |
parameterValueFlow(p, ret, read) and
@@ -553,7 +634,7 @@ private module Cached {
private predicate mayBenefitFromCallContextExt(DataFlowCall call, DataFlowCallable callable) {
mayBenefitFromCallContext(call, callable)
or
callable = call.getEnclosingCallable() and
callEnclosingCallable(call, callable) and
exists(viableCallableLambda(call, TDataFlowCallSome(_)))
}
@@ -611,7 +692,7 @@ private module Cached {
mayBenefitFromCallContextExt(call, _) and
c = viableCallableExt(call) and
ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContextExt(call, ctx)) and
tgts = strictcount(DataFlowCall ctx | viableCallableExt(ctx) = call.getEnclosingCallable()) and
tgts = strictcount(DataFlowCall ctx | callEnclosingCallable(call, viableCallableExt(ctx))) and
ctxtgts < tgts
)
}
@@ -635,8 +716,7 @@ private module Cached {
* Holds if `p` can flow to the pre-update node associated with post-update
* node `n`, in the same callable, using only value-preserving steps.
*/
cached
predicate parameterValueFlowsToPreUpdate(ParameterNode p, PostUpdateNode n) {
private predicate parameterValueFlowsToPreUpdate(ParamNode p, PostUpdateNode n) {
parameterValueFlow(p, n.getPreUpdateNode(), TReadStepTypesNone())
}
@@ -644,9 +724,9 @@ private module Cached {
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
) {
storeStep(node1, c, node2) and
readStep(_, c, _) and
contentType = getNodeType(node1) and
containerType = getNodeType(node2)
read(_, c, _) and
contentType = getNodeDataFlowType(node1) and
containerType = getNodeDataFlowType(node2)
or
exists(Node n1, Node n2 |
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
@@ -654,12 +734,15 @@ private module Cached {
|
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1)
or
readStep(n2, c, n1) and
contentType = getNodeType(n1) and
containerType = getNodeType(n2)
read(n2, c, n1) and
contentType = getNodeDataFlowType(n1) and
containerType = getNodeDataFlowType(n2)
)
}
cached
predicate read(Node node1, Content c, Node node2) { readStep(node1, c, node2) }
/**
* Holds if data can flow from `node1` to `node2` via a direct assignment to
* `f`.
@@ -678,8 +761,9 @@ private module Cached {
* are aliases. A typical example is a function returning `this`, implementing a fluent
* interface.
*/
cached
predicate reverseStepThroughInputOutputAlias(PostUpdateNode fromNode, PostUpdateNode toNode) {
private predicate reverseStepThroughInputOutputAlias(
PostUpdateNode fromNode, PostUpdateNode toNode
) {
exists(Node fromPre, Node toPre |
fromPre = fromNode.getPreUpdateNode() and
toPre = toNode.getPreUpdateNode()
@@ -688,14 +772,20 @@ private module Cached {
// Does the language-specific simpleLocalFlowStep already model flow
// from function input to output?
fromPre = getAnOutNode(c, _) and
toPre.(ArgumentNode).argumentOf(c, _) and
simpleLocalFlowStep(toPre.(ArgumentNode), fromPre)
toPre.(ArgNode).argumentOf(c, _) and
simpleLocalFlowStep(toPre.(ArgNode), fromPre)
)
or
argumentValueFlowsThrough(toPre, TReadStepTypesNone(), fromPre)
)
}
cached
predicate simpleLocalFlowStepExt(Node node1, Node node2) {
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
}
/**
* Holds if the call context `call` either improves virtual dispatch in
* `callable` or if it allows us to prune unreachable nodes in `callable`.
@@ -704,7 +794,7 @@ private module Cached {
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
reducedViableImplInCallContext(_, callable, call)
or
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCall(n, call))
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
cached
@@ -726,12 +816,12 @@ private module Cached {
cached
newtype TLocalFlowCallContext =
TAnyLocalCall() or
TSpecificLocalCall(DataFlowCall call) { isUnreachableInCall(_, call) }
TSpecificLocalCall(DataFlowCall call) { isUnreachableInCallCached(_, call) }
cached
newtype TReturnKindExt =
TValueReturn(ReturnKind kind) or
TParamUpdate(int pos) { exists(ParameterNode p | p.isParameterOf(_, pos)) }
TParamUpdate(int pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
cached
newtype TBooleanOption =
@@ -761,23 +851,15 @@ private module Cached {
* A `Node` at which a cast can occur such that the type should be checked.
*/
class CastingNode extends Node {
CastingNode() {
this instanceof ParameterNode or
this instanceof CastNode or
this instanceof OutNodeExt or
// For reads, `x.f`, we want to check that the tracked type after the read (which
// is obtained by popping the head of the access path stack) is compatible with
// the type of `x.f`.
readStep(_, _, this)
}
CastingNode() { castingNode(this) }
}
private predicate readStepWithTypes(
Node n1, DataFlowType container, Content c, Node n2, DataFlowType content
) {
readStep(n1, c, n2) and
container = getNodeType(n1) and
content = getNodeType(n2)
read(n1, c, n2) and
container = getNodeDataFlowType(n1) and
content = getNodeDataFlowType(n2)
}
private newtype TReadStepTypesOption =
@@ -854,7 +936,7 @@ class CallContextSomeCall extends CallContextCall, TSomeCall {
override string toString() { result = "CcSomeCall" }
override predicate relevantFor(DataFlowCallable callable) {
exists(ParameterNode p | getNodeEnclosingCallable(p) = callable)
exists(ParamNode p | getNodeEnclosingCallable(p) = callable)
}
override predicate matchesCall(DataFlowCall call) { any() }
@@ -866,7 +948,7 @@ class CallContextReturn extends CallContextNoCall, TReturn {
}
override predicate relevantFor(DataFlowCallable callable) {
exists(DataFlowCall call | this = TReturn(_, call) and call.getEnclosingCallable() = callable)
exists(DataFlowCall call | this = TReturn(_, call) and callEnclosingCallable(call, callable))
}
}
@@ -899,7 +981,7 @@ class LocalCallContextSpecificCall extends LocalCallContext, TSpecificLocalCall
}
private predicate relevantLocalCCtx(DataFlowCall call, DataFlowCallable callable) {
exists(Node n | getNodeEnclosingCallable(n) = callable and isUnreachableInCall(n, call))
exists(Node n | getNodeEnclosingCallable(n) = callable and isUnreachableInCallCached(n, call))
}
/**
@@ -913,26 +995,37 @@ LocalCallContext getLocalCallContext(CallContext ctx, DataFlowCallable callable)
else result instanceof LocalCallContextAny
}
/**
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
class ParamNode extends Node {
ParamNode() { parameterNode(this, _, _) }
/**
* Holds if this node is the parameter of callable `c` at the specified
* (zero-based) position.
*/
predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) }
}
/** A data-flow node that represents a call argument. */
class ArgNode extends Node {
ArgNode() { argumentNode(this, _, _) }
/** Holds if this argument occurs at the given position in the given call. */
final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) }
}
/**
* A node from which flow can return to the caller. This is either a regular
* `ReturnNode` or a `PostUpdateNode` corresponding to the value of a parameter.
*/
class ReturnNodeExt extends Node {
ReturnNodeExt() {
this instanceof ReturnNode or
parameterValueFlowsToPreUpdate(_, this)
}
ReturnNodeExt() { returnNodeExt(this, _) }
/** Gets the kind of this returned value. */
ReturnKindExt getKind() {
result = TValueReturn(this.(ReturnNode).getKind())
or
exists(ParameterNode p, int pos |
parameterValueFlowsToPreUpdate(p, this) and
p.isParameterOf(_, pos) and
result = TParamUpdate(pos)
)
}
ReturnKindExt getKind() { returnNodeExt(this, result) }
}
/**
@@ -940,11 +1033,7 @@ class ReturnNodeExt extends Node {
* or a post-update node associated with a call argument.
*/
class OutNodeExt extends Node {
OutNodeExt() {
this instanceof OutNode
or
this.(PostUpdateNode).getPreUpdateNode() instanceof ArgumentNode
}
OutNodeExt() { outNodeExt(this) }
}
/**
@@ -957,7 +1046,7 @@ abstract class ReturnKindExt extends TReturnKindExt {
abstract string toString();
/** Gets a node corresponding to data flow out of `call`. */
abstract OutNodeExt getAnOutNode(DataFlowCall call);
final OutNodeExt getAnOutNode(DataFlowCall call) { result = getAnOutNodeExt(call, this) }
}
class ValueReturnKind extends ReturnKindExt, TValueReturn {
@@ -968,10 +1057,6 @@ class ValueReturnKind extends ReturnKindExt, TValueReturn {
ReturnKind getKind() { result = kind }
override string toString() { result = kind.toString() }
override OutNodeExt getAnOutNode(DataFlowCall call) {
result = getAnOutNode(call, this.getKind())
}
}
class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate {
@@ -982,13 +1067,6 @@ class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate {
int getPosition() { result = pos }
override string toString() { result = "param update " + pos }
override OutNodeExt getAnOutNode(DataFlowCall call) {
exists(ArgumentNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, this.getPosition())
)
}
}
/** A callable tagged with a relevant return kind. */
@@ -1015,10 +1093,13 @@ class ReturnPosition extends TReturnPosition0 {
*/
pragma[inline]
DataFlowCallable getNodeEnclosingCallable(Node n) {
exists(Node n0 |
pragma[only_bind_into](n0) = n and
pragma[only_bind_into](result) = n0.getEnclosingCallable()
)
nodeEnclosingCallable(pragma[only_bind_out](n), pragma[only_bind_into](result))
}
/** Gets the type of `n` used for type pruning. */
pragma[inline]
DataFlowType getNodeDataFlowType(Node n) {
nodeDataFlowType(pragma[only_bind_out](n), pragma[only_bind_into](result))
}
pragma[noinline]
@@ -1042,7 +1123,7 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
cc instanceof CallContextAny and callable = viableCallableExt(call)
or
exists(DataFlowCallable c0, DataFlowCall call0 |
call0.getEnclosingCallable() = callable and
callEnclosingCallable(call0, callable) and
cc = TReturn(c0, call0) and
c0 = prunedViableImplInCallContextReverse(call0, call)
)
@@ -1063,8 +1144,6 @@ DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
result = viableCallableExt(call) and cc instanceof CallContextReturn
}
predicate read = readStep/3;
/** An optional Boolean value. */
class BooleanOption extends TBooleanOption {
string toString() {
@@ -1116,7 +1195,7 @@ abstract class AccessPathFront extends TAccessPathFront {
TypedContent getHead() { this = TFrontHead(result) }
predicate isClearedAt(Node n) { clearsContent(n, getHead().getContent()) }
predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -321,5 +321,5 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() }
/** Extra data-flow steps needed for lamba flow analysis. */
/** Extra data-flow steps needed for lambda flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }

View File

@@ -46,7 +46,7 @@ class Node extends TNode {
/**
* INTERNAL: Do not use. Alternative name for `getFunction`.
*/
final Function getEnclosingCallable() { result = unique(Function f | f = this.getFunction() | f) }
final Function getEnclosingCallable() { result = this.getFunction() }
/** Gets the type of this node. */
Type getType() { none() } // overridden in subclasses
@@ -324,7 +324,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode {
* A synthetic data flow node used for flow into a collection when an iterator
* write occurs in a callee.
*/
class IteratorPartialDefinitionNode extends PartialDefinitionNode {
private class IteratorPartialDefinitionNode extends PartialDefinitionNode {
override IteratorPartialDefinition pd;
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
@@ -526,7 +526,6 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) {
* This is the local flow predicate that's used as a building block in global
* data flow. It may have less flow than the `localFlowStep` predicate.
*/
cached
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
// Expr -> Expr
exprToExprStep_nocfg(nodeFrom.asExpr(), nodeTo.asExpr())
@@ -694,7 +693,12 @@ private predicate exprToExprStep_nocfg(Expr fromExpr, Expr toExpr) {
fromExpr = call.getQualifier()
) and
call.getTarget() = f and
outModel.isReturnValue()
// AST dataflow treats a reference as if it were the referred-to object, while the dataflow
// models treat references as pointers. If the return type of the call is a reference, then
// look for data flow the the referred-to object, rather than the reference itself.
if call.getType().getUnspecifiedType() instanceof ReferenceType
then outModel.isReturnValueDeref()
else outModel.isReturnValue()
)
)
}
@@ -715,6 +719,7 @@ private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
}
private module FieldFlow {
private import DataFlowImplCommon
private import DataFlowImplLocal
private import DataFlowPrivate
@@ -747,7 +752,7 @@ private module FieldFlow {
exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and
// This configuration should not be able to cross function boundaries, but
// we double-check here just to be sure.
node1.getEnclosingCallable() = node2.getEnclosingCallable()
getNodeEnclosingCallable(node1) = getNodeEnclosingCallable(node2)
}
}

View File

@@ -7,6 +7,7 @@ private import semmle.code.cpp.controlflow.SSA
private import semmle.code.cpp.dataflow.internal.SubBasicBlocks
private import semmle.code.cpp.dataflow.internal.AddressFlow
private import semmle.code.cpp.models.implementations.Iterator
private import semmle.code.cpp.models.interfaces.PointerWrapper
/**
* A conceptual variable that is assigned only once, like an SSA variable. This
@@ -158,18 +159,14 @@ private module PartialDefinitions {
Expr innerDefinedExpr;
IteratorPartialDefinition() {
exists(Expr convertedInner |
not this instanceof Conversion and
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted() and
(
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
or
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
collection instanceof IteratorParameter
) and
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
)
innerDefinedExpr = getInnerDefinedExpr(this, node) and
(
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
or
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
collection instanceof IteratorParameter
) and
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
or
// iterators passed by value without a copy constructor
exists(Call call |
@@ -207,16 +204,18 @@ private module PartialDefinitions {
}
}
private Expr getInnerDefinedExpr(Expr e, ControlFlowNode node) {
not e instanceof Conversion and
exists(Expr convertedInner |
valueToUpdate(convertedInner, e.getFullyConverted(), node) and
result = convertedInner.getUnconverted()
)
}
class VariablePartialDefinition extends PartialDefinition {
Expr innerDefinedExpr;
VariablePartialDefinition() {
not this instanceof Conversion and
exists(Expr convertedInner |
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted()
)
}
VariablePartialDefinition() { innerDefinedExpr = getInnerDefinedExpr(this, node) }
deprecated override predicate partiallyDefines(Variable v) {
innerDefinedExpr = v.getAnAccess()
@@ -296,7 +295,8 @@ module FlowVar_internal {
// treating them as immutable, but for data flow it gives better results in
// practice to make the variable synonymous with its contents.
not v.getUnspecifiedType() instanceof ReferenceType and
not v instanceof IteratorParameter
not v instanceof IteratorParameter and
not v instanceof PointerWrapperParameter
}
/**
@@ -644,10 +644,19 @@ module FlowVar_internal {
predicate parameterIsNonConstReference(Parameter p) {
exists(ReferenceType refType |
refType = p.getUnderlyingType() and
not refType.getBaseType().isConst()
(
not refType.getBaseType().isConst()
or
// A field of a parameter of type `const std::shared_ptr<A>& p` can still be changed even though
// the base type of the reference is `const`.
refType.getBaseType().getUnspecifiedType() =
any(PointerWrapper wrapper | not wrapper.pointsToConst())
)
)
or
p instanceof IteratorParameter
or
p instanceof PointerWrapperParameter
}
/**
@@ -836,6 +845,10 @@ module FlowVar_internal {
IteratorParameter() { this.getUnspecifiedType() instanceof Iterator }
}
class PointerWrapperParameter extends Parameter {
PointerWrapperParameter() { this.getUnspecifiedType() instanceof PointerWrapper }
}
/**
* Holds if `v` is initialized to have value `assignedExpr`.
*/

View File

@@ -11,6 +11,7 @@
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
private import semmle.code.cpp.models.interfaces.Iterator
private import semmle.code.cpp.models.interfaces.PointerWrapper
private module DataFlow {
import semmle.code.cpp.dataflow.internal.DataFlowUtil
@@ -44,6 +45,7 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
* different objects.
*/
cached
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
// Taint can flow through expressions that alter the value but preserve
// more than one bit of it _or_ expressions that follow data through
@@ -141,7 +143,10 @@ private predicate noFlowFromChildExpr(Expr e) {
or
e instanceof LogicalOrExpr
or
e instanceof Call
// Allow taint from `operator*` on smart pointers.
exists(Call call | e = call |
not call.getTarget() = any(PointerWrapper wrapper).getAnUnwrapperFunction()
)
or
e instanceof SizeofOperator
or

View File

@@ -300,17 +300,25 @@ class FunctionCall extends Call, @funbindexpr {
}
}
/** A _user-defined_ unary `operator*` function. */
class OverloadedPointerDereferenceFunction extends Function {
OverloadedPointerDereferenceFunction() {
this.hasName("operator*") and
this.getEffectiveNumberOfParameters() = 1
}
}
/**
* An instance of a _user-defined_ unary `operator*` applied to its argument.
* ```
* T1 operator*(const T2 &);
* T1 a; T2 b;
* a = *b;
* ```
*/
class OverloadedPointerDereferenceExpr extends FunctionCall {
OverloadedPointerDereferenceExpr() {
getTarget().hasName("operator*") and
getTarget().getEffectiveNumberOfParameters() = 1
this.getTarget() instanceof OverloadedPointerDereferenceFunction
}
override string getAPrimaryQlClass() { result = "OverloadedPointerDereferenceExpr" }

View File

@@ -850,6 +850,24 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
this.getAllocatorCall()
.getArgument(this.getAllocator().(OperatorNewAllocationFunction).getPlacementArgument())
}
/**
* For `operator new`, this gets the call or expression that initializes the allocated object, if any.
*
* As examples, for `new int(4)`, this will be `4`, and for `new std::vector(4)`, this will
* be a call to the constructor `std::vector::vector(size_t)` with `4` as an argument.
*
* For `operator new[]`, this gets the call or expression that initializes the first element of the
* array, if any.
*
* This will either be a call to the default constructor for the array's element type (as
* in `new std::string[10]`), or a literal zero for arrays of scalars which are zero-initialized
* due to extra parentheses (as in `new int[10]()`).
*
* At runtime, the constructor will be called once for each element in the array, but the
* constructor call only exists once in the AST.
*/
final Expr getInitializer() { result = this.getChild(1) }
}
/**
@@ -871,14 +889,6 @@ class NewExpr extends NewOrNewArrayExpr, @new_expr {
override Type getAllocatedType() {
new_allocated_type(underlyingElement(this), unresolveElement(result))
}
/**
* Gets the call or expression that initializes the allocated object, if any.
*
* As examples, for `new int(4)`, this will be `4`, and for `new std::vector(4)`, this will
* be a call to the constructor `std::vector::vector(size_t)` with `4` as an argument.
*/
Expr getInitializer() { result = this.getChild(1) }
}
/**
@@ -909,18 +919,6 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
result = getType().getUnderlyingType().(PointerType).getBaseType()
}
/**
* Gets the call or expression that initializes the first element of the array, if any.
*
* This will either be a call to the default constructor for the array's element type (as
* in `new std::string[10]`), or a literal zero for arrays of scalars which are zero-initialized
* due to extra parentheses (as in `new int[10]()`).
*
* At runtime, the constructor will be called once for each element in the array, but the
* constructor call only exists once in the AST.
*/
Expr getInitializer() { result = this.getChild(1) }
/**
* Gets the extent of the non-constant array dimension, if any.
*
@@ -1271,7 +1269,8 @@ private predicate convparents(Expr child, int idx, Element parent) {
)
}
// Pulled out for performance. See QL-796.
// Pulled out for performance. See
// https://github.com/github/codeql-coreql-team/issues/1044.
private predicate hasNoConversions(Expr e) { not e.hasConversion() }
/**

View File

@@ -2,13 +2,16 @@ import cpp
import semmle.code.cpp.security.Security
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.DataFlow2
private import semmle.code.cpp.ir.dataflow.DataFlow3
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.models.interfaces.Taint
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.ir.dataflow.TaintTracking
private import semmle.code.cpp.ir.dataflow.TaintTracking2
private import semmle.code.cpp.ir.dataflow.TaintTracking3
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
/**
* A predictable instruction is one where an external user can predict
@@ -65,23 +68,19 @@ private DataFlow::Node getNodeForExpr(Expr node) {
not argv(node.(VariableAccess).getTarget())
}
private class DefaultTaintTrackingCfg extends DataFlow::Configuration {
private class DefaultTaintTrackingCfg extends TaintTracking::Configuration {
DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) }
override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) }
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
}
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
private class ToGlobalVarTaintTrackingCfg extends DataFlow::Configuration {
private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration {
ToGlobalVarTaintTrackingCfg() { this = "GlobalVarTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) }
@@ -90,20 +89,18 @@ private class ToGlobalVarTaintTrackingCfg extends DataFlow::Configuration {
sink.asVariable() instanceof GlobalOrNamespaceVariable
}
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
or
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))
or
readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable))
}
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
private class FromGlobalVarTaintTrackingCfg extends DataFlow2::Configuration {
private class FromGlobalVarTaintTrackingCfg extends TaintTracking2::Configuration {
FromGlobalVarTaintTrackingCfg() { this = "FromGlobalVarTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) {
@@ -114,18 +111,16 @@ private class FromGlobalVarTaintTrackingCfg extends DataFlow2::Configuration {
override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) }
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
or
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
// Additional step for flow out of variables. There is no flow _into_
// variables in this configuration, so this step only serves to take flow
// out of a variable that's a source.
readsVariable(n2.asInstruction(), n1.asVariable())
}
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
private predicate readsVariable(LoadInstruction load, Variable var) {
@@ -170,277 +165,132 @@ private predicate nodeIsBarrierEqualityCandidate(
any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true)
}
private predicate nodeIsBarrier(DataFlow::Node node) {
exists(Variable checkedVar |
readsVariable(node.asInstruction(), checkedVar) and
hasUpperBoundsCheck(checkedVar)
)
or
exists(Variable checkedVar, Operand access |
/*
* This node is guarded by a condition that forces the accessed variable
* to equal something else. For example:
* ```
* x = taintsource()
* if (x == 10) {
* taintsink(x); // not considered tainted
* }
* ```
*/
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
readsVariable(access.getDef(), checkedVar)
)
}
private predicate nodeIsBarrierIn(DataFlow::Node node) {
// don't use dataflow into taint sources, as this leads to duplicate results.
exists(Expr source | isUserInput(source, _) |
node = DataFlow::exprNode(source)
or
// This case goes together with the similar (but not identical) rule in
// `getNodeForSource`.
node = DataFlow::definitionByReferenceNodeFromArgument(source)
)
}
cached
private predicate commonTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
operandToInstructionTaintStep(fromNode.asOperand(), toNode.asInstruction())
or
instructionToOperandTaintStep(fromNode.asInstruction(), toNode.asOperand())
}
private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand toOperand) {
// Propagate flow from the definition of an operand to the operand, even when the overlap is inexact.
// We only do this in certain cases:
// 1. The instruction's result must not be conflated, and
// 2. The instruction's result type is one the types where we expect element-to-object flow. Currently
// this is array types and union types. This matches the other two cases of element-to-object flow in
// `DefaultTaintTracking`.
toOperand.getAnyDef() = fromInstr and
not fromInstr.isResultConflated() and
(
fromInstr.getResultType() instanceof ArrayType or
fromInstr.getResultType() instanceof Union
)
or
exists(ReadSideEffectInstruction readInstr |
fromInstr = readInstr.getArgumentDef() and
toOperand = readInstr.getSideEffectOperand()
)
}
private predicate operandToInstructionTaintStep(Operand fromOperand, Instruction toInstr) {
// Expressions computed from tainted data are also tainted
exists(CallInstruction call, int argIndex | call = toInstr |
isPureFunction(call.getStaticCallTarget().getName()) and
fromOperand = getACallArgumentOrIndirection(call, argIndex) and
forall(Operand argOperand | argOperand = call.getAnArgumentOperand() |
argOperand = getACallArgumentOrIndirection(call, argIndex) or
predictableInstruction(argOperand.getAnyDef())
) and
// flow through `strlen` tends to cause dubious results, if the length is
// bounded.
not call.getStaticCallTarget().getName() = "strlen"
)
or
// Flow from argument to return value
toInstr =
any(CallInstruction call |
exists(int indexIn |
modelTaintToReturnValue(call.getStaticCallTarget(), indexIn) and
fromOperand = getACallArgumentOrIndirection(call, indexIn) and
not predictableOnlyFlow(call.getStaticCallTarget().getName())
)
private module Cached {
cached
predicate nodeIsBarrier(DataFlow::Node node) {
exists(Variable checkedVar |
readsVariable(node.asInstruction(), checkedVar) and
hasUpperBoundsCheck(checkedVar)
)
or
// Flow from input argument to output argument
// TODO: This won't work in practice as long as all aliased memory is tracked
// together in a single virtual variable.
// TODO: Will this work on the test for `TaintedPath.ql`, where the output arg
// is a pointer addition expression?
toInstr =
any(WriteSideEffectInstruction outInstr |
exists(CallInstruction call, int indexIn, int indexOut |
modelTaintToParameter(call.getStaticCallTarget(), indexIn, indexOut) and
fromOperand = getACallArgumentOrIndirection(call, indexIn) and
outInstr.getIndex() = indexOut and
outInstr.getPrimaryInstruction() = call
)
)
or
// Flow through pointer dereference
toInstr.(LoadInstruction).getSourceAddressOperand() = fromOperand
or
// Flow through partial reads of arrays and unions
toInstr.(LoadInstruction).getSourceValueOperand() = fromOperand and
exists(Instruction fromInstr | fromInstr = fromOperand.getAnyDef() |
not fromInstr.isResultConflated() and
(
fromInstr.getResultType() instanceof ArrayType or
fromInstr.getResultType() instanceof Union
)
)
or
// Unary instructions tend to preserve enough information in practice that we
// want taint to flow through.
// The exception is `FieldAddressInstruction`. Together with the rule for
// `LoadInstruction` above and for `ChiInstruction` below, flow through
// `FieldAddressInstruction` could cause flow into one field to come out an
// unrelated field. This would happen across function boundaries, where the IR
// would not be able to match loads to stores.
toInstr.(UnaryInstruction).getUnaryOperand() = fromOperand and
(
not toInstr instanceof FieldAddressInstruction
or
toInstr.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
)
or
// Flow from an element to an array or union that contains it.
toInstr.(ChiInstruction).getPartialOperand() = fromOperand and
not toInstr.isResultConflated() and
exists(Type t | toInstr.getResultLanguageType().hasType(t, false) |
t instanceof Union
or
t instanceof ArrayType
)
or
exists(BinaryInstruction bin |
bin = toInstr and
predictableInstruction(toInstr.getAnOperand().getDef()) and
fromOperand = toInstr.getAnOperand()
)
or
// This is part of the translation of `a[i]`, where we want taint to flow
// from `a`.
toInstr.(PointerAddInstruction).getLeftOperand() = fromOperand
or
// Until we have flow through indirections across calls, we'll take flow out
// of the indirection and into the argument.
// When we get proper flow through indirections across calls, this code can be
// moved to `adjusedSink` or possibly into the `DataFlow::ExprNode` class.
exists(ReadSideEffectInstruction read |
read.getSideEffectOperand() = fromOperand and
read.getArgumentDef() = toInstr
)
or
// Until we have from through indirections across calls, we'll take flow out
// of the parameter and into its indirection.
// `InitializeIndirectionInstruction` only has a single operand: the address of the
// value whose indirection we are initializing. When initializing an indirection of a parameter `p`,
// the IR looks like this:
// ```
// m1 = InitializeParameter[p] : &r1
// r2 = Load[p] : r2, m1
// m3 = InitializeIndirection[p] : &r2
// ```
// So by having flow from `r2` to `m3` we're enabling flow from `m1` to `m3`. This relies on the
// `LoadOperand`'s overlap being exact.
toInstr.(InitializeIndirectionInstruction).getAnOperand() = fromOperand
}
exists(Variable checkedVar, Operand access |
/*
* This node is guarded by a condition that forces the accessed variable
* to equal something else. For example:
* ```
* x = taintsource()
* if (x == 10) {
* taintsink(x); // not considered tainted
* }
* ```
*/
/**
* Returns the index of the side effect instruction corresponding to the specified function output,
* if one exists.
*/
private int getWriteSideEffectIndex(FunctionOutput output) {
output.isParameterDeref(result)
or
output.isQualifierObject() and result = -1
}
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
readsVariable(access.getDef(), checkedVar)
)
}
/**
* Get an operand that goes into argument `argumentIndex` of `call`. This
* can be either directly or through one pointer indirection.
*/
private Operand getACallArgumentOrIndirection(CallInstruction call, int argumentIndex) {
result = call.getPositionalArgumentOperand(argumentIndex)
or
exists(ReadSideEffectInstruction readSE |
// TODO: why are read side effect operands imprecise?
result = readSE.getSideEffectOperand() and
readSE.getPrimaryInstruction() = call and
readSE.getIndex() = argumentIndex
)
}
private predicate modelTaintToParameter(Function f, int parameterIn, int parameterOut) {
exists(FunctionInput modelIn, FunctionOutput modelOut |
(
f.(DataFlowFunction).hasDataFlow(modelIn, modelOut)
cached
predicate nodeIsBarrierIn(DataFlow::Node node) {
// don't use dataflow into taint sources, as this leads to duplicate results.
exists(Expr source | isUserInput(source, _) |
node = DataFlow::exprNode(source)
or
f.(TaintFunction).hasTaintFlow(modelIn, modelOut)
) and
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
parameterOut = getWriteSideEffectIndex(modelOut)
)
// This case goes together with the similar (but not identical) rule in
// `getNodeForSource`.
node = DataFlow::definitionByReferenceNodeFromArgument(source)
)
or
// don't use dataflow into binary instructions if both operands are unpredictable
exists(BinaryInstruction iTo |
iTo = node.asInstruction() and
not predictableInstruction(iTo.getLeft()) and
not predictableInstruction(iTo.getRight()) and
// propagate taint from either the pointer or the offset, regardless of predictability
not iTo instanceof PointerArithmeticInstruction
)
or
// don't use dataflow through calls to pure functions if two or more operands
// are unpredictable
exists(Instruction iFrom1, Instruction iFrom2, CallInstruction iTo |
iTo = node.asInstruction() and
isPureFunction(iTo.getStaticCallTarget().getName()) and
iFrom1 = iTo.getAnArgument() and
iFrom2 = iTo.getAnArgument() and
not predictableInstruction(iFrom1) and
not predictableInstruction(iFrom2) and
iFrom1 != iFrom2
)
}
cached
Element adjustedSink(DataFlow::Node sink) {
// TODO: is it more appropriate to use asConvertedExpr here and avoid
// `getConversion*`? Or will that cause us to miss some cases where there's
// flow to a conversion (like a `ReferenceDereferenceExpr`) and we want to
// pretend there was flow to the converted `Expr` for the sake of
// compatibility.
sink.asExpr().getConversion*() = result
or
// For compatibility, send flow from arguments to parameters, even for
// functions with no body.
exists(FunctionCall call, int i |
sink.asExpr() = call.getArgument(i) and
result = resolveCall(call).getParameter(i)
)
or
// For compatibility, send flow into a `Variable` if there is flow to any
// Load or Store of that variable.
exists(CopyInstruction copy |
copy.getSourceValue() = sink.asInstruction() and
(
readsVariable(copy, result) or
writesVariable(copy, result)
) and
not hasUpperBoundsCheck(result)
)
or
// For compatibility, send flow into a `NotExpr` even if it's part of a
// short-circuiting condition and thus might get skipped.
result.(NotExpr).getOperand() = sink.asExpr()
or
// Taint postfix and prefix crement operations when their operand is tainted.
result.(CrementOperation).getAnOperand() = sink.asExpr()
or
// Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted.
result.(AssignOperation).getAnOperand() = sink.asExpr()
or
result =
sink.asOperand()
.(SideEffectOperand)
.getUse()
.(ReadSideEffectInstruction)
.getArgumentDef()
.getUnconvertedResultExpression()
}
/**
* Step to return value of a modeled function when an input taints the
* dereference of the return value.
*/
cached
predicate additionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(CallInstruction call, Function func, FunctionInput modelIn, FunctionOutput modelOut |
n1.asOperand() = callInput(call, modelIn) and
(
func.(TaintFunction).hasTaintFlow(modelIn, modelOut)
or
func.(DataFlowFunction).hasDataFlow(modelIn, modelOut)
) and
call.getStaticCallTarget() = func and
modelOut.isReturnValueDeref() and
call = n2.asInstruction()
)
}
}
private predicate modelTaintToReturnValue(Function f, int parameterIn) {
// Taint flow from parameter to return value
exists(FunctionInput modelIn, FunctionOutput modelOut |
f.(TaintFunction).hasTaintFlow(modelIn, modelOut) and
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
(modelOut.isReturnValue() or modelOut.isReturnValueDeref())
)
or
// Data flow (not taint flow) to where the return value points. For the time
// being we will conflate pointers and objects in taint tracking.
exists(FunctionInput modelIn, FunctionOutput modelOut |
f.(DataFlowFunction).hasDataFlow(modelIn, modelOut) and
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
modelOut.isReturnValueDeref()
)
or
// Taint flow from one argument to another and data flow from an argument to a
// return value. This happens in functions like `strcat` and `memcpy`. We
// could model this flow in two separate steps, but that would add reverse
// flow from the write side-effect to the call instruction, which may not be
// desirable.
exists(int parameterMid, InParameter modelMid, OutReturnValue returnOut |
modelTaintToParameter(f, parameterIn, parameterMid) and
modelMid.isParameter(parameterMid) and
f.(DataFlowFunction).hasDataFlow(modelMid, returnOut)
)
}
private Element adjustedSink(DataFlow::Node sink) {
// TODO: is it more appropriate to use asConvertedExpr here and avoid
// `getConversion*`? Or will that cause us to miss some cases where there's
// flow to a conversion (like a `ReferenceDereferenceExpr`) and we want to
// pretend there was flow to the converted `Expr` for the sake of
// compatibility.
sink.asExpr().getConversion*() = result
or
// For compatibility, send flow from arguments to parameters, even for
// functions with no body.
exists(FunctionCall call, int i |
sink.asExpr() = call.getArgument(i) and
result = resolveCall(call).getParameter(i)
)
or
// For compatibility, send flow into a `Variable` if there is flow to any
// Load or Store of that variable.
exists(CopyInstruction copy |
copy.getSourceValue() = sink.asInstruction() and
(
readsVariable(copy, result) or
writesVariable(copy, result)
) and
not hasUpperBoundsCheck(result)
)
or
// For compatibility, send flow into a `NotExpr` even if it's part of a
// short-circuiting condition and thus might get skipped.
result.(NotExpr).getOperand() = sink.asExpr()
or
// Taint postfix and prefix crement operations when their operand is tainted.
result.(CrementOperation).getAnOperand() = sink.asExpr()
or
// Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted.
result.(AssignOperation).getAnOperand() = sink.asExpr()
}
private import Cached
/**
* Holds if `tainted` may contain taint from `source`.
@@ -558,7 +408,7 @@ module TaintedWithPath {
string toString() { result = "TaintTrackingConfiguration" }
}
private class AdjustedConfiguration extends DataFlow3::Configuration {
private class AdjustedConfiguration extends TaintTracking3::Configuration {
AdjustedConfiguration() { this = "AdjustedConfiguration" }
override predicate isSource(DataFlow::Node source) {
@@ -571,21 +421,22 @@ module TaintedWithPath {
exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink)))
}
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
or
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
// Steps into and out of global variables
exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() |
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))
or
readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable))
)
or
additionalTaintStep(n1, n2)
}
override predicate isBarrier(DataFlow::Node node) {
override predicate isSanitizer(DataFlow::Node node) {
exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e))
}
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
/*

View File

@@ -0,0 +1,15 @@
/**
* Provides a `TaintTracking3` module, which is a copy of the `TaintTracking`
* module. Use this class when data-flow configurations or taint-tracking
* configurations must depend on each other. Two classes extending
* `DataFlow::Configuration` should never depend on each other, but one of them
* should instead depend on a `DataFlow2::Configuration`, a
* `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The
* `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and
* `TaintTracking2::Configuration` extends `DataFlow2::Configuration`.
*
* See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation.
*/
module TaintTracking3 {
import semmle.code.cpp.ir.dataflow.internal.tainttracking3.TaintTrackingImpl
}

View File

@@ -2,11 +2,14 @@ private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import DataFlowImplCommon as DataFlowImplCommon
/**
* Gets a function that might be called by `call`.
*/
cached
Function viableCallable(CallInstruction call) {
DataFlowImplCommon::forceCachingInSameStage() and
result = call.getStaticCallTarget()
or
// If the target of the call does not have a body in the snapshot, it might
@@ -43,7 +46,6 @@ private module VirtualDispatch {
abstract DataFlow::Node getDispatchValue();
/** Gets a candidate target for this call. */
cached
abstract Function resolve();
/**

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
* Holds if data can flow in one local step from `node1` to `node2`.
*/
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
(
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
) and
simpleLocalFlowStepExt(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
*/
private predicate jumpStep(Node node1, Node node2, Configuration config) {
jumpStep(node1, node2) and
jumpStepCached(node1, node2) and
not outBarrier(node1, config) and
not inBarrier(node2, config) and
not fullBarrier(node1, config) and
@@ -388,7 +385,7 @@ private module Stage1 {
*/
pragma[nomagic]
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
exists(ArgumentNode arg |
exists(ArgNode arg |
fwdFlow(arg, cc, config) and
viableParamArg(call, _, arg)
)
@@ -515,24 +512,22 @@ private module Stage1 {
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
viableParamArg(call, p, arg) and
fwdFlow(arg, config)
}
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
) {
exists(ParameterNode p |
private predicate revFlowIn(DataFlowCall call, ArgNode arg, boolean toReturn, Configuration config) {
exists(ParamNode p |
revFlow(p, toReturn, config) and
viableParamArgNodeCandFwd1(call, p, arg, config)
)
}
pragma[nomagic]
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
private predicate revFlowInToReturn(DataFlowCall call, ArgNode arg, Configuration config) {
revFlowIn(call, arg, true, config)
}
@@ -597,7 +592,7 @@ private module Stage1 {
* Holds if flow may enter through `p` and reach a return node making `p` a
* candidate for the origin of a summary.
*/
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnKindExt kind |
throughFlowNodeCand(p, config) and
returnFlowCallableNodeCand(c, kind, config) and
@@ -663,7 +658,7 @@ private predicate flowOutOfCallNodeCand1(
pragma[nomagic]
private predicate viableParamArgNodeCand1(
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
DataFlowCall call, ParamNode p, ArgNode arg, Configuration config
) {
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
Stage1::revFlow(arg, config)
@@ -675,7 +670,7 @@ private predicate viableParamArgNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, Configuration config
) {
viableParamArgNodeCand1(call, p, arg, config) and
Stage1::revFlow(p, config) and
@@ -735,8 +730,7 @@ private predicate flowOutOfCallNodeCand1(
*/
pragma[nomagic]
private predicate flowIntoCallNodeCand1(
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, arg, p, config) and
exists(int b, int j |
@@ -944,10 +938,10 @@ private module Stage2 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -992,7 +986,7 @@ private module Stage2 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
)
@@ -1133,10 +1127,9 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1146,7 +1139,7 @@ private module Stage2 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1199,13 +1192,13 @@ private module Stage2 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -1245,8 +1238,7 @@ private predicate flowOutOfCallNodeCand2(
pragma[nomagic]
private predicate flowIntoCallNodeCand2(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
@@ -1260,8 +1252,8 @@ private module LocalFlowBigStep {
*/
private class FlowCheckNode extends Node {
FlowCheckNode() {
this instanceof CastNode or
clearsContent(this, _)
castNode(this) or
clearsContentCached(this, _)
}
}
@@ -1275,7 +1267,7 @@ private module LocalFlowBigStep {
config.isSource(node) or
jumpStep(_, node, config) or
additionalJumpStep(_, node, config) or
node instanceof ParameterNode or
node instanceof ParamNode or
node instanceof OutNodeExt or
store(_, _, node, _) or
read(_, _, node) or
@@ -1321,21 +1313,21 @@ private module LocalFlowBigStep {
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
LocalCallContext cc
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
t = getNodeType(node1)
t = getNodeDataFlowType(node1)
or
additionalLocalFlowStepNodeCand2(node1, node2, config) and
preservesValue = false and
t = getNodeType(node2)
t = getNodeDataFlowType(node2)
) and
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
@@ -1350,7 +1342,7 @@ private module LocalFlowBigStep {
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
t = getNodeDataFlowType(node2) and
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
@@ -1384,7 +1376,7 @@ private module Stage3 {
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -1443,7 +1435,9 @@ private module Stage3 {
bindingset[node, ap]
private predicate filter(Node node, Ap ap) {
not ap.isClearedAt(node) and
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
}
bindingset[ap, contentType]
@@ -1583,10 +1577,10 @@ private module Stage3 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -1631,7 +1625,7 @@ private module Stage3 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -1772,10 +1766,9 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -1785,7 +1778,7 @@ private module Stage3 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -1838,13 +1831,13 @@ private module Stage3 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2088,7 +2081,7 @@ private module Stage4 {
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
private ApNil getApNil(Node node) {
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
}
bindingset[tc, tail]
@@ -2133,11 +2126,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -2158,8 +2148,7 @@ private module Stage4 {
pragma[nomagic]
private predicate flowIntoCall(
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
Configuration config
DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
@@ -2303,10 +2292,10 @@ private module Stage4 {
pragma[nomagic]
private predicate fwdFlowIn(
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
DataFlowCall call, ParamNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
Configuration config
) {
exists(ArgumentNode arg, boolean allowsFieldFlow |
exists(ArgNode arg, boolean allowsFieldFlow |
fwdFlow(arg, outercc, argAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
@@ -2351,7 +2340,7 @@ private module Stage4 {
private predicate fwdFlowIsEntered(
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
@@ -2492,10 +2481,9 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowIn(
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
Configuration config
DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
exists(ParameterNode p, boolean allowsFieldFlow |
exists(ParamNode p, boolean allowsFieldFlow |
revFlow(p, toReturn, returnAp, ap, config) and
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
@@ -2505,7 +2493,7 @@ private module Stage4 {
pragma[nomagic]
private predicate revFlowInToReturn(
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config
) {
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
}
@@ -2558,13 +2546,13 @@ private module Stage4 {
pragma[noinline]
private predicate parameterFlow(
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
ParamNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
) {
revFlow(p, true, apSome(ap0), ap, config) and
c = getNodeEnclosingCallable(p)
}
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
predicate parameterMayFlowThrough(ParamNode p, DataFlowCallable c, Ap ap, Configuration config) {
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
parameterFlow(p, ap, ap0, c, config) and
c = getNodeEnclosingCallable(ret) and
@@ -2609,7 +2597,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
TSummaryCtxSome(ParamNode p, AccessPath ap) {
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
}
@@ -2630,7 +2618,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private ParamNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
@@ -2761,7 +2749,7 @@ private newtype TPathNode =
config.isSource(node) and
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
@@ -2982,7 +2970,7 @@ class PathNode extends TPathNode {
Configuration getConfiguration() { none() }
private predicate isHidden() {
nodeIsHidden(this.getNode()) and
hiddenNode(this.getNode()) and
not this.isSource() and
not this instanceof PathNodeSink
}
@@ -3132,7 +3120,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3151,7 +3139,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
cc instanceof CallContextAny and
sc instanceof SummaryCtxNone and
mid.getAp() instanceof AccessPathNil and
ap = TAccessPathNil(getNodeType(node))
ap = TAccessPathNil(getNodeDataFlowType(node))
or
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
sc = mid.getSummaryCtx()
@@ -3238,7 +3226,7 @@ pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3251,7 +3239,7 @@ pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
) {
exists(ParameterNode p |
exists(ParamNode p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
)
@@ -3275,7 +3263,7 @@ private predicate pathIntoCallable0(
* respectively.
*/
private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
PathNodeMid mid, ParamNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
@@ -3571,7 +3559,7 @@ private module FlowExploration {
private newtype TSummaryCtx1 =
TSummaryCtx1None() or
TSummaryCtx1Param(ParameterNode p)
TSummaryCtx1Param(ParamNode p)
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
@@ -3594,7 +3582,7 @@ private module FlowExploration {
cc instanceof CallContextAny and
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -3614,7 +3602,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not clearsContentCached(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
)
@@ -3628,9 +3616,9 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
not clearsContentCached(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
else any()
)
}
@@ -3786,7 +3774,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
PartialAccessPath ap, Configuration config
) {
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
(
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -3800,7 +3788,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
)
or
@@ -3816,7 +3804,7 @@ private module FlowExploration {
sc1 = TSummaryCtx1None() and
sc2 = TSummaryCtx2None() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getNodeType(node)) and
ap = TPartialNil(getNodeDataFlowType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
@@ -3830,7 +3818,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
apConsFwd(ap, tc, ap0, config) and
compatibleTypes(ap.getType(), getNodeType(node))
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
)
or
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
@@ -3927,7 +3915,7 @@ private module FlowExploration {
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(ArgumentNode arg |
exists(ArgNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
@@ -3946,7 +3934,7 @@ private module FlowExploration {
}
private predicate partialPathIntoCallable(
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
PartialPathNodeFwd mid, ParamNode p, CallContext outercc, CallContextCall innercc,
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
@@ -3983,7 +3971,7 @@ private module FlowExploration {
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
exists(ParamNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
)
@@ -4040,7 +4028,7 @@ private module FlowExploration {
apConsRev(ap, c, ap0, config)
)
or
exists(ParameterNode p |
exists(ParamNode p |
mid.getNode() = p and
viableParamArg(_, p, node) and
sc1 = mid.getSummaryCtx1() and
@@ -4118,7 +4106,7 @@ private module FlowExploration {
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
) {
exists(PartialPathNodeRev mid, ParameterNode p |
exists(PartialPathNodeRev mid, ParamNode p |
mid.getNode() = p and
p.isParameterOf(_, pos) and
sc1 = mid.getSummaryCtx1() and
@@ -4141,7 +4129,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
PartialPathNodeRev mid, ArgNode node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and

View File

@@ -31,26 +31,26 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
* currently excludes read-steps, store-steps, and flow-through.
*
* The analysis uses non-linear recursion: When computing a flow path in or out
* of a call, we use the results of the analysis recursively to resolve lamba
* of a call, we use the results of the analysis recursively to resolve lambda
* calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly.
*/
private module LambdaFlow {
private predicate viableParamNonLambda(DataFlowCall call, int i, ParameterNode p) {
private predicate viableParamNonLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallable(call), i)
}
private predicate viableParamLambda(DataFlowCall call, int i, ParameterNode p) {
private predicate viableParamLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), i)
}
private predicate viableParamArgNonLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) {
private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamNonLambda(call, i, p) and
arg.argumentOf(call, i)
)
}
private predicate viableParamArgLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) {
private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamLambda(call, i, p) and
arg.argumentOf(call, i)
@@ -118,8 +118,8 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
if node instanceof CastNode or node instanceof ArgumentNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeType(node))
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()
}
@@ -129,7 +129,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
lambdaCall(lambdaCall, kind, node) and
t = getNodeType(node) and
t = getNodeDataFlowType(node) and
toReturn = false and
toJump = false and
lastCall = TDataFlowCallNone()
@@ -146,7 +146,7 @@ private module LambdaFlow {
getNodeEnclosingCallable(node) = getNodeEnclosingCallable(mid)
|
preservesValue = false and
t = getNodeType(node)
t = getNodeDataFlowType(node)
or
preservesValue = true and
t = t0
@@ -160,7 +160,7 @@ private module LambdaFlow {
toJump = true and
lastCall = TDataFlowCallNone()
|
jumpStep(node, mid) and
jumpStepCached(node, mid) and
t = t0
or
exists(boolean preservesValue |
@@ -168,7 +168,7 @@ private module LambdaFlow {
getNodeEnclosingCallable(node) != getNodeEnclosingCallable(mid)
|
preservesValue = false and
t = getNodeType(node)
t = getNodeDataFlowType(node)
or
preservesValue = true and
t = t0
@@ -176,7 +176,7 @@ private module LambdaFlow {
)
or
// flow into a callable
exists(ParameterNode p, DataFlowCallOption lastCall0, DataFlowCall call |
exists(ParamNode p, DataFlowCallOption lastCall0, DataFlowCall call |
revLambdaFlowIn(lambdaCall, kind, p, t, toJump, lastCall0) and
(
if lastCall0 = TDataFlowCallNone() and toJump = false
@@ -227,7 +227,7 @@ private module LambdaFlow {
pragma[nomagic]
predicate revLambdaFlowIn(
DataFlowCall lambdaCall, LambdaCallKind kind, ParameterNode p, DataFlowType t, boolean toJump,
DataFlowCall lambdaCall, LambdaCallKind kind, ParamNode p, DataFlowType t, boolean toJump,
DataFlowCallOption lastCall
) {
revLambdaFlow(lambdaCall, kind, p, t, false, toJump, lastCall)
@@ -242,6 +242,89 @@ private DataFlowCallable viableCallableExt(DataFlowCall call) {
cached
private module Cached {
/**
* If needed, call this predicate from `DataFlowImplSpecific.qll` in order to
* force a stage-dependency on the `DataFlowImplCommon.qll` stage and therby
* collapsing the two stages.
*/
cached
predicate forceCachingInSameStage() { any() }
cached
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = n.getEnclosingCallable() }
cached
predicate callEnclosingCallable(DataFlowCall call, DataFlowCallable c) {
c = call.getEnclosingCallable()
}
cached
predicate nodeDataFlowType(Node n, DataFlowType t) { t = getNodeType(n) }
cached
predicate jumpStepCached(Node node1, Node node2) { jumpStep(node1, node2) }
cached
predicate clearsContentCached(Node n, Content c) { clearsContent(n, c) }
cached
predicate isUnreachableInCallCached(Node n, DataFlowCall call) { isUnreachableInCall(n, call) }
cached
predicate outNodeExt(Node n) {
n instanceof OutNode
or
n.(PostUpdateNode).getPreUpdateNode() instanceof ArgNode
}
cached
predicate hiddenNode(Node n) { nodeIsHidden(n) }
cached
OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) {
result = getAnOutNode(call, k.(ValueReturnKind).getKind())
or
exists(ArgNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, k.(ParamUpdateReturnKind).getPosition())
)
}
cached
predicate returnNodeExt(Node n, ReturnKindExt k) {
k = TValueReturn(n.(ReturnNode).getKind())
or
exists(ParamNode p, int pos |
parameterValueFlowsToPreUpdate(p, n) and
p.isParameterOf(_, pos) and
k = TParamUpdate(pos)
)
}
cached
predicate castNode(Node n) { n instanceof CastNode }
cached
predicate castingNode(Node n) {
castNode(n) or
n instanceof ParamNode or
n instanceof OutNodeExt or
// For reads, `x.f`, we want to check that the tracked type after the read (which
// is obtained by popping the head of the access path stack) is compatible with
// the type of `x.f`.
read(_, _, n)
}
cached
predicate parameterNode(Node n, DataFlowCallable c, int i) {
n.(ParameterNode).isParameterOf(c, i)
}
cached
predicate argumentNode(Node n, DataFlowCall call, int pos) {
n.(ArgumentNode).argumentOf(call, pos)
}
/**
* Gets a viable target for the lambda call `call`.
*
@@ -261,7 +344,7 @@ private module Cached {
* The instance parameter is considered to have index `-1`.
*/
pragma[nomagic]
private predicate viableParam(DataFlowCall call, int i, ParameterNode p) {
private predicate viableParam(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableExt(call), i)
}
@@ -270,11 +353,11 @@ private module Cached {
* dispatch into account.
*/
cached
predicate viableParamArg(DataFlowCall call, ParameterNode p, ArgumentNode arg) {
predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParam(call, i, p) and
arg.argumentOf(call, i) and
compatibleTypes(getNodeType(arg), getNodeType(p))
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p))
)
}
@@ -312,7 +395,7 @@ private module Cached {
* `read` indicates whether it is contents of `p` that can flow to `node`.
*/
pragma[nomagic]
private predicate parameterValueFlowCand(ParameterNode p, Node node, boolean read) {
private predicate parameterValueFlowCand(ParamNode p, Node node, boolean read) {
p = node and
read = false
or
@@ -325,30 +408,30 @@ private module Cached {
// read
exists(Node mid |
parameterValueFlowCand(p, mid, false) and
readStep(mid, _, node) and
read(mid, _, node) and
read = true
)
or
// flow through: no prior read
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArgCand(p, arg, false) and
argumentValueFlowsThroughCand(arg, node, read)
)
or
// flow through: no read inside method
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArgCand(p, arg, read) and
argumentValueFlowsThroughCand(arg, node, false)
)
}
pragma[nomagic]
private predicate parameterValueFlowArgCand(ParameterNode p, ArgumentNode arg, boolean read) {
private predicate parameterValueFlowArgCand(ParamNode p, ArgNode arg, boolean read) {
parameterValueFlowCand(p, arg, read)
}
pragma[nomagic]
predicate parameterValueFlowsToPreUpdateCand(ParameterNode p, PostUpdateNode n) {
predicate parameterValueFlowsToPreUpdateCand(ParamNode p, PostUpdateNode n) {
parameterValueFlowCand(p, n.getPreUpdateNode(), false)
}
@@ -360,7 +443,7 @@ private module Cached {
* `read` indicates whether it is contents of `p` that can flow to the return
* node.
*/
predicate parameterValueFlowReturnCand(ParameterNode p, ReturnKind kind, boolean read) {
predicate parameterValueFlowReturnCand(ParamNode p, ReturnKind kind, boolean read) {
exists(ReturnNode ret |
parameterValueFlowCand(p, ret, read) and
kind = ret.getKind()
@@ -369,9 +452,9 @@ private module Cached {
pragma[nomagic]
private predicate argumentValueFlowsThroughCand0(
DataFlowCall call, ArgumentNode arg, ReturnKind kind, boolean read
DataFlowCall call, ArgNode arg, ReturnKind kind, boolean read
) {
exists(ParameterNode param | viableParamArg(call, param, arg) |
exists(ParamNode param | viableParamArg(call, param, arg) |
parameterValueFlowReturnCand(param, kind, read)
)
}
@@ -382,14 +465,14 @@ private module Cached {
*
* `read` indicates whether it is contents of `arg` that can flow to `out`.
*/
predicate argumentValueFlowsThroughCand(ArgumentNode arg, Node out, boolean read) {
predicate argumentValueFlowsThroughCand(ArgNode arg, Node out, boolean read) {
exists(DataFlowCall call, ReturnKind kind |
argumentValueFlowsThroughCand0(call, arg, kind, read) and
out = getAnOutNode(call, kind)
)
}
predicate cand(ParameterNode p, Node n) {
predicate cand(ParamNode p, Node n) {
parameterValueFlowCand(p, n, _) and
(
parameterValueFlowReturnCand(p, _, _)
@@ -416,21 +499,21 @@ private module Cached {
* If a read step was taken, then `read` captures the `Content`, the
* container type, and the content type.
*/
predicate parameterValueFlow(ParameterNode p, Node node, ReadStepTypesOption read) {
predicate parameterValueFlow(ParamNode p, Node node, ReadStepTypesOption read) {
parameterValueFlow0(p, node, read) and
if node instanceof CastingNode
then
// normal flow through
read = TReadStepTypesNone() and
compatibleTypes(getNodeType(p), getNodeType(node))
compatibleTypes(getNodeDataFlowType(p), getNodeDataFlowType(node))
or
// getter
compatibleTypes(read.getContentType(), getNodeType(node))
compatibleTypes(read.getContentType(), getNodeDataFlowType(node))
else any()
}
pragma[nomagic]
private predicate parameterValueFlow0(ParameterNode p, Node node, ReadStepTypesOption read) {
private predicate parameterValueFlow0(ParamNode p, Node node, ReadStepTypesOption read) {
p = node and
Cand::cand(p, _) and
read = TReadStepTypesNone()
@@ -447,7 +530,7 @@ private module Cached {
readStepWithTypes(mid, read.getContainerType(), read.getContent(), node,
read.getContentType()) and
Cand::parameterValueFlowReturnCand(p, _, true) and
compatibleTypes(getNodeType(p), read.getContainerType())
compatibleTypes(getNodeDataFlowType(p), read.getContainerType())
)
or
parameterValueFlow0_0(TReadStepTypesNone(), p, node, read)
@@ -455,34 +538,32 @@ private module Cached {
pragma[nomagic]
private predicate parameterValueFlow0_0(
ReadStepTypesOption mustBeNone, ParameterNode p, Node node, ReadStepTypesOption read
ReadStepTypesOption mustBeNone, ParamNode p, Node node, ReadStepTypesOption read
) {
// flow through: no prior read
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArg(p, arg, mustBeNone) and
argumentValueFlowsThrough(arg, read, node)
)
or
// flow through: no read inside method
exists(ArgumentNode arg |
exists(ArgNode arg |
parameterValueFlowArg(p, arg, read) and
argumentValueFlowsThrough(arg, mustBeNone, node)
)
}
pragma[nomagic]
private predicate parameterValueFlowArg(
ParameterNode p, ArgumentNode arg, ReadStepTypesOption read
) {
private predicate parameterValueFlowArg(ParamNode p, ArgNode arg, ReadStepTypesOption read) {
parameterValueFlow(p, arg, read) and
Cand::argumentValueFlowsThroughCand(arg, _, _)
}
pragma[nomagic]
private predicate argumentValueFlowsThrough0(
DataFlowCall call, ArgumentNode arg, ReturnKind kind, ReadStepTypesOption read
DataFlowCall call, ArgNode arg, ReturnKind kind, ReadStepTypesOption read
) {
exists(ParameterNode param | viableParamArg(call, param, arg) |
exists(ParamNode param | viableParamArg(call, param, arg) |
parameterValueFlowReturn(param, kind, read)
)
}
@@ -496,18 +577,18 @@ private module Cached {
* container type, and the content type.
*/
pragma[nomagic]
predicate argumentValueFlowsThrough(ArgumentNode arg, ReadStepTypesOption read, Node out) {
predicate argumentValueFlowsThrough(ArgNode arg, ReadStepTypesOption read, Node out) {
exists(DataFlowCall call, ReturnKind kind |
argumentValueFlowsThrough0(call, arg, kind, read) and
out = getAnOutNode(call, kind)
|
// normal flow through
read = TReadStepTypesNone() and
compatibleTypes(getNodeType(arg), getNodeType(out))
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(out))
or
// getter
compatibleTypes(getNodeType(arg), read.getContainerType()) and
compatibleTypes(read.getContentType(), getNodeType(out))
compatibleTypes(getNodeDataFlowType(arg), read.getContainerType()) and
compatibleTypes(read.getContentType(), getNodeDataFlowType(out))
)
}
@@ -516,7 +597,7 @@ private module Cached {
* value-preserving steps and a single read step, not taking call
* contexts into account, thus representing a getter-step.
*/
predicate getterStep(ArgumentNode arg, Content c, Node out) {
predicate getterStep(ArgNode arg, Content c, Node out) {
argumentValueFlowsThrough(arg, TReadStepTypesSome(_, c, _), out)
}
@@ -529,7 +610,7 @@ private module Cached {
* container type, and the content type.
*/
private predicate parameterValueFlowReturn(
ParameterNode p, ReturnKind kind, ReadStepTypesOption read
ParamNode p, ReturnKind kind, ReadStepTypesOption read
) {
exists(ReturnNode ret |
parameterValueFlow(p, ret, read) and
@@ -553,7 +634,7 @@ private module Cached {
private predicate mayBenefitFromCallContextExt(DataFlowCall call, DataFlowCallable callable) {
mayBenefitFromCallContext(call, callable)
or
callable = call.getEnclosingCallable() and
callEnclosingCallable(call, callable) and
exists(viableCallableLambda(call, TDataFlowCallSome(_)))
}
@@ -611,7 +692,7 @@ private module Cached {
mayBenefitFromCallContextExt(call, _) and
c = viableCallableExt(call) and
ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContextExt(call, ctx)) and
tgts = strictcount(DataFlowCall ctx | viableCallableExt(ctx) = call.getEnclosingCallable()) and
tgts = strictcount(DataFlowCall ctx | callEnclosingCallable(call, viableCallableExt(ctx))) and
ctxtgts < tgts
)
}
@@ -635,8 +716,7 @@ private module Cached {
* Holds if `p` can flow to the pre-update node associated with post-update
* node `n`, in the same callable, using only value-preserving steps.
*/
cached
predicate parameterValueFlowsToPreUpdate(ParameterNode p, PostUpdateNode n) {
private predicate parameterValueFlowsToPreUpdate(ParamNode p, PostUpdateNode n) {
parameterValueFlow(p, n.getPreUpdateNode(), TReadStepTypesNone())
}
@@ -644,9 +724,9 @@ private module Cached {
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
) {
storeStep(node1, c, node2) and
readStep(_, c, _) and
contentType = getNodeType(node1) and
containerType = getNodeType(node2)
read(_, c, _) and
contentType = getNodeDataFlowType(node1) and
containerType = getNodeDataFlowType(node2)
or
exists(Node n1, Node n2 |
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
@@ -654,12 +734,15 @@ private module Cached {
|
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1)
or
readStep(n2, c, n1) and
contentType = getNodeType(n1) and
containerType = getNodeType(n2)
read(n2, c, n1) and
contentType = getNodeDataFlowType(n1) and
containerType = getNodeDataFlowType(n2)
)
}
cached
predicate read(Node node1, Content c, Node node2) { readStep(node1, c, node2) }
/**
* Holds if data can flow from `node1` to `node2` via a direct assignment to
* `f`.
@@ -678,8 +761,9 @@ private module Cached {
* are aliases. A typical example is a function returning `this`, implementing a fluent
* interface.
*/
cached
predicate reverseStepThroughInputOutputAlias(PostUpdateNode fromNode, PostUpdateNode toNode) {
private predicate reverseStepThroughInputOutputAlias(
PostUpdateNode fromNode, PostUpdateNode toNode
) {
exists(Node fromPre, Node toPre |
fromPre = fromNode.getPreUpdateNode() and
toPre = toNode.getPreUpdateNode()
@@ -688,14 +772,20 @@ private module Cached {
// Does the language-specific simpleLocalFlowStep already model flow
// from function input to output?
fromPre = getAnOutNode(c, _) and
toPre.(ArgumentNode).argumentOf(c, _) and
simpleLocalFlowStep(toPre.(ArgumentNode), fromPre)
toPre.(ArgNode).argumentOf(c, _) and
simpleLocalFlowStep(toPre.(ArgNode), fromPre)
)
or
argumentValueFlowsThrough(toPre, TReadStepTypesNone(), fromPre)
)
}
cached
predicate simpleLocalFlowStepExt(Node node1, Node node2) {
simpleLocalFlowStep(node1, node2) or
reverseStepThroughInputOutputAlias(node1, node2)
}
/**
* Holds if the call context `call` either improves virtual dispatch in
* `callable` or if it allows us to prune unreachable nodes in `callable`.
@@ -704,7 +794,7 @@ private module Cached {
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
reducedViableImplInCallContext(_, callable, call)
or
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCall(n, call))
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
cached
@@ -726,12 +816,12 @@ private module Cached {
cached
newtype TLocalFlowCallContext =
TAnyLocalCall() or
TSpecificLocalCall(DataFlowCall call) { isUnreachableInCall(_, call) }
TSpecificLocalCall(DataFlowCall call) { isUnreachableInCallCached(_, call) }
cached
newtype TReturnKindExt =
TValueReturn(ReturnKind kind) or
TParamUpdate(int pos) { exists(ParameterNode p | p.isParameterOf(_, pos)) }
TParamUpdate(int pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
cached
newtype TBooleanOption =
@@ -761,23 +851,15 @@ private module Cached {
* A `Node` at which a cast can occur such that the type should be checked.
*/
class CastingNode extends Node {
CastingNode() {
this instanceof ParameterNode or
this instanceof CastNode or
this instanceof OutNodeExt or
// For reads, `x.f`, we want to check that the tracked type after the read (which
// is obtained by popping the head of the access path stack) is compatible with
// the type of `x.f`.
readStep(_, _, this)
}
CastingNode() { castingNode(this) }
}
private predicate readStepWithTypes(
Node n1, DataFlowType container, Content c, Node n2, DataFlowType content
) {
readStep(n1, c, n2) and
container = getNodeType(n1) and
content = getNodeType(n2)
read(n1, c, n2) and
container = getNodeDataFlowType(n1) and
content = getNodeDataFlowType(n2)
}
private newtype TReadStepTypesOption =
@@ -854,7 +936,7 @@ class CallContextSomeCall extends CallContextCall, TSomeCall {
override string toString() { result = "CcSomeCall" }
override predicate relevantFor(DataFlowCallable callable) {
exists(ParameterNode p | getNodeEnclosingCallable(p) = callable)
exists(ParamNode p | getNodeEnclosingCallable(p) = callable)
}
override predicate matchesCall(DataFlowCall call) { any() }
@@ -866,7 +948,7 @@ class CallContextReturn extends CallContextNoCall, TReturn {
}
override predicate relevantFor(DataFlowCallable callable) {
exists(DataFlowCall call | this = TReturn(_, call) and call.getEnclosingCallable() = callable)
exists(DataFlowCall call | this = TReturn(_, call) and callEnclosingCallable(call, callable))
}
}
@@ -899,7 +981,7 @@ class LocalCallContextSpecificCall extends LocalCallContext, TSpecificLocalCall
}
private predicate relevantLocalCCtx(DataFlowCall call, DataFlowCallable callable) {
exists(Node n | getNodeEnclosingCallable(n) = callable and isUnreachableInCall(n, call))
exists(Node n | getNodeEnclosingCallable(n) = callable and isUnreachableInCallCached(n, call))
}
/**
@@ -913,26 +995,37 @@ LocalCallContext getLocalCallContext(CallContext ctx, DataFlowCallable callable)
else result instanceof LocalCallContextAny
}
/**
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
class ParamNode extends Node {
ParamNode() { parameterNode(this, _, _) }
/**
* Holds if this node is the parameter of callable `c` at the specified
* (zero-based) position.
*/
predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) }
}
/** A data-flow node that represents a call argument. */
class ArgNode extends Node {
ArgNode() { argumentNode(this, _, _) }
/** Holds if this argument occurs at the given position in the given call. */
final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) }
}
/**
* A node from which flow can return to the caller. This is either a regular
* `ReturnNode` or a `PostUpdateNode` corresponding to the value of a parameter.
*/
class ReturnNodeExt extends Node {
ReturnNodeExt() {
this instanceof ReturnNode or
parameterValueFlowsToPreUpdate(_, this)
}
ReturnNodeExt() { returnNodeExt(this, _) }
/** Gets the kind of this returned value. */
ReturnKindExt getKind() {
result = TValueReturn(this.(ReturnNode).getKind())
or
exists(ParameterNode p, int pos |
parameterValueFlowsToPreUpdate(p, this) and
p.isParameterOf(_, pos) and
result = TParamUpdate(pos)
)
}
ReturnKindExt getKind() { returnNodeExt(this, result) }
}
/**
@@ -940,11 +1033,7 @@ class ReturnNodeExt extends Node {
* or a post-update node associated with a call argument.
*/
class OutNodeExt extends Node {
OutNodeExt() {
this instanceof OutNode
or
this.(PostUpdateNode).getPreUpdateNode() instanceof ArgumentNode
}
OutNodeExt() { outNodeExt(this) }
}
/**
@@ -957,7 +1046,7 @@ abstract class ReturnKindExt extends TReturnKindExt {
abstract string toString();
/** Gets a node corresponding to data flow out of `call`. */
abstract OutNodeExt getAnOutNode(DataFlowCall call);
final OutNodeExt getAnOutNode(DataFlowCall call) { result = getAnOutNodeExt(call, this) }
}
class ValueReturnKind extends ReturnKindExt, TValueReturn {
@@ -968,10 +1057,6 @@ class ValueReturnKind extends ReturnKindExt, TValueReturn {
ReturnKind getKind() { result = kind }
override string toString() { result = kind.toString() }
override OutNodeExt getAnOutNode(DataFlowCall call) {
result = getAnOutNode(call, this.getKind())
}
}
class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate {
@@ -982,13 +1067,6 @@ class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate {
int getPosition() { result = pos }
override string toString() { result = "param update " + pos }
override OutNodeExt getAnOutNode(DataFlowCall call) {
exists(ArgumentNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, this.getPosition())
)
}
}
/** A callable tagged with a relevant return kind. */
@@ -1015,10 +1093,13 @@ class ReturnPosition extends TReturnPosition0 {
*/
pragma[inline]
DataFlowCallable getNodeEnclosingCallable(Node n) {
exists(Node n0 |
pragma[only_bind_into](n0) = n and
pragma[only_bind_into](result) = n0.getEnclosingCallable()
)
nodeEnclosingCallable(pragma[only_bind_out](n), pragma[only_bind_into](result))
}
/** Gets the type of `n` used for type pruning. */
pragma[inline]
DataFlowType getNodeDataFlowType(Node n) {
nodeDataFlowType(pragma[only_bind_out](n), pragma[only_bind_into](result))
}
pragma[noinline]
@@ -1042,7 +1123,7 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
cc instanceof CallContextAny and callable = viableCallableExt(call)
or
exists(DataFlowCallable c0, DataFlowCall call0 |
call0.getEnclosingCallable() = callable and
callEnclosingCallable(call0, callable) and
cc = TReturn(c0, call0) and
c0 = prunedViableImplInCallContextReverse(call0, call)
)
@@ -1063,8 +1144,6 @@ DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
result = viableCallableExt(call) and cc instanceof CallContextReturn
}
predicate read = readStep/3;
/** An optional Boolean value. */
class BooleanOption extends TBooleanOption {
string toString() {
@@ -1116,7 +1195,7 @@ abstract class AccessPathFront extends TAccessPathFront {
TypedContent getHead() { this = TFrontHead(result) }
predicate isClearedAt(Node n) { clearsContent(n, getHead().getContent()) }
predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {

View File

@@ -557,5 +557,5 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() }
/** Extra data-flow steps needed for lamba flow analysis. */
/** Extra data-flow steps needed for lambda flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }

View File

@@ -12,10 +12,20 @@ private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.models.interfaces.DataFlow
cached
private newtype TIRDataFlowNode =
TInstructionNode(Instruction i) or
TOperandNode(Operand op) or
TVariableNode(Variable var)
private module Cached {
cached
newtype TIRDataFlowNode =
TInstructionNode(Instruction i) or
TOperandNode(Operand op) or
TVariableNode(Variable var)
cached
predicate localFlowStepCached(Node nodeFrom, Node nodeTo) {
simpleLocalFlowStep(nodeFrom, nodeTo)
}
}
private import Cached
/**
* A node in a data flow graph.
@@ -362,15 +372,22 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
/**
* Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
* For instance, an update to a field of a struct containing only one field. For these cases we
* attach the PostUpdateNode to the store instruction. There's no obvious pre update node for this case
* (as the entire memory is updated), so `getPreUpdateNode` is implemented as `none()`.
* For instance, an update to a field of a struct containing only one field. Even if the store does
* have a chi instruction, a subsequent use of the result of the store may be linked directly to the
* result of the store as an inexact definition if the store totally overlaps the use. For these
* cases we attach the PostUpdateNode to the store instruction. There's no obvious pre update node
* for this case (as the entire memory is updated), so `getPreUpdateNode` is implemented as
* `none()`.
*/
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
override StoreInstruction instr;
ExplicitSingleFieldStoreQualifierNode() {
not exists(ChiInstruction chi | chi.getPartial() = instr) and
(
instr.getAUse().isDefinitionInexact()
or
not exists(ChiInstruction chi | chi.getPartial() = instr)
) and
// Without this condition any store would create a `PostUpdateNode`.
instr.getDestinationAddress() instanceof FieldAddressInstruction
}
@@ -583,7 +600,7 @@ Node uninitializedNode(LocalVariable v) { none() }
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
* (intra-procedural) step.
*/
predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo) }
predicate localFlowStep = localFlowStepCached/2;
/**
* INTERNAL: do not use.
@@ -591,7 +608,6 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
* This is the local flow predicate that's used as a building block in global
* data flow. It may have less flow than the `localFlowStep` predicate.
*/
cached
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
// Operand -> Instruction flow
simpleInstructionLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction())

View File

@@ -9,30 +9,18 @@ private import semmle.code.cpp.ir.dataflow.DataFlow
/**
* Gets the instruction that goes into `input` for `call`.
*/
DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
// A positional argument
Operand callInput(CallInstruction call, FunctionInput input) {
// An argument or qualifier
exists(int index |
result.asInstruction() = call.getPositionalArgument(index) and
input.isParameter(index)
result = call.getArgumentOperand(index) and
input.isParameterOrQualifierAddress(index)
)
or
// A value pointed to by a positional argument
// A value pointed to by an argument or qualifier
exists(ReadSideEffectInstruction read |
result.asOperand() = read.getSideEffectOperand() and
result = read.getSideEffectOperand() and
read.getPrimaryInstruction() = call and
input.isParameterDeref(read.getIndex())
)
or
// The qualifier pointer
result.asInstruction() = call.getThisArgument() and
input.isQualifierAddress()
or
// The qualifier object
exists(ReadSideEffectInstruction read |
result.asOperand() = read.getSideEffectOperand() and
read.getPrimaryInstruction() = call and
read.getIndex() = -1 and
input.isQualifierObject()
input.isParameterDerefOrQualifierObject(read.getIndex())
)
}
@@ -44,19 +32,11 @@ Instruction callOutput(CallInstruction call, FunctionOutput output) {
result = call and
output.isReturnValue()
or
// The side effect of a call on the value pointed to by a positional argument
// The side effect of a call on the value pointed to by an argument or qualifier
exists(WriteSideEffectInstruction effect |
result = effect and
effect.getPrimaryInstruction() = call and
output.isParameterDeref(effect.getIndex())
)
or
// The side effect of a call on the qualifier object
exists(WriteSideEffectInstruction effect |
result = effect and
effect.getPrimaryInstruction() = call and
effect.getIndex() = -1 and
output.isQualifierObject()
output.isParameterDerefOrQualifierObject(effect.getIndex())
)
// TODO: return value dereference
}

View File

@@ -6,34 +6,7 @@ private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
/**
* Gets a short ID for an IR dataflow node.
* - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`).
* - For `Operand`s, this is the label of the operand, prefixed with the result ID of the
* instruction and a dot (e.g. `m128.left`).
* - For `Variable`s, this is the qualified name of the variable.
*/
private string nodeId(DataFlow::Node node, int order1, int order2) {
exists(Instruction instruction | instruction = node.asInstruction() |
result = instruction.getResultId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
exists(Operand operand, Instruction instruction |
operand = node.asOperand() and
instruction = operand.getUse()
|
result = instruction.getResultId() + "." + operand.getDumpId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
result = "var(" + node.asVariable().getQualifiedName() + ")" and
order1 = 1000000 and
order2 = 0
}
private import PrintIRUtilities
/**
* Gets the local dataflow from other nodes in the same function to this node.

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