Compare commits

..

590 Commits

Author SHA1 Message Date
Esben Sparre Andreasen
5f41b3afb6 make boosted version of js/code-injection
Changes generated with:

```
tb boost src/Security/CWE-094/CodeInjection.ql CodeInjectionSink
```
2022-01-31 10:57:18 +01:00
Tom Hvitved
477f83cf9e Merge pull request #7746 from hvitved/csharp/remove-legacy-relations
C#: Remove some unused legacy relations from the DB scheme
2022-01-26 10:40:55 +01:00
Arthur Baars
948ebe4b4c Merge pull request #7568 from aibaars/ruby-pattern-matching-taint
Ruby: taint steps for pattern matches
2022-01-26 10:27:47 +01:00
Stephan Brandauer
b7690e5e6b Merge pull request #7734 from kaeluka/js-add-node-prefix-to-module-import
js: add support for the 'node:' prefix for importing internal modules
2022-01-26 10:15:08 +01:00
Tom Hvitved
28e03a8aae Merge pull request #7738 from hvitved/ruby/action-controller-perf
Ruby: Fix bad join in `ActionControllerHelperMethod`
2022-01-26 09:48:21 +01:00
Tom Hvitved
2c27a07ead Merge pull request #7726 from hvitved/ruby/any-array-element-content
Ruby: Introduce `TAnyArrayElementContent`
2022-01-26 09:48:01 +01:00
Tom Hvitved
51205d6ce5 C#: Add DB downgrade script 2022-01-26 08:44:37 +01:00
Tom Hvitved
83fb822115 C#: Add DB upgrade script 2022-01-26 08:43:24 +01:00
Tom Hvitved
4c16320e28 C#: Remove some unused legacy relations from the DB scheme 2022-01-26 08:35:08 +01:00
Arthur Baars
941f230c94 Merge pull request #7729 from github/hmac/bump-clap
Ruby extractor: bump clap
2022-01-26 08:12:47 +01:00
Henry Mercer
15aa09fb7a Merge pull request #7744 from github/henrymercer/js-atm-tweak-query-help
JS: Move experimental notice to the bottom of the ML-powered query help
2022-01-25 17:44:27 +00:00
Edoardo Pirovano
662675ebf0 Merge pull request #7739 from github/edoardo/3.4-mergeback
Merge `rc/3.4` into `main`
2022-01-25 17:44:13 +00:00
Shati Patel
1c711e05be Merge pull request #7661 from shati-patel/vscode-pack-commands
Docs: Mention packaging commands in CodeQL extension
2022-01-25 16:55:37 +00:00
Andrew Eisenberg
e722121be8 Merge pull request #7618 from github/aeisenberg/getting-started-docs
Docs: Simplify getting started docs
2022-01-25 08:30:06 -08:00
Edoardo Pirovano
1b539eb4dc Merge branch rc/3.4 into main 2022-01-25 16:22:01 +00:00
Mathias Vorreiter Pedersen
5d0f7efe84 Merge pull request #7743 from jketema/doc-fixes
CodeQL documentation fixes
2022-01-25 16:11:08 +00:00
Henry Mercer
70f7535988 JS: Move experimental notice to the bottom of the ML-powered query help
The Code Scanning UI shows just the first paragraph of the query help
as a summary, until a user chooses to expand the help.
We decided it was more useful to display the standard query help in this
summary compared to the experimental query notice, since there is
already a notice about experimental queries on the alert show page.
2022-01-25 15:52:09 +00:00
Tom Hvitved
afd6f58fe8 Merge pull request #7741 from hvitved/csharp/compilation-args-exclude-extractor-args
C#: Exclude extractor arguments from `compilation_args` relation
2022-01-25 16:31:46 +01:00
Geoffrey White
63ff17b3c1 Merge pull request #7737 from geoffw0/clrtxt5
C++: Upgrade cpp/cleartext-storage-file
2022-01-25 15:09:13 +00:00
Jeroen Ketema
082c712843 Replace Block by BlockStmt in basic C/C++ query documentation
`Block` has be deprecated in favor of `BlockStmt`.
2022-01-25 15:21:34 +01:00
Jeroen Ketema
1cfd222770 Remove redundant can 2022-01-25 15:21:06 +01:00
Tom Hvitved
d7a91fdbe6 C#: Exclude extractor arguments from compilation_args relation 2022-01-25 15:09:29 +01:00
Stephan Brandauer
4ee290acd3 update test for 'node:' prefix 2022-01-25 14:25:44 +01:00
Stephan Brandauer
20ea825e4a test for 'node:' prefix for importing node modules 2022-01-25 13:43:16 +01:00
shati-patel
1462565810 Clarify "download packs" usage 2022-01-25 12:37:17 +00:00
Erik Krogh Kristensen
cc527bdecd Merge pull request #7721 from erik-krogh/CWE-1275
JS: add a js/samesite-none-cookie cookie
2022-01-25 13:28:08 +01:00
Shati Patel
9e1e2ba442 Apply suggestions from code review
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-01-25 12:27:00 +00:00
Tom Hvitved
49488fa0a0 Ruby: Fix bad join in ActionControllerHelperMethod
```
[2022-01-25 12:35:14] (234s) Tuple counts for ActionController::ActionControllerHelperMethod#class#ff/2@ef816fil after 1.5s:
                      7685     ~0%     {3} r1 = JOIN ActionController::ActionControllerContextCall#ff#shared WITH Method::Method::getName_dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'controllerClass', Lhs.0 'this'
                      13198    ~0%     {3} r2 = JOIN r1 WITH Constant::ConstantValue::getStringOrSymbol_dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1 'controllerClass', Lhs.2 'this', Rhs.1
                      15835365 ~4%     {5} r3 = JOIN r2 WITH AST::AstNode::getEnclosingModule_dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, "helper_method", Lhs.0 'controllerClass', Lhs.1 'this', Lhs.2
                      12943    ~1%     {4} r4 = JOIN r3 WITH Call::MethodCall::getMethodName_dispred#ff ON FIRST 2 OUTPUT Lhs.4, Lhs.2 'controllerClass', Lhs.3 'this', Lhs.0
                      1146184  ~0%     {4} r5 = JOIN r4 WITH Expr::Expr::getConstantValue_dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.3, Rhs.1, Lhs.1 'controllerClass', Lhs.2 'this'
                      212      ~0%     {2} r6 = JOIN r5 WITH project#Call::Call::getArgument_dispred#fff ON FIRST 2 OUTPUT Lhs.3 'this', Lhs.2 'controllerClass'
                                       return r6
```

Joining on enclosing module and name simultaneously yields a much better join.
2022-01-25 13:00:13 +01:00
Erik Krogh Kristensen
caaee5e4e5 make a utility predicate for extracting sameSite values 2022-01-25 12:32:04 +01:00
Erik Krogh Kristensen
9f9dee5d18 apply documentation suggestions
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2022-01-25 12:14:16 +01:00
Tom Hvitved
67962cb93d Ruby: Fix bad join in access predicate
Joining on variable name alone is a bad thing:

```
[2022-01-25 11:13:20] (228s) Tuple counts for Variable::Cached::access#ff#shared/3@868b54tu after 3m37s:
                      112554    ~0%     {3} r1 = JOIN Variable::VariableReal::getNameImpl_dispred#ff WITH Variable::VariableReal::getDeclaringScopeImpl_dispred#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.0 'arg2', Rhs.1 'arg1'
                      561015756 ~1%     {3} r2 = JOIN r1 WITH Variable::variableName#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1 'arg0', Lhs.2 'arg1', Lhs.1 'arg2'
                                        return r2
```

This change ensures that we join on name and scope simultaneously.
2022-01-25 11:37:38 +01:00
Michael Nebel
26d9848fca Merge pull request #7730 from michaelnebel/csharp/csharp10-release-notes
C#: Add change notes for the already implemented C# 10 features.
2022-01-25 11:31:02 +01:00
Geoffrey White
d70b813949 Merge pull request #7732 from MathiasVP/security-severity-for-return-stack-allocated-memory
C++: Add security-severity to `cpp/return-stack-allocated-memory`
2022-01-25 10:13:49 +00:00
Stephan Brandauer
9825136e58 add support for the 'node:' prefix for importing internal modules 2022-01-25 10:55:34 +01:00
Tom Hvitved
0299b4603f Merge pull request #7677 from hvitved/ruby/constant-value
Ruby: Replace `getValueText` with `getConstantValue`
2022-01-25 10:31:02 +01:00
Harry Maclean
962d0213b5 Ruby extractor: stop using deprecated function 2022-01-25 22:04:24 +13:00
Tony Torralba
82ad79f55f Merge pull request #7728 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-25 09:53:12 +01:00
Mathias Vorreiter Pedersen
72241886bf C++: Add security-severity to 'cpp/return-stack-allocated-memory'. 2022-01-25 08:49:00 +00:00
Michael Nebel
f6a8d50593 C#: Add change notes for the already implemented C# 10 features. 2022-01-25 09:46:57 +01:00
Stephan Brandauer
35cc5ff0e2 Merge pull request #7715 from kaeluka/recognize-fs-extra-path-args
JS: add a predicate to recognize path arguments in calls to the fs-extra lib
2022-01-25 09:36:59 +01:00
Tom Hvitved
06776d19ee Merge pull request #4949 from luchua-bc/cs/hash-without-salt
C#: Query to detect hash without salt
2022-01-25 09:04:23 +01:00
Tom Hvitved
fdd787b89c Merge pull request #7658 from hvitved/csharp/dataflow/no-negative-positions
C#: Get rid of negative parameter/argument data-flow positions
2022-01-25 09:01:44 +01:00
dependabot[bot]
6543b1a3a9 Update clap requirement from 2.33 to 3.0
Updates the requirements on [clap](https://github.com/clap-rs/clap) to permit the latest version.

Apply this update in both the generator and extractor.
2022-01-25 16:53:39 +13:00
github-actions[bot]
1c2f4e79ff Add changed framework coverage reports 2022-01-25 00:10:23 +00:00
CodeQL CI
8d1e22bc38 Merge pull request #7632 from erik-krogh/CWE-862
Approved by esbena, felicitymay
2022-01-24 12:47:16 -08:00
Erik Krogh Kristensen
d4bac887cf add a js/samesite-none-cookie cookie 2022-01-24 21:39:41 +01:00
yo-h
364f07e3c5 Merge pull request #7725 from github/turbo-go-117-update
Update supported Go version
2022-01-24 15:23:00 -05:00
Robert Marsh
6d3381cb89 Merge pull request #7718 from MathiasVP/move-return-stack-allocated-memory-into-code-scanning
C++: Add `security` tag to `cpp/return-stack-allocated-memory`
2022-01-24 14:52:23 -05:00
Tom Hvitved
66a24c5c49 Ruby: Introduce TAnyArrayElementContent 2022-01-24 20:25:05 +01:00
Pierre
af0fc37f39 Update supported Go version 2022-01-24 20:20:04 +01:00
Andrew Eisenberg
f71217706a Merge branch 'main' into aeisenberg/getting-started-docs 2022-01-24 11:16:13 -08:00
Rasmus Wriedt Larsen
301318020f Merge pull request #7455 from haby0/py/add-shutil-module-path-injection-sinks
Python: Add shutil module sinks for path injection query
2022-01-24 20:06:36 +01:00
Tom Hvitved
e3afcb1b06 C#: Add missing severity and update expected test output 2022-01-24 20:00:25 +01:00
Tom Hvitved
65e1c0ebc1 Merge remote-tracking branch 'upstream/main' into cs/hash-without-salt 2022-01-24 19:57:07 +01:00
Geoffrey White
e42d3e540a C++: Change note. 2022-01-24 18:32:17 +00:00
Geoffrey White
764f27f08e C++: Upgrade to path-problem. 2022-01-24 18:32:05 +00:00
Geoffrey White
bbaac556e2 C++: Reveal the FP to be an issue with dataflow / model of strcpy. 2022-01-24 17:53:37 +00:00
Geoffrey White
11929378c7 C++: Upgrade cpp/cleartext-storage-file to full taint flow. 2022-01-24 17:48:45 +00:00
Andrew Eisenberg
497c87851c Merge pull request #7571 from github/aeisenberg/remove-upgrades
Update docs on the output of `resolve qlpacks`
2022-01-24 09:02:02 -08:00
Erik Krogh Kristensen
75f389749a Merge pull request #7719 from erik-krogh/cwe-219
JS: add CWE-219 to js/exposure-of-private-files
2022-01-24 17:06:09 +01:00
Tom Hvitved
cc712c20cb Ruby: Use bitShiftLeft instead of pow in parseInteger 2022-01-24 16:06:35 +01:00
Erik Krogh Kristensen
bb786bc557 fix good/bad mixup in ClientExposedCookie qhelp 2022-01-24 15:34:30 +01:00
Tom Hvitved
6efa595478 Merge pull request #7688 from hvitved/dataflow/required-component-stack
Data flow: Restructure `RequiredSummaryComponentStack`
2022-01-24 15:10:08 +01:00
Tom Hvitved
2a972dc045 Address review comments 2022-01-24 14:27:42 +01:00
Tony Torralba
b59fd4070f Merge pull request #7136 from atorralba/atorralba/promote-insecure-trustmanager
Java: Promote Insecure TrustManager from experimental
2022-01-24 14:05:14 +01:00
Erik Krogh Kristensen
148b0c33a9 update the empty-password-in-config-file qhelp 2022-01-24 13:39:54 +01:00
Erik Krogh Kristensen
ab0d67a573 update query name and description
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-01-24 13:37:25 +01:00
Erik Krogh Kristensen
b2dc02b831 Merge pull request #7717 from erik-krogh/cwe-80
JS: add CWE-80 to queries that detect bad HTML sanitizers
2022-01-24 13:34:57 +01:00
Tom Hvitved
64f19637d4 Address review comments 2022-01-24 13:33:18 +01:00
Erik Krogh Kristensen
823cadecd5 add CWE-219 to js/exposure-of-private-files 2022-01-24 13:22:06 +01:00
Edoardo Pirovano
413c0a8f4f Merge pull request #7673 from github/post-release-prep/codeql-cli-2.7.6
Post-release preparation for codeql-cli-2.7.6
2022-01-24 11:59:51 +00:00
Mathias Vorreiter Pedersen
7db66055e5 C++: Add change note. 2022-01-24 11:57:25 +00:00
Mathias Vorreiter Pedersen
08379df613 C++: Add 'security' tag to 'cpp/return-stack-allocated-memory'. 2022-01-24 11:43:38 +00:00
Geoffrey White
4c99d39acf Merge pull request #7701 from MathiasVP/remove-intentional-get-stack-pointer
C++: Remove FPs from `cpp/return-stack-allocated-memory`
2022-01-24 11:39:10 +00:00
Arthur Baars
78b4d7cbb5 Ruby: remove redundant cast 2022-01-24 11:27:31 +01:00
Arthur Baars
0cef887683 Ruby: address comments 2022-01-24 11:27:26 +01:00
Geoffrey White
683f909f7a Merge pull request #7704 from geoffw0/clrtxt4
C++: Another improvement to cpp/cleartext-transmission
2022-01-24 10:11:11 +00:00
Erik Krogh Kristensen
ab1bc685bb add CWE-80 to queries that detect bad HTML sanitizers 2022-01-24 11:01:17 +01:00
Stephan Brandauer
02db472209 consistent notation 2022-01-24 10:58:06 +01:00
Anders Schack-Mulligen
7af6dc7164 Merge pull request #7702 from atorralba/atorralba/fix-jndi-injection-sinks
Java: Remove some JNDI Injection sinks
2022-01-24 10:53:58 +01:00
Stephan Brandauer
8be58fe01e Fix comment to avoid summarizing implementation
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2022-01-24 10:47:28 +01:00
Arthur Baars
5df1f7a0c3 Ruby: use CfgNodes classes to implement case value to pattern variable taint steps 2022-01-24 10:31:08 +01:00
Arthur Baars
7d7e9ba9e1 Ruby: add CasePattern classes to CfgNodes 2022-01-24 10:31:08 +01:00
Arthur Baars
e9a01f9e8f Ruby: fix test case 2022-01-24 10:31:08 +01:00
Arthur Baars
634c8cd060 Ruby: Generalize CfgNodes::ChildMapping 2022-01-24 10:31:08 +01:00
Arthur Baars
fcec8a8388 Address comments 2022-01-24 10:31:08 +01:00
Arthur Baars
ab4935fe68 Ruby: fix some alerts 2022-01-24 10:31:08 +01:00
Arthur Baars
7630b277b8 Ruby: update AST and CFG test data 2022-01-24 10:31:08 +01:00
Arthur Baars
26a0167d6d Ruby: add taint step test for hash patterns 2022-01-24 10:31:06 +01:00
Arthur Baars
49c452239e Ruby: add taint steps from case value to variables in patterns 2022-01-24 10:10:22 +01:00
Arthur Baars
77a3e4bd61 Ruby: CFG: fix completion of AsPattern variable 2022-01-24 10:10:22 +01:00
Stephan Brandauer
b277731312 add a predicate to recognize path arguments in calls to the fs-extra lib 2022-01-24 09:40:22 +01:00
Tony Torralba
908b7c43f2 Fix stubs 2022-01-24 09:34:43 +01:00
Anders Schack-Mulligen
9bd2ac96ea Merge pull request #7705 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-24 09:14:35 +01:00
Anders Schack-Mulligen
b4bf7a1561 Merge pull request #7698 from aschackmull/java/bitwise-assignop-guards
Java: Add support for bitwise compound assignments in Guards.
2022-01-24 09:11:53 +01:00
github-actions[bot]
020970ff4c Add changed framework coverage reports 2022-01-24 00:09:45 +00:00
Andrew Eisenberg
aee9eb5203 Apply docs fixes
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
2022-01-21 11:35:15 -08:00
Aditya Sharad
67e3f5edbc Merge pull request #7685 from adityasharad/merge/3.3-3.4
Merge rc/3.3 into rc/3.4
2022-01-21 10:49:19 -08:00
Tom Hvitved
85e1cda81b Ruby: Distinguish symbols from strings in ConstantValue 2022-01-21 19:16:12 +01:00
Harry Maclean
8e40899dfd Merge pull request #7419 from github/hmac/const-get 2022-01-22 07:01:09 +13:00
Harry Maclean
2fa18801aa Merge pull request #7665 from github/hmac/barrier-guard-array-const 2022-01-22 06:59:51 +13:00
Tony Torralba
78d7e538a5 Remove some JNDI Injection sinks
Add tests and stubs
2022-01-21 17:47:15 +01:00
Henry Mercer
c41de33156 Merge pull request #7700 from github/henrymercer/js-atm-fix-xss-results-pattern
JS: Fix copy/paste error in XSS ML-powered queries results patterns
2022-01-21 16:18:33 +00:00
Geoffrey White
0b98397e9b C++: Catch another encryption clue. 2022-01-21 16:16:16 +00:00
Geoffrey White
97447d0b3a C++: Expand tests. 2022-01-21 16:16:15 +00:00
Henry Mercer
84907f91f1 JS: Fix copy/paste error in XSS ML-powered queries results patterns
We didn’t catch this because our unit tests test only library code due
to the previous difficulty of running queries with an ML model (the ML
models in packs work should fix that), and because the end-to-end
evaluation runs separate queries that have different result patterns.

Going forward we should create unit tests for the queries themselves,
which will require using the ML model in tests. We should also be able
to catch this type of error using DCA.
2022-01-21 15:17:52 +00:00
Mathias Vorreiter Pedersen
48064c1c8f C++: Fix false positive. 2022-01-21 15:16:02 +00:00
Mathias Vorreiter Pedersen
7c8c2090f7 C++: Add real-world false positive from the 'cpp/return-stack-allocated-memory' query. 2022-01-21 15:14:18 +00:00
Mathias Vorreiter Pedersen
117795c409 Merge pull request #7682 from MathiasVP/rewrite-return-stack-allocated-memory-to-use-ir
C++: Use the IR for `cpp/return-stack-allocated-memory`.
2022-01-21 14:57:30 +00:00
yoff
a77a6ec864 Merge pull request #7684 from erik-krogh/patches
small refactorizations across CodeQL
2022-01-21 15:04:14 +01:00
Tom Hvitved
9d89cace95 Merge pull request #7643 from michaelnebel/csharp/struct-improvements
C#: Struct (and to a minor extent anonymous types) improvements
2022-01-21 14:51:26 +01:00
Anders Schack-Mulligen
5f7ee337cd Java: Use more set literal syntax. 2022-01-21 13:58:27 +01:00
Anders Schack-Mulligen
41d294229d Java: Add support for bitwise compound assignments in Guards. 2022-01-21 13:56:07 +01:00
Tony Torralba
1eaa379bb7 Merge pull request #7681 from atorralba/atorralba/improve-android-implicit-intents-query
Java: Improvements to the Android query Use of implicit PendingIntents
2022-01-21 13:46:17 +01:00
Tony Torralba
c7e1df5689 Update java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.qhelp
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-01-21 11:57:11 +01:00
Erik Krogh Kristensen
a235f8f023 remove redundant inline type casts 2022-01-21 11:46:33 +01:00
Erik Krogh Kristensen
b75c316c27 fix non-us spelling 2022-01-21 11:46:33 +01:00
Erik Krogh Kristensen
f500bccbe4 add explicit this to member call 2022-01-21 11:46:33 +01:00
Erik Krogh Kristensen
ddfc3bc00f use set literals instead of big disjunctions 2022-01-21 11:46:33 +01:00
Benjamin Muskalla
830c2dc90a Merge pull request #7603 from bmuskalla/commonsIoModel
Java: Replace Commons IO model
2022-01-21 11:42:27 +01:00
yoff
5b9ae9cede Merge pull request #7659 from RasmusWL/move-regex-injection-files
Python: Move regex injection configuration files
2022-01-21 11:42:06 +01:00
Tony Torralba
0846d1f7b6 Merge pull request #7691 from atorralba/atorralba/fix-recursion-entrypointfieldstep
Java: Fix recursion in `entrypointFieldStep`
2022-01-21 11:37:58 +01:00
Tony Torralba
3f6e035016 Docs improvements 2022-01-21 11:37:02 +01:00
yoff
4fd0ada9a8 Merge pull request #7652 from RasmusWL/cleartext-remove-fps
Python: Remove usernames as sensitive source for cleartext queries
2022-01-21 11:30:40 +01:00
Erik Krogh Kristensen
f9d5cbf017 update qhelp
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2022-01-21 11:26:58 +01:00
Tony Torralba
d22632ef78 Fix recursion in entrypointFieldStep
When using local taint tracking to define a RemoteFlowSource, a recursion was created because entrypointFieldStep adds new RemoteFlowSources and was a local taint step. This is fixed by converting entrypointFieldStep into a defaultAdditionalTaintStep instead of a localAdditionalTaintStep, i.e. it will only affect global taint tracking from now on.
2022-01-21 10:48:13 +01:00
Tom Hvitved
f9b906d1e2 C#: Update uses of RequiredSummaryComponentStack 2022-01-21 09:42:16 +01:00
Tom Hvitved
cba733136c Data flow: Sync 2022-01-21 09:42:16 +01:00
Tom Hvitved
f1a2b21e44 Data flow: Restructure RequiredSummaryComponentStack 2022-01-21 09:42:16 +01:00
Tom Hvitved
aa9cfebc65 Ruby: Replace getValueText with getConstantValue 2022-01-21 09:19:19 +01:00
CodeQL CI
b02f1c87a1 Merge pull request #7679 from erik-krogh/ql-doc-style
Approved by esbena
2022-01-20 23:43:44 -08:00
CodeQL CI
2287b6e549 Merge pull request #7675 from erik-krogh/move-url-sink-to-customizations
Approved by esbena
2022-01-20 23:43:15 -08:00
Aditya Sharad
ccc6291844 Merge rc/3.3 into rc/3.4
Conflicts in *-support.rst resolved in favour of rc/3.3, which has a new paragraph.
Enterprise version numbers updated to LGTM Enterprise 1.30 and CodeQL 2.7.6.
2022-01-20 15:49:10 -08:00
Erik Krogh Kristensen
15c1ce722a Merge pull request #7678 from erik-krogh/use-set
JS: use more set literals
2022-01-20 21:03:48 +01:00
shati-patel
8fc429caf4 Emphasize use case for installing pack deps 2022-01-20 19:03:30 +00:00
Mathias Vorreiter Pedersen
bd1720f797 C++: Add change note. 2022-01-20 18:27:09 +00:00
Mathias Vorreiter Pedersen
e689f6bad2 C++: Use the IR for 'cpp/return-stack-allocated-memory'. 2022-01-20 18:22:49 +00:00
Tom Hvitved
cbea5eaeaa C#: Simplify argument/parameter positions for captured variables 2022-01-20 17:08:12 +01:00
Tony Torralba
6fe0b78978 Remove PendingIntentAsField step and add SliceProviderLifecycle step 2022-01-20 16:52:07 +01:00
Andrew Eisenberg
534f8999b6 Update docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-01-20 07:09:34 -08:00
Erik Krogh Kristensen
2bffe56580 update expected output 2022-01-20 16:06:57 +01:00
Erik Krogh Kristensen
3155114e36 use more set literals 2022-01-20 16:06:34 +01:00
Anders Schack-Mulligen
fede7dd238 Merge pull request #7676 from aschackmull/java/instanceaccessnode
Java: Add data flow node encapsulating instance accesses.
2022-01-20 15:40:21 +01:00
Erik Krogh Kristensen
a77b2b0209 Merge pull request #7668 from erik-krogh/simplify-casts
simplify expressions that could be type-casts
2022-01-20 15:20:18 +01:00
Erik Krogh Kristensen
5780161b2c fix most issues found by ql/class-doc-style in JS 2022-01-20 15:10:16 +01:00
Alex Ford
9613ff743b Merge pull request #7611 from github/ruby/protect_from_forgery-without-exception
Ruby: flag up `protect_from_forgery` calls without an exception strategy
2022-01-20 13:45:30 +00:00
Tony Torralba
caab1c3332 Merge pull request #6963 from atorralba/atorralba/android-onactivityresult-source
Android: Add the Intent parameter of the `onActivityResult` method as a source
2022-01-20 14:27:30 +01:00
Tony Torralba
29e87b3abd Merge pull request #6975 from atorralba/atorralba/android-intent-uri-permission-manipulation
Java: CWE-266 - Query to detect Intent URI Permission Manipulation in Android applications
2022-01-20 14:27:02 +01:00
Geoffrey White
b230681bc8 Merge pull request #7650 from geoffw0/clrtxt3
C++: Improve cpp/cleartext-transmission
2022-01-20 13:21:54 +00:00
Rasmus Wriedt Larsen
f53dce3a83 Python: Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2022-01-20 14:20:15 +01:00
Anders Schack-Mulligen
43da5aabbe Java: Add dataflow node encapsulating instance accesses. 2022-01-20 14:12:33 +01:00
Erik Krogh Kristensen
7167e856fe move electron sink to the customizations file 2022-01-20 14:07:23 +01:00
github-actions[bot]
ab218421da Post-release preparation for codeql-cli-2.7.6 2022-01-20 12:59:20 +00:00
Tony Torralba
62f847a82e Apply suggestions from code review
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2022-01-20 13:44:10 +01:00
Tony Torralba
3957ebe880 Fix bitwiseLocalTaintStep 2022-01-20 13:34:32 +01:00
Tony Torralba
265f8a3b19 Make bitwise taintsteps specific for this query 2022-01-20 13:23:56 +01:00
Tony Torralba
4e9849e19d Refactor IntentFlagsOrDataCheckedGuard to avoid footgun 2022-01-20 13:23:55 +01:00
Tony Torralba
62c21918b2 Add QLDoc to guard and sanitizer 2022-01-20 13:23:54 +01:00
Tony Torralba
58a0bcd70f Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2022-01-20 13:23:53 +01:00
Tony Torralba
8767d2db23 Don't capitalize the term content provider
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2022-01-20 13:23:52 +01:00
Tony Torralba
596cfd399e Improve description 2022-01-20 13:23:52 +01:00
Tony Torralba
ab560234e3 Update java/change-notes/2021-10-27-android-intent-uri-permission-manipulation-query.md
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2022-01-20 13:23:51 +01:00
Tony Torralba
3405db31b8 Add qhelp 2022-01-20 13:23:51 +01:00
Tony Torralba
6152c8a989 Add change note 2022-01-20 13:23:48 +01:00
Tony Torralba
e1d30ebc09 Added severity
Removed duplicated code
2022-01-20 13:23:15 +01:00
Tony Torralba
ec8ffeed07 Add Intent URI Permission Manipulation query 2022-01-20 13:23:14 +01:00
Michael Nebel
e804922a2c C#: Add flow test case for with expressions on anonymous types. 2022-01-20 13:14:06 +01:00
Michael Nebel
97d9985e0b C#: Add support for flow via object initializer for anonymous types. 2022-01-20 13:12:19 +01:00
Tony Torralba
c09b6691e1 Merge pull request #6171 from atorralba/atorralba/promote-unsafe-certificate-trust
Java: Promote Unsafe certificate trust query from experimental
2022-01-20 12:07:03 +01:00
Felicity Chapman
e178626226 Merge pull request #7653 from github/felicitymay-patch-1
Port changes from main to rc/3.3 to avoid regression
2022-01-20 10:45:13 +00:00
Anders Schack-Mulligen
f154530141 Merge pull request #7662 from JLLeitschuh/patch-2
Fix typo in FileWritable
2022-01-20 11:13:59 +01:00
Benjamin Muskalla
8217873bae Align files with new naming pattern 2022-01-20 11:02:53 +01:00
Anders Schack-Mulligen
4aa2661dc1 Merge pull request #7634 from bmuskalla/refactorLangModel
Refactor Apache Commons Lang model
2022-01-20 11:01:25 +01:00
Benjamin Muskalla
4cac35adad Regnerate model to capture char[] APIs 2022-01-20 10:59:28 +01:00
Benjamin Muskalla
857c2778a6 Added missing model for ReadableByteChannel
This reveals more models for commons io
2022-01-20 10:59:28 +01:00
Benjamin Muskalla
b20b3ab480 Regenrate model to replace manual models 2022-01-20 10:59:27 +01:00
Benjamin Muskalla
93f6fde63c Keep not-yet-covered models 2022-01-20 10:59:27 +01:00
Benjamin Muskalla
d07997699f Introduce generated model for Commons IO 2022-01-20 10:59:24 +01:00
Geoffrey White
8bdbaf4b57 C++: Autoformat. 2022-01-20 09:52:24 +00:00
CodeQL CI
cfa670c123 Merge pull request #7651 from erik-krogh/CWE-471
Approved by asgerf, esbena
2022-01-20 01:47:39 -08:00
Tom Hvitved
a1cdf256ad Merge pull request #7667 from github/release-prep/2.7.6
Release preparation for version 2.7.6
2022-01-20 10:45:17 +01:00
Erik Krogh Kristensen
4e8e3a7420 simplify expressions that could be type-casts 2022-01-20 10:41:35 +01:00
Benjamin Muskalla
2748bbffa3 Merge pull request #7656 from bmuskalla/excludeMainLoggingGenerator
Java: Exclude irrelevant rows from models
2022-01-20 10:40:51 +01:00
Tony Torralba
967308fbfd Change InsecureTrustManagerConfiguration to DataFlow 2022-01-20 10:24:47 +01:00
mc
c105d71952 Update InsecureTrustManager.qhelp
Fixed typos and carried out and editorial review
2022-01-20 10:24:46 +01:00
Tony Torralba
7a1a45f5f9 QLDoc 2022-01-20 10:24:46 +01:00
Tony Torralba
77c2b43560 Add change note and severity score 2022-01-20 10:24:43 +01:00
Michael Nebel
76a0853f5b C#: Add struct declaration and update line numbers for the existing test cases. 2022-01-20 10:23:57 +01:00
Tony Torralba
d58bb4753e Refactor tests 2022-01-20 10:23:19 +01:00
Tony Torralba
ab4dc30f54 Refactor into libraries 2022-01-20 10:23:18 +01:00
Tony Torralba
7cd05fb685 Move from experimental 2022-01-20 10:23:18 +01:00
Michael Nebel
7d7ab58108 C#: Add flow test for record struct fields. 2022-01-20 09:58:02 +01:00
Michael Nebel
210bad6c29 C#: Add test case for with expressions for record structs, structs and anonymous types. 2022-01-20 09:58:02 +01:00
Michael Nebel
fc7f642734 C#: With expression examples for record structs, structs and anonymous types. 2022-01-20 09:58:02 +01:00
Michael Nebel
858aec3839 C#: Add test for source of the struct parameterless constructor(s). 2022-01-20 09:58:02 +01:00
Michael Nebel
073d2f2c75 C#: Add some example struct types, including one with a default constructor declarations. 2022-01-20 09:58:01 +01:00
Michael Nebel
547f492be0 Merge pull request #7577 from michaelnebel/csharp/line-pragma
C#: Make support for Line span pragma
2022-01-20 09:51:57 +01:00
github-actions[bot]
4ce8ccc52b Release preparation for version 2.7.6 2022-01-20 08:21:18 +00:00
Harry Maclean
6bae03a7cc Ruby: Update string const barrier guard
This change recognises guards like `FOO.include?`, where `FOO` is an array
constant.
2022-01-20 17:34:12 +13:00
Harry Maclean
13a0ece25c Ruby: Add test case: array constant barrier guard
This guard isn't yet recognised as a `StringConstArrayInclusionCall`.
2022-01-20 17:07:01 +13:00
Andrew Eisenberg
95355b5854 Docs: Add back removed section on getting started
Adds a second getting started, specifically for checking out the
codeql repo as a way to get the core queries.

This ensures that people wanting to work in the traditional way still
have the old docs available.
2022-01-19 13:36:57 -08:00
Jonathan Leitschuh
23548c50e1 Fix typo in FileWritable 2022-01-19 16:14:38 -05:00
Tom Hvitved
70f4efb834 Merge pull request #7646 from hvitved/csharp/roslyn-tuple-elements-workaround
C#: Workaround Roslyn bug in `INamedTypeSymbol.TupleElements`
2022-01-19 19:54:29 +01:00
Tom Hvitved
128682b59e C#: Replace Argument[-1] with Argument[Qualifier] in all flow summaries 2022-01-19 18:54:24 +01:00
shati-patel
dc71ecef83 Docs: Mention packaging commands in CodeQL extension 2022-01-19 16:36:01 +00:00
Rasmus Wriedt Larsen
b9ee2960e2 Python: Add change-note 2022-01-19 17:24:53 +01:00
Rasmus Wriedt Larsen
aa10ad6a8a Python: Fix RegexInjection query, add old deprecated versions 2022-01-19 17:22:44 +01:00
Rasmus Wriedt Larsen
e82ea7ad17 Python: move regex injection configuration files
I did not notice that these went to the wrong location in
https://github.com/github/codeql/pull/6693. They should be in the
dataflow folder with the rest of the data-flow configurations files, the
injection folder is for old points-to based modeling.
2022-01-19 17:21:46 +01:00
Tom Hvitved
0990a1b404 C#: Get rid of negative parameter/argument data-flow positions 2022-01-19 17:14:37 +01:00
Tony Torralba
695e77a219 Simplify isSslSocket predicate 2022-01-19 17:01:28 +01:00
Mathias Vorreiter Pedersen
40c8881575 Merge pull request #7472 from erik-krogh/redundant-aggregate
QL-for-QL: Add a could-be-cast query
2022-01-19 15:48:00 +00:00
Henry Mercer
58b1a6fd40 Merge pull request #7655 from github/henrymercer/bump-atm-query-pack-v0.0.6
JS: Bump ML-powered query packs to v0.0.6
2022-01-19 15:44:55 +00:00
Tony Torralba
e442e50e6b Apply suggestions from code review
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2022-01-19 16:43:48 +01:00
Tony Torralba
101ad777e3 Move things around after rebase 2022-01-19 16:43:48 +01:00
Tony Torralba
03020582af Apply suggestions from code review
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2022-01-19 16:43:47 +01:00
Tony Torralba
9ffc5ab183 Update java/ql/src/semmle/code/java/security/UnsafeCertTrustQuery.qll
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2022-01-19 16:43:47 +01:00
Tony Torralba
c16181dd2f QLDocs 2022-01-19 16:43:46 +01:00
Tony Torralba
000a544729 Decouple UnsafeCertTrust.qll to reuse the taint tracking configuration 2022-01-19 16:43:43 +01:00
Tony Torralba
1e2a956a30 Remove unused stub 2022-01-19 16:43:02 +01:00
Tony Torralba
d9e98ceacc Consider setSslContextFactory and fix tests 2022-01-19 16:43:01 +01:00
Tony Torralba
4d207101e2 Fix QLDoc 2022-01-19 16:43:00 +01:00
Tony Torralba
999acb0021 Improve qhelp references 2022-01-19 16:43:00 +01:00
Tony Torralba
e9712f04a4 Add missing QLDoc 2022-01-19 16:42:59 +01:00
Tony Torralba
698fd64f7f Adjust test after rebase 2022-01-19 16:42:59 +01:00
Tony Torralba
68fe3dd9f4 Fix conflicts in experimental query 2022-01-19 16:42:58 +01:00
Tony Torralba
c24520cb75 Adjust qhelp after rebase 2022-01-19 16:42:58 +01:00
Tony Torralba
5997b874de Add change note 2022-01-19 16:42:53 +01:00
Tony Torralba
9e93aecf75 Add spurious test case 2022-01-19 16:42:06 +01:00
Tony Torralba
19d1a780ca Generalize sanitizer using local flow 2022-01-19 16:42:05 +01:00
Tony Torralba
64518bf91a Handle a specific pass-by-reference flow issue 2022-01-19 16:42:04 +01:00
Tony Torralba
4508945f85 Fix assumption regarding when an SSLSocket does the TLS handhsake 2022-01-19 16:42:03 +01:00
Tony Torralba
e842acf9e0 Improve qhelp 2022-01-19 16:42:03 +01:00
Tony Torralba
5d4cd70f8c Adjusted sources and sanitizer of UnsafeCertTrust taint tracking config 2022-01-19 16:42:02 +01:00
Tony Torralba
e43fff2d30 Use InlineExpectationsTest 2022-01-19 16:42:02 +01:00
Tony Torralba
02d0fa9188 Minor changes in QLDocs and a sanitizer's type 2022-01-19 16:42:01 +01:00
Tony Torralba
4313baf622 Big refactor:
- Move classes and predicates to appropriate libraries
- Overhaul the endpoint identification algorithm logic to use taint tracking
- Adapt tests
2022-01-19 16:42:00 +01:00
Tony Torralba
e0f4c73aed Move from experimental 2022-01-19 16:42:00 +01:00
Tony Torralba
6096080156 Use all possible packages for Fragment classes
Also fix stub
2022-01-19 16:23:11 +01:00
Benjamin Muskalla
52406dc8df Exclude logging sinks
Those sinks are too coarse grained to be exposed as sinks on any model.
2022-01-19 16:11:59 +01:00
Benjamin Muskalla
25d251c24f Exclude main methods from models 2022-01-19 16:11:59 +01:00
Tony Torralba
3c9fac0c6e Sync DataFlowImplForOnActivityResult.qll 2022-01-19 16:11:51 +01:00
Tony Torralba
6a4d2ee850 Apply code review suggestions 2022-01-19 16:08:31 +01:00
Tony Torralba
57ff13dd19 Sync DataFlowImplForOnActivityResult to latest changes 2022-01-19 16:08:31 +01:00
Tony Torralba
ea4ff80cc6 Add DataFlowImplForOnActivityResult to identical-files.json 2022-01-19 16:08:31 +01:00
Tony Torralba
37916a8368 Fix previous merge 2022-01-19 16:08:31 +01:00
Tony Torralba
d9d9ad7d63 Use dedicated instance of DataFlow 2022-01-19 16:08:31 +01:00
Tony Torralba
aef63f69b0 Formatting 2022-01-19 16:08:30 +01:00
Tony Torralba
4b3029564c Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2022-01-19 16:08:29 +01:00
Tony Torralba
c675028537 Add Fragment and Activity edge case 2022-01-19 16:08:28 +01:00
Tony Torralba
9ae1f1cf85 QLDoc 2022-01-19 16:08:27 +01:00
Tony Torralba
211cb9370f Add the Intent parameter of onActivityResult as a source 2022-01-19 16:08:25 +01:00
Tony Torralba
520d8f5ec5 Add stubs 2022-01-19 16:06:23 +01:00
Tom Hvitved
7e3f3c6e2a Merge pull request #7515 from hvitved/csharp/extraction-mode
C#: Introduce extractor mode to identify DBs created with `codeql test run`
2022-01-19 16:04:57 +01:00
Chris Smowton
162b3822dd Merge pull request #7613 from github/smowton/admin/tag-random-used-once
Remove security-severity tag to java/random-used-once
2022-01-19 14:43:08 +00:00
Henry Mercer
c134e6c9ef JS: Bump ML-powered query packs to v0.0.6 2022-01-19 14:40:42 +00:00
Felicity Chapman
51e8b4c7ed Port changes from main to rc/3.3 to avoid regression 2022-01-19 14:26:52 +00:00
Rasmus Wriedt Larsen
e82e648ca1 Python: Remove usernames as sensitive source for cleartext queries
Closes #6363, #6927, #6726, #7497, #7116
2022-01-19 15:25:21 +01:00
Chris Smowton
c63fcb2c69 Add change note 2022-01-19 14:13:45 +00:00
Rasmus Wriedt Larsen
f3daff4e5a Python: Add FP tests for cleartext logging 2022-01-19 15:13:06 +01:00
Chris Smowton
f0645a34b9 Remove security-severity tag instead
This leaves the Java query in the same state as its C# cousin.
2022-01-19 14:06:40 +00:00
Erik Krogh Kristensen
cb9e14f544 add cwe-471 to js/prototype-pollution 2022-01-19 14:54:57 +01:00
Alex Ford
0aab670b17 Ruby: add missing example rails action 2022-01-19 13:47:00 +00:00
Tom Hvitved
cb098df4ea Merge pull request #7334 from github/hmac/regexp-interpolations
Ruby: Resolve simple string interpolations
2022-01-19 14:43:58 +01:00
Alex Ford
45ed5a806c Ruby: changenote for rb/csrf-protection-disabled enhancement 2022-01-19 13:41:00 +00:00
Alex Ford
b27d315ff4 Ruby: add an example of protect_from_forgery with: :exception 2022-01-19 13:30:27 +00:00
Mathias Vorreiter Pedersen
dfbde23821 Merge pull request #7627 from geoffw0/nullterm5
C++: Fix branch related FPs in cpp/improper-null-termination.
2022-01-19 13:30:05 +00:00
Erik Krogh Kristensen
e4203a4109 add CWE-471 to the prototype-pollution queries 2022-01-19 14:26:34 +01:00
Tom Hvitved
dacb33d1dd C#: Adjust Roslyn workaround 2022-01-19 14:12:21 +01:00
Geoffrey White
0230494799 C++: Expand QLDoc comment. 2022-01-19 13:07:55 +00:00
Henry Mercer
061b9badfe Merge pull request #7649 from github/henrymercer/bump-atm-query-pack-v0.0.5
JS: Bump ML-powered query packs to v0.0.5
2022-01-19 13:00:41 +00:00
Geoffrey White
acfd593eb4 C++: Change note. 2022-01-19 13:00:36 +00:00
Geoffrey White
330b4c3704 C++: Generalize hasSocketInput a little to include fgets and friends. 2022-01-19 13:00:35 +00:00
Geoffrey White
9c2d961ae5 C++: Fix another expression of stdin / stdout we see in practice. 2022-01-19 13:00:34 +00:00
Michael Nebel
d7cd1cf0b9 C#: Address review comments. 2022-01-19 13:50:02 +01:00
Tom Hvitved
4f90b45dd7 C#: Address review comments 2022-01-19 13:46:22 +01:00
Tom Hvitved
c8509cc382 C#: Introduce extractor mode to identify DBs created with codeql test run 2022-01-19 13:46:22 +01:00
Geoffrey White
d77ba020f9 C++: Support more routines as proof-of-encryption in cpp/cleartext-transmission. 2022-01-19 12:40:32 +00:00
Geoffrey White
974a8b1a9a C++: Add a test case. 2022-01-19 12:33:21 +00:00
Henry Mercer
d467725ccd JS: Bump ML-powered query packs to v0.0.5 2022-01-19 12:08:33 +00:00
Michael Nebel
3df30545d3 Merge pull request #7628 from michaelnebel/csharp/issue-7609
C#: Fix false positive alert for shadowing on record types.
2022-01-19 12:24:57 +01:00
Tom Hvitved
71ddd00a6c C#: Workaround Roslyn bug in INamedTypeSymbol.TupleElements 2022-01-19 11:33:03 +01:00
Michael Nebel
edafdc8fde C#: Added change note. 2022-01-19 11:04:53 +01:00
Michael Nebel
194da454b1 C#: Add record deconstruct method as an exception from the bad practice rule. 2022-01-19 11:04:53 +01:00
Michael Nebel
2eea6ca5fd C#: Example record type with autogenerated Deconstruct method. 2022-01-19 11:04:53 +01:00
Mathias Vorreiter Pedersen
bdfde88e99 Merge pull request #7630 from JarLob/patch-2
C++: Reduce FPs in IncorrectPrivilegeAssignment.ql
2022-01-19 09:49:43 +00:00
Erik Krogh Kristensen
ef2eacebce add a js/empty-password-in-configuration-file query 2022-01-19 10:48:45 +01:00
Michael Nebel
55f787bcae Merge pull request #7605 from michaelnebel/csharp/record-struct
C#: Support for record structs
2022-01-19 10:39:52 +01:00
Harry Maclean
994fcf54b5 Merge pull request #7126 from jeffgran/jg/graphql-ruby
Ruby: Add support for GraphQL
2022-01-19 22:19:30 +13:00
Harry Maclean
08d48b9375 Add top-level doc comment to GraphQL.qll 2022-01-19 21:42:46 +13:00
Tony Torralba
b2c7175ac5 Merge pull request #7641 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-19 09:34:01 +01:00
Tom Hvitved
f02aeafef1 Ruby: Move regex/non-regex split into TAstNode to convey disjointness 2022-01-19 09:22:01 +01:00
github-actions[bot]
f7240be136 Add changed framework coverage reports 2022-01-19 00:09:52 +00:00
Jaroslav Lobačevski
a1b0315d90 Update cpp/ql/src/experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql 2022-01-19 00:52:10 +01:00
Andrew Eisenberg
01b5881de6 Docs: Remove reference to checking out main branch
We are no longer including information about how to check out
github/codeql, so this paragraph doesn't fit any more.
2022-01-18 15:48:33 -08:00
Andrew Eisenberg
0cd6556964 Docs: Update analyzing databases docs
Add more information about running packs. Include the `--download` flag.
2022-01-18 15:03:08 -08:00
Andrew Eisenberg
7fcf567eda Docs: Simplify getting started docs
It is no longer necessary to check out a version of `github/codeql` as
a sibling directory to the distribution. Instead, users can download
the required packs as needed. using the `pack download` command or
the `--download` option for `codeql database analyze`.
2022-01-18 15:03:08 -08:00
Harry Maclean
4f7f92490a Distinguish regex components from strings
Create a set of classes for components of regex literals,
separate from those of string literals. This allows us to special-case
components of free-spacing regexes (ones with the /x flag) to not have a
`getValueText()`.

This in turn is useful because our regex parser can't handle free-spacing
regexes, so excluding them ensures that we don't generate erroneous
ReDoS alerts.
2022-01-19 11:23:40 +13:00
Jaroslav Lobačevski
3fa2516898 Update cpp/ql/src/experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql 2022-01-18 21:47:55 +01:00
Jaroslav Lobačevski
d1c89562b8 Apply suggestions from code review 2022-01-18 21:45:13 +01:00
Chris Smowton
84097468cc Merge pull request #7286 from luchua-bc/java/unsafe-url-forward-dispatch
Java: CWE-552 Query to detect unsafe request dispatcher usage
2022-01-18 18:19:20 +00:00
Henry Mercer
63672ca394 Merge pull request #7616 from github/henrymercer/js-atm-add-query-help
JS: Add query help for ML-powered queries
2022-01-18 18:11:53 +00:00
Chris Smowton
1e32514600 Avoid using this for a non-extending supertype, and remove needless casts 2022-01-18 17:20:40 +00:00
Benjamin Muskalla
9e91b805d6 Sort Lang3 models 2022-01-18 18:10:37 +01:00
Benjamin Muskalla
e6800c877c Merge Lang3 rows 2022-01-18 18:10:37 +01:00
Benjamin Muskalla
736e68820c Split out Lang3 models 2022-01-18 18:10:37 +01:00
Benjamin Muskalla
67b60dcf78 Sort Lang2 rows 2022-01-18 18:10:36 +01:00
Benjamin Muskalla
82bda6d573 Merge Lang2 summary models 2022-01-18 18:10:36 +01:00
Benjamin Muskalla
8eb6743586 Split out Lang2 rows 2022-01-18 18:10:33 +01:00
Chris Smowton
d744cf9053 Clean up guard logic:
* Always sanitize after the second guard, not the first
* Only check basic-block dominance in one place
* One BarrierGuard extension per final guard
2022-01-18 17:10:06 +00:00
Chris Smowton
748008ad51 Remove dangling reference to UnsafeRequestPath.java 2022-01-18 17:08:38 +00:00
luchua-bc
a3d65a8ed0 Update recommendation in qldoc and make examples more comprehendible 2022-01-18 17:01:26 +00:00
Geoffrey White
982fb8f73a C++: Add change note. 2022-01-18 16:38:44 +00:00
Robert Marsh
024bd27485 Merge pull request #7578 from MathiasVP/store-dest-should-not-be-use
C++: Store destinations should not be uses for dataflow SSA
2022-01-18 11:36:15 -05:00
Jeff Gran
47697f59c1 Ruby: Add classes for detecting user input from graphql-ruby 2022-01-18 09:13:58 -07:00
CodeQL CI
1912c56f82 Merge pull request #7631 from RasmusWL/sqlalchemy-scoped-session
Approved by tausbn
2022-01-18 14:31:49 +00:00
Rasmus Wriedt Larsen
95e935e9c1 Python: Support SQLAlchemy scoped_session 2022-01-18 14:34:31 +01:00
Erik Krogh Kristensen
30d896bdbb QL: make the alert-message more precise when the type-cast is also redundant 2022-01-18 14:25:43 +01:00
Jaroslav Lobačevski
92f5a5f893 Reduce FPs in IncorrectPrivilegeAssignment.ql
Implements suggestions from https://github.com/github/codeql/pull/6949#issuecomment-976482965
2022-01-18 13:43:17 +01:00
Erik Krogh Kristensen
14d2f5fe02 QL: add a new ql/could-be-cast query 2022-01-18 13:37:32 +01:00
Erik Krogh Kristensen
a1f4c85dea QL: update expected output for the printAst test 2022-01-18 13:37:04 +01:00
Erik Krogh Kristensen
1ec868eeae QL: various improvements to Ast.qll 2022-01-18 13:23:33 +01:00
Erik Krogh Kristensen
95ae113994 QL: downgrade redundant-inline-cast to a warning query 2022-01-18 13:22:01 +01:00
Erik Krogh Kristensen
ea7945bac1 QL: show recommendation queries by default, and remove the MissingQLDoc query 2022-01-18 13:21:07 +01:00
Henry Mercer
be0c26f83d Merge pull request #7617 from github/henrymercer/js-atm-update-alert-messages
JS: Update alert messages for ML-powered queries
2022-01-18 11:37:02 +00:00
Mathias Vorreiter Pedersen
cb0cc8d859 Merge pull request #7625 from geoffw0/nullterm4
C++: Fix some code duplication.
2022-01-18 11:18:06 +00:00
Tony Torralba
b16b0270d2 Merge pull request #6779 from atorralba/atorralba/android-implicit-pending-intents
Java: CWE-927 - Query to detect the use of implicit PendingIntents
2022-01-18 12:14:47 +01:00
Geoffrey White
548a62d1ab C++: Fix branch related FPs in cpp/improper-null-termination. 2022-01-18 11:13:08 +00:00
Felicity Chapman
c3ed74d63c Merge pull request #7604 from github/lgtm-1.29-docs
Update version numbers in CodeQL support notes for LGTM 1.29
2022-01-18 11:09:38 +00:00
Chris Smowton
9819752bdd Merge pull request #7526 from smowton/smowton/fix/restore-nodes-edges-consistency
Don't include arg -> param edges in PathGraph::edges where arg is not reachable
2022-01-18 11:05:47 +00:00
Benjamin Muskalla
7e215a5193 Merge pull request #7599 from bmuskalla/modelWriter
Java: Model Appenable and Writer
2022-01-18 11:55:27 +01:00
Henry Mercer
1893b9f7a9 Merge pull request #7376 from github/henrymercer/js-atm-absent-features-optimization
JS: Update featurization for absent features optimization
2022-01-18 10:15:53 +00:00
Tony Torralba
f103d45340 Merge branch 'main' into atorralba/android-implicit-pending-intents 2022-01-18 10:50:49 +01:00
Mathias Vorreiter Pedersen
e1598aba5e C++: Fix spelling. 2022-01-18 09:44:36 +00:00
Tony Torralba
3ff7710a18 Improve ExplicitIntent's QLDoc 2022-01-18 10:43:52 +01:00
Tony Torralba
fe2755c4a0 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2022-01-18 10:41:19 +01:00
Benjamin Muskalla
365a8d9bbd Fix flow for fluent appendable api 2022-01-18 10:41:00 +01:00
Benjamin Muskalla
8e6a15640f Model basic channel APIs 2022-01-18 10:40:39 +01:00
Anders Schack-Mulligen
fff3b5c5b4 Dataflow: Add qldoc. 2022-01-18 10:39:55 +01:00
Anders Schack-Mulligen
9479301485 Ruby: Accept qltest expected changes. 2022-01-18 10:36:52 +01:00
Anders Schack-Mulligen
5cfa3c7927 C++: Accept qltest expected changes. 2022-01-18 10:36:52 +01:00
Anders Schack-Mulligen
7b98ca9b0a C#: Adjust qltest expected output. 2022-01-18 10:36:52 +01:00
Anders Schack-Mulligen
aa9912a699 Java: Fix expected output 2022-01-18 10:36:52 +01:00
Anders Schack-Mulligen
71e39353ca Dataflow: Sync. 2022-01-18 10:36:52 +01:00
Anders Schack-Mulligen
b22c4e3c56 Dataflow: Bugfix: include subpaths ending at a sink. 2022-01-18 10:34:14 +01:00
Chris Smowton
f7d3892320 Update test expectations 2022-01-18 10:30:09 +01:00
Anders Schack-Mulligen
dfa79f6119 Dataflow: Sync. 2022-01-18 10:30:09 +01:00
Anders Schack-Mulligen
46736a137c Dataflow: Don't include subpaths that can't reach a sink. 2022-01-18 10:30:09 +01:00
Chris Smowton
2c37885f6e Sync dataflow 2022-01-18 10:30:09 +01:00
Chris Smowton
7c9b44b4cb Don't include arg -> param edges in PathGraph::edges whose arg is not reachable
This avoids lots of missing-node warnings from `codeql bqrs interpret` as it discards the nodes that occur in the `edges` relation but not `nodes`. The problem arises because subpaths introduced two variants of `reach`, one of which is more restrictive than simply `reach(succ) and succ = pred.getASuccessor()`, so it no longer suffices to just check that the successor is reachable.
2022-01-18 10:30:09 +01:00
Michael Nebel
de3d62b3f4 C#: Update stats file for the new relations (they are unfortunately empty). 2022-01-18 09:33:40 +01:00
Michael Nebel
bf21026771 C#: Add downgrade scripts for the line span pragma. 2022-01-18 09:32:14 +01:00
Michael Nebel
8fd116fbd7 C#: Add upgrade scripts for the new tables requires for the line span pragma. 2022-01-18 09:32:14 +01:00
Michael Nebel
ac47c96f48 C#: Add Line span pragma test case. 2022-01-18 09:32:14 +01:00
Michael Nebel
8b048ca17e C#: Add line span pragma example. 2022-01-18 09:32:14 +01:00
Michael Nebel
93255dfe13 C#: Add QL library support for the Line span directive. 2022-01-18 09:32:14 +01:00
Michael Nebel
7e264668d8 C#: Refator directive visitor to use expression body. 2022-01-18 09:32:14 +01:00
Michael Nebel
af380f846e C#: Add support in the extractor for the LineSpanDirective. 2022-01-18 09:32:14 +01:00
Michael Nebel
195d40c04e C#: Add new class needed for LineSpanDirective and modify existing implementation to use the new types. 2022-01-18 09:32:14 +01:00
Michael Nebel
a197befb5f C#: Add shared base class for line and line span pragmas. 2022-01-18 09:32:14 +01:00
Michael Nebel
c9467d7e94 C#: Add new tables to the dbscheme line span pragma. 2022-01-18 09:32:14 +01:00
Anders Schack-Mulligen
c41ec1f8ec Merge pull request #7619 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-18 09:17:40 +01:00
github-actions[bot]
b8959f7bdb Add changed framework coverage reports 2022-01-18 00:10:52 +00:00
Alex Ford
c1a51d94a2 Ruby: add test for protect_from_forgery without exception strategy 2022-01-17 17:44:52 +00:00
Erik Krogh Kristensen
d63f4bfd94 Merge pull request #7615 from erik-krogh/super-charpred
QL: support this.method() calls in the charpred that references non-extending supertypes
2022-01-17 18:32:10 +01:00
Felicity Chapman
e0110bd25e FIx typo in new note 2022-01-17 17:20:00 +00:00
Henry Mercer
ffa4135cbe JS: Update alert messages for ML-powered queries 2022-01-17 17:19:49 +00:00
Erik Krogh Kristensen
a4cfb80b81 QL: update comment 2022-01-17 17:19:15 +00:00
Felicity Chapman
e7dde79d50 Add note and link to main CodeQL CLI docs 2022-01-17 17:14:58 +00:00
Erik Krogh Kristensen
85c273a413 QL: support this.method() calls in the charpred that references non-extending supertypes 2022-01-17 17:42:35 +01:00
Henry Mercer
e9128466d4 JS: Add query help for ML-powered queries
Query help is identical to the original query, except for a new
paragraph prepended to the overview explaining that the queries are
experimental.

We add Markdown query help since only Markdown query help is embedded in
SARIF via `--sarif-add-query-help`.
2022-01-17 16:34:50 +00:00
Henry Mercer
568d37e9b9 JS: Update definition of ATM query suite
It's simpler to just run all the queries in the pack instead of
specifying the IDs.
2022-01-17 16:34:50 +00:00
Geoffrey White
d475101286 C++: Fix some code duplication. 2022-01-17 16:26:22 +00:00
Owen Mansel-Chan
065043b311 Merge pull request #7588 from owen-mc/add-specific-needs-reference-predicates
Dataflow: Add language-specific NeedsReference predicates
2022-01-17 15:51:34 +00:00
Michael Nebel
b927aad6ed C#: Address review comments related to record structs. 2022-01-17 16:16:18 +01:00
Michael Nebel
6c1bb4a3a9 C#: Add test case for record class and record structs. 2022-01-17 16:16:18 +01:00
Michael Nebel
746fd603d8 C#: Add flow summary test for record struct constructors. 2022-01-17 16:16:18 +01:00
Michael Nebel
9770f09839 C#: Deprecate Record and introduce RecordClass instead. Also make flow summary support for record struct constructors. 2022-01-17 16:16:18 +01:00
Michael Nebel
55cb2aa160 C#: Use modifier to decide, if a type is a record like type and implement support for record struct types. 2022-01-17 16:16:18 +01:00
Michael Nebel
dc76775d07 C#: Consider 'record' a type modifier in the extractor (it can be applied to both class and struct). 2022-01-17 16:16:18 +01:00
Michael Nebel
c17bd29640 C#: Rename C# code file and update test. 2022-01-17 16:16:18 +01:00
Tony Torralba
e967b8a9be Merge pull request #6576 from atorralba/atorralba/android-cleartext-storage-filesystem
Java: Create new query Cleartext storage of sensitive information in Android filesystem
2022-01-17 14:02:38 +01:00
Tony Torralba
227929508f Merge pull request #6923 from atorralba/atorralba/android-fragment-injection
Java: CWE-470  - Queries to detect Fragment Injection in Android applications
2022-01-17 14:02:15 +01:00
Tom Hvitved
3c837c322b Merge pull request #7514 from github/post-release-prep/codeql-cli-2.7.5
Post-release preparation for codeql-cli-2.7.5
2022-01-17 12:40:33 +01:00
Tony Torralba
7beab7cb59 Apply code review suggestions 2022-01-17 12:02:27 +01:00
Mathias Vorreiter Pedersen
78642aaae2 Merge pull request #7593 from MathiasVP/fix-join-order-in-get-conversion-type
C++: Fix join order in 'getConversionType4'
2022-01-17 11:01:08 +00:00
Chris Smowton
16aa53a928 Add security tag to java/random-used-once
Raised in https://github.com/github/codeql/issues/7601, this is one of the only .ql files that has a security-severity score but not the tag "security", including many other queries that live outside the `Security/` subdirectory.

Besides this the only other files with this security-severity-but-no-security-tag combination are:

```
java/ql/src/Frameworks/JavaEE/EJB/EjbContainerInterference.ql
java/ql/src/Frameworks/JavaEE/EJB/EjbFileIO.ql
java/ql/src/Frameworks/JavaEE/EJB/EjbNative.ql
java/ql/src/Frameworks/JavaEE/EJB/EjbReflection.ql
java/ql/src/Frameworks/JavaEE/EJB/EjbSecurityConfiguration.ql
java/ql/src/Frameworks/JavaEE/EJB/EjbSerialization.ql
java/ql/src/Frameworks/JavaEE/EJB/EjbSetSocketOrUrlFactory.ql
```

Given their location I'm assuming these queries are disabled by default and likely shouldn't changed?
2022-01-17 10:35:34 +00:00
Tony Torralba
a23b8a4a43 Update java/ql/src/Security/CWE/CWE-470/FragmentInjection.inc.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2022-01-17 11:20:39 +01:00
Tony Torralba
ba3a4fb717 Rename filesystemStore predicate after d9e6e5aa04 2022-01-17 11:13:41 +01:00
Tony Torralba
500deac12d Change query description 2022-01-17 11:11:05 +01:00
Tony Torralba
d9e6e5aa04 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2022-01-17 11:11:05 +01:00
Tony Torralba
22aad17d0e Apply review suggestions
Co-authored-by: Ethan Palm <56270045+ethanpalm@users.noreply.github.com>
2022-01-17 11:11:04 +01:00
Tony Torralba
9bbba3c96f Adjust UnsupportedExternalAPIs test 2022-01-17 11:11:04 +01:00
Tony Torralba
1e4840e071 Fix predicate name 2022-01-17 11:11:03 +01:00
Tony Torralba
79ddbd6fe4 Fix QLDoc and the qhelp example 2022-01-17 11:11:03 +01:00
Tony Torralba
c1ac09a063 Added query for Cleartext Storage in Android Filesystem 2022-01-17 11:11:00 +01:00
Paolo Tranquilli
6a53b7b233 Merge pull request #7543 from github/rdmarsh2/cpp/hex-format-range-analysis
C++: Use range analysis for maximum lengths of `%x` formats
2022-01-17 08:32:34 +01:00
Alex Ford
d09f48ecb4 Ruby: flag up protect_from_forgery calls without an exception strategy 2022-01-16 20:56:13 +00:00
luchua-bc
4797fce48a Update use cases and qldoc 2022-01-16 01:15:29 +00:00
luchua-bc
978ef1570a Update method names 2022-01-16 01:11:25 +00:00
Tom Hvitved
2ecf0d3264 Merge pull request #7550 from michaelnebel/csharp/global-using
C#: Support for identifying whether a using directive is "global".
2022-01-14 20:03:18 +01:00
Robert Marsh
5df6bcf952 C++: change note for hex format range analysis 2022-01-14 13:18:58 -05:00
Dave Bartolomeo
bce2a810a3 Merge pull request #7400 from github/dbartol/change-note-instructions
Add instructions for creating change notes.
2022-01-14 13:10:44 -05:00
Robert Marsh
9de63b2812 Merge branch 'main' into rdmarsh2/cpp/hex-format-range-analysis
Accept test changes from query split
2022-01-14 12:53:52 -05:00
Andrew Eisenberg
fbb5d7196f Merge branch 'main' into post-release-prep/codeql-cli-2.7.5 2022-01-14 08:23:43 -08:00
Tony Torralba
a2c98baf29 Reordering 2022-01-14 17:17:57 +01:00
Tony Torralba
eb1806c0a9 Split PathMatchGuard into three guards 2022-01-14 17:14:18 +01:00
Ian Lynagh
bba8e45e74 Merge pull request #7602 from igfoo/igfoo/typos
Fix a couple of typos: clases / clasess
2022-01-14 15:56:04 +00:00
Henry Mercer
ed28b7f174 Merge pull request #7575 from github/henrymercer/atm-remove-code-to-features
JS: Remove ATM `CodeToFeatures` library
2022-01-14 15:31:34 +00:00
Michael Nebel
e09009cd8e Merge pull request #7118 from michaelnebel/csharp-primary-ql-class
C#: PrimaryQlClass
2022-01-14 16:14:28 +01:00
Felicity Chapman
fdf77ad2b9 Update version numbers for LGTM 1.29 2022-01-14 15:07:29 +00:00
Ian Lynagh
22dc24629f Fix a couple of typos: clases / clasess 2022-01-14 14:28:29 +00:00
Tony Torralba
fb1287d577 Use dominance instead of getParent
Add clarification comments to PathMatchGuard
2022-01-14 15:28:02 +01:00
Mathias Vorreiter Pedersen
25253c7b8d C++: Don't count write operations as uses for IR dataflow. Accept test changes. 2022-01-14 13:39:57 +00:00
Mathias Vorreiter Pedersen
e8afec413a C++: Add testcase that demonstrates a FP caused by spurious flow through phi nodes in IR dataflow. 2022-01-14 13:34:27 +00:00
Tony Torralba
136fefbab5 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2022-01-14 13:38:17 +01:00
luchua-bc
877c52981f Remove the deprecated library keyword 2022-01-14 12:13:41 +00:00
Tony Torralba
cde7a35c1f QLDoc 2022-01-14 13:12:30 +01:00
Michael Nebel
8c6c8b0adb C#: Remove un-needed ql doc comment. 2022-01-14 12:55:54 +01:00
Tony Torralba
6aac848015 Fix imports 2022-01-14 12:43:08 +01:00
Tony Torralba
9f616e7cbe Refactor to use FlowState
Remove the auxiliary DataFlow configuration
2022-01-14 12:24:35 +01:00
Mathias Vorreiter Pedersen
b51c85597b Merge pull request #7529 from erik-krogh/fixup-library-deps
QL: recognize dependecies of the form: libraryPathDependencies: library-name
2022-01-14 11:13:56 +00:00
Erik Krogh Kristensen
b02fecf125 Merge pull request #7600 from erik-krogh/ql-for-ql-team
QL: change reviewers of QL-for-QL to a newly created team
2022-01-14 11:45:40 +01:00
Erik Krogh Kristensen
47e56365c4 QL: change reviewers of QL-for-QL to a newly created team 2022-01-14 11:32:09 +01:00
Henry Mercer
d55e6d1ca7 Merge pull request #7594 from github/henrymercer/js-atm-rename-queries
JS: Update names, IDs, and tags for ML-powered queries
2022-01-14 10:28:24 +00:00
Benjamin Muskalla
a4429d01a3 Add tests for writer models 2022-01-14 11:12:35 +01:00
Benjamin Muskalla
37ca6a5e41 Model Appenable and Writer
This allows us to track taint carried through all kind of writers.
2022-01-14 11:12:35 +01:00
Mathias Vorreiter Pedersen
6d95d47467 Merge branch 'main' into fix-join-order-in-get-conversion-type 2022-01-14 09:53:17 +00:00
Michael Nebel
6009d71e9a C#: Add getAPrimaryQlClass override to UnknownExpr. 2022-01-14 10:41:44 +01:00
Tony Torralba
df95317a58 Fix tests after stub change 2022-01-14 10:33:21 +01:00
Tony Torralba
6f06be9419 Update change note 2022-01-14 10:33:19 +01:00
Tony Torralba
bd4abf4fd0 Additional Notification models 2022-01-14 10:32:38 +01:00
Tony Torralba
a9757fbc83 Setting null Components is not a sanitizer 2022-01-14 10:32:37 +01:00
Tony Torralba
a59a4024a5 Update stubs 2022-01-14 10:32:36 +01:00
Tony Torralba
66794665f3 Remove unneeded implicit read step 2022-01-14 10:32:36 +01:00
Tony Torralba
a0a914466c Rewording 2022-01-14 10:32:33 +01:00
Tony Torralba
9c12c5f8b8 Remove duplicated models 2022-01-14 10:32:01 +01:00
Tony Torralba
f963887c58 Change test to avoid collision with SensitiveCommunication.ql 2022-01-14 10:32:01 +01:00
Tony Torralba
48acff9262 Remove unneeded code 2022-01-14 10:32:00 +01:00
Tony Torralba
9e3594fcf1 Added more sinks 2022-01-14 10:32:00 +01:00
Tony Torralba
1e3e48132c Rewording 2022-01-14 10:31:59 +01:00
Tony Torralba
47c851efaf Consider more startService methods 2022-01-14 10:31:59 +01:00
Tony Torralba
12059a8a50 Update models to use synthetic fields 2022-01-14 10:31:58 +01:00
Tony Torralba
d49e52fb73 Add support for PendingIntents in Notifications 2022-01-14 10:31:58 +01:00
Tony Torralba
c73e4ebc48 Remove models after rebase 2022-01-14 10:31:58 +01:00
Tony Torralba
7f85dae63b Add support for implicit field read flows 2022-01-14 10:31:57 +01:00
Tony Torralba
e58a8587db Add support for Slices 2022-01-14 10:31:56 +01:00
Tony Torralba
d43242d09e Added tests 2022-01-14 10:31:56 +01:00
Tony Torralba
d0077b8c12 Added query ImplicitPendingIntents 2022-01-14 10:31:53 +01:00
Mathias Vorreiter Pedersen
68385dfab5 Merge pull request #7386 from github/redsun82/cpp-overrunning-write-precision-split
C++: split `cpp/overrunning-write` into two
2022-01-14 09:11:39 +00:00
Tom Hvitved
6c20585fc7 C#: Eliminate bad magic optimization
```
[2022-01-14 08:57:14] (253s) Tuple counts for Stmt::getAChild#bbf/3@8dfbc66f after 1m53s:
                      4922010396 ~5%     {3} r1 = JOIN ControlFlowElement::ControlFlowElement::getEnclosingCallable_dispred#ff_10#join_rhs WITH ControlFlowElement::ControlFlowElement::getEnclosingCallable_dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1 'cfe', Rhs.1 'cfe', Lhs.0 'c'
                      1597068    ~2%     {3} r2 = JOIN r1 WITH Element::Element::getAChild_dispred#ff ON FIRST 2 OUTPUT Lhs.0 'cfe', Lhs.2 'c', Lhs.1 'result'
                                         return r2
```
2022-01-14 10:10:23 +01:00
Tom Hvitved
411d2b2876 C#: Update stats 2022-01-14 10:10:23 +01:00
Michael Nebel
f025db0371 C#: Add downgrade script for deleting using_global relation. 2022-01-14 10:10:23 +01:00
Michael Nebel
dcd6a6be40 C#: Add database upgrade script for adding the using_global relation. 2022-01-14 10:10:22 +01:00
Michael Nebel
a1eff1603a C#: Add test for global using directive. 2022-01-14 10:10:22 +01:00
Michael Nebel
c118d9bf6f C#: Add support for the global modifier for using directives. 2022-01-14 10:10:22 +01:00
Michael Nebel
e305a8a6c5 C#: Refactor Tuples to use expression body syntax. 2022-01-14 10:10:22 +01:00
Michael Nebel
6e72f6e2c4 C#: Refactor to re-use code to extract modifier tokens. 2022-01-14 10:10:13 +01:00
Edoardo Pirovano
f2818ebb5e Merge pull request #7489 from edoardopirovano/fix-example
Fix example in JavaScript query
2022-01-14 08:58:28 +00:00
Tony Torralba
8f73772955 Merge pull request #7595 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-14 09:32:13 +01:00
Anders Schack-Mulligen
0b24af901d Merge pull request #7349 from aschackmull/dataflow/state
Dataflow: Add support for flow state
2022-01-14 09:12:38 +01:00
github-actions[bot]
685336fa23 Add changed framework coverage reports 2022-01-14 00:10:33 +00:00
Henry Mercer
e9bb9f5294 JS: Update names, IDs, and tags for ML-powered queries 2022-01-13 17:45:40 +00:00
Henry Mercer
8e9d8c112d JS: Improve comments in FunctionBodyFeatures.qll 2022-01-13 17:20:42 +00:00
Henry Mercer
2aea3257cb JS: Improve documentation for getTokenizedAstNode 2022-01-13 17:20:41 +00:00
Andrew Eisenberg
4ffd8c62ac Merge pull request #7579 from github/aeisenberg/changenote-upgrades-removal
Changenotes: Add changenotes for upgrades refactoring
2022-01-13 09:09:06 -08:00
Andrew Eisenberg
c6deccf863 Minor fixes to the getting started docs
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-01-13 09:02:10 -08:00
Michael Nebel
71baf32596 Update csharp/ql/consistency-queries/PrimaryQlClass.ql
Co-authored-by: Tom Hvitved <hvitved@github.com>
2022-01-13 16:36:31 +01:00
Owen Mansel-Chan
d41c55c69c Add needed predicates for Ruby and C#
This was done manually.
2022-01-13 15:10:19 +00:00
Owen Mansel-Chan
2de6340ff5 Sync FlowSummaryImpl.qll
Done using sync-files.py
2022-01-13 15:09:25 +00:00
Owen Mansel-Chan
83a25698bb Allow adding inputs and outputs needing reference 2022-01-13 15:09:17 +00:00
Tony Torralba
b6886b8e43 Move code to qll file 2022-01-13 15:28:57 +01:00
Tony Torralba
81feaaec02 Refactor PathMatchGuard 2022-01-13 15:24:41 +01:00
Anders Schack-Mulligen
c44cf29992 Merge pull request #7587 from owen-mc/add-default-taint-sanitizer-guard
Dataflow: Add default taint sanitizer guard
2022-01-13 14:44:55 +01:00
Tony Torralba
cd9a485c47 Refactor NullOrEmptyCheckGuard 2022-01-13 14:44:08 +01:00
Anders Schack-Mulligen
61490e74d8 Merge pull request #7561 from aschackmull/java/misc-perf
Java: A few perf fixes for getASupertype*().
2022-01-13 14:43:28 +01:00
Mathias Vorreiter Pedersen
6148af4621 C++: Fix join order in 'getConversionType4'. 2022-01-13 13:28:36 +00:00
Anders Schack-Mulligen
f7cf327e71 Dataflow: Sync 2022-01-13 13:28:43 +01:00
Anders Schack-Mulligen
a34c981209 Dataflow: Address comments. 2022-01-13 13:28:24 +01:00
Anders Schack-Mulligen
69973dadb3 Merge pull request #7548 from zbazztian/spring-taint-summaries
Java: Add Spring and Apache Common Langs taint flow steps
2022-01-13 13:00:41 +01:00
Paolo Tranquilli
e6763c858d C++: add bindingset to private Printf predicate
That predicate turned out to create a lot of tuples, of which only a
minimal part was then used in the query.
2022-01-13 11:59:48 +00:00
Paolo Tranquilli
64d15d6226 C++: fix inc.qhelp files and change notes 2022-01-13 11:59:48 +00:00
Paolo Tranquilli
7b4300e4cf C++: Apply suggestions in documentation
Co-authored-by: Sarah Edwards <skedwards88@github.com>
2022-01-13 11:59:48 +00:00
Paolo Tranquilli
9d49ad9f20 C++: use includes in OverrunWrite qhelp files
Also added the relevant CERT C _and_ C++ standard references where they
were missing, and did some minor stylistic tweaks to
`OverrunWriteFloat.qhelp`.
2022-01-13 11:59:48 +00:00
Paolo Tranquilli
c117a1e21f C++: demote VeryLikelyOverrunWrite cast results
There were some false positives where something like

    int x;
    // ...
    sprintf(buff, "%ld", (long)x);

was considered as if the parameter had a non-trivial range analysis only
because the range of `int` is smaller than the range for `long`, without
any non-trivial range analysis actually done on `x`.

These will now be reported by `OverrunWrite` instead.
2022-01-13 11:59:48 +00:00
Paolo Tranquilli
630982cc31 C++: auto format Printf.qll 2022-01-13 11:59:48 +00:00
Paolo Tranquilli
9f811b2439 C++: remove unused variables and fix tests 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
013216d5e6 C++: exclude widening from VeryLikelyOverrunWrite
This also restrict what we consider "non-trivial" range analysis, as we
now require both ends to be non-trivially bounded for signed integers.
This avoids false positives stemming from a non trivial upper bound but
no meaningful lower bound, for example.
2022-01-13 11:59:47 +00:00
Paolo Tranquilli
aac029841a C++: doc fixes to VeryLikelyOverrunWrite 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
c8741f6475 C++: update 2021-12-14-overruning-write-split.md
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2022-01-13 11:59:47 +00:00
Paolo Tranquilli
1e4861a944 C++: shorten VeryLikelyOverrunWrite @name 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
106400238a C++: tweak overrunning write qhelp files 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
8ac34f3db5 C++: NoSpecifiedEstimateReasonUnspecified... 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
4a85b9b0cc C++: add VeryLikelyOverrunWrite.ql to cwe-120 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
97f1a5bac0 C++: add VeryLikelyOverrunWrite.qhelp 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
10b62154a1 C++: add cpp/very-likely-overruning-write help
Also update the help of `cpp/overruning-write`, as the case shown there
will actually not be flagged by that query any more.
2022-01-13 11:59:47 +00:00
Paolo Tranquilli
b979f02e5d C++: fix OverrunWrite for backward compatibility
Rather than testing for `TypeBoundsAnalysis`, we test that the reason is
not `ValueFlowAnalysis` (which is reported by the new
`cpp/very-likely-overruning-write` query), so that if a client has
overridden `BufferWrite::getMaxData` the `NoSpecifiedEstimateReason` is
taken into account.
2022-01-13 11:59:47 +00:00
Paolo Tranquilli
db6214fdff C++: add change note for new overrun write query 2022-01-13 11:59:47 +00:00
Paolo Tranquilli
a0059202db C++: split cpp/overrunning-write into two
This splits the `cpp/overruning-write` into two separate queries based
off on the reason for the estimation. If the overrun is detected based
on non-trivial range analysis, the results are now marked by the new
`cpp/very-likely-overruning-write` high precision query. If it is based
on less precise, usually type based bounds, then it will still be marked
by `cpp/overruning-write` which remains at medium precision.
2022-01-13 11:59:47 +00:00
Michael Nebel
85fc127c0a C#: Fix BDD limit issue (thank you @jbj). 2022-01-13 12:46:56 +01:00
Owen Mansel-Chan
7e42ccfbf1 Don't cache defaultTaintSanitizerGuard for java 2022-01-13 11:36:20 +00:00
Michael Nebel
7c11e2d7e9 C#: Add a consistency test for getAPrimaryQlClass 2022-01-13 12:20:42 +01:00
Michael Nebel
6b937a939b C#: Add getAPrimaryQlClass overrides 2022-01-13 12:20:41 +01:00
Stephan Brandauer
40ad88ba53 Merge pull request #7474 from kaeluka/db-reads-as-taint-sources
JS: DB reads as taint sources
2022-01-13 12:06:48 +01:00
Michael Nebel
8583a4ffea Merge pull request #7583 from michaelnebel/csharp/fix-broken-test
C#: Narrow string interpolation expressions to a specific single file in testcase.
2022-01-13 11:37:52 +01:00
Erik Krogh Kristensen
89bab6ae12 Merge pull request #7097 from erik-krogh/railsReDoS
JS/PY/RB: support a limited number of ranges for ReDoS analysis
2022-01-13 11:04:36 +01:00
Stephan Brandauer
93507a2d71 combine two implementations for database-accesses as remote flow sources 2022-01-13 10:53:58 +01:00
Michael Nebel
aacb03a74b C#: Narrow string interpolation expressions to a specific single file in testcase. 2022-01-13 10:25:33 +01:00
Stephan Brandauer
63aaf24063 base implementation of Sequelize model on models-as-data 2022-01-13 09:41:25 +01:00
Anders Schack-Mulligen
da69886777 Merge pull request #7580 from github/workflow/coverage/update
Update CSV framework coverage reports
2022-01-13 09:26:00 +01:00
Sebastian Bauersfeld
a6e4f29560 Java: Use the interface instead of the abstract class 2022-01-13 14:13:36 +07:00
Sebastian Bauersfeld
69f329ffec Java: Add test cases for AbstractMessageSource.getMessage() methods 2022-01-13 14:13:27 +07:00
Sebastian Bauersfeld
39b6678b7d Java: Add test case for StringEscapeUtils.escapeJson() taint step. 2022-01-13 11:18:37 +07:00
github-actions[bot]
625836a3be Add changed framework coverage reports 2022-01-13 00:11:30 +00:00
Andrew Eisenberg
e435a3e9c3 Changenotes: Add changenotes for upgrades refactoring 2022-01-12 11:36:31 -08:00
Henry Mercer
1c3c9216f5 Merge pull request #7576 from github/henrymercer/js-bump-atm-versions
JS: Bump ATM pack versions to 0.0.4
2022-01-12 16:53:10 +00:00
Stephan Brandauer
09a28c428c base implementation of Spanner model on models-as-data 2022-01-12 17:07:16 +01:00
Henry Mercer
9abc3411a4 JS: Bump ATM pack versions to 0.0.4 2022-01-12 15:19:13 +00:00
Robert Marsh
5031d6c4a3 Merge pull request #7566 from MathiasVP/smaller-join-in-reachesRefParameter
C++: Smaller join in `reachesRefParameter`
2022-01-12 10:04:35 -05:00
Owen Mansel-Chan
8e8278764b Add predicate defaultTaintSanitizerGuard for each language
This was done manually, as these files are not synced by sync-files.py.
2022-01-12 14:44:56 +00:00
Owen Mansel-Chan
c112980b81 Sync TaintTrackingImpl.qll
Done automatically using sync-files.py
2022-01-12 14:44:55 +00:00
Owen Mansel-Chan
9ec3d7787c Add option for default taint sanitizer guard
This allows languages to specify A sanitizer guard in all
global taint flow configurations but not in local taint.
2022-01-12 14:44:55 +00:00
github-actions[bot]
8a2d92badc Post-release preparation for codeql-cli-2.7.5 2022-01-12 13:28:43 +00:00
Mathias Vorreiter Pedersen
9e51908b02 Merge pull request #7551 from MathiasVP/fix-join-orders-in-unsigned-difference-expr-query
C++: Fix join orders in `cpp/unsigned-difference-expression-compared-zero`
2022-01-12 08:29:03 +00:00
luchua-bc
263dbd33f6 Optimize the query 2022-01-12 02:33:17 +00:00
Andrew Eisenberg
e4eb2c2a59 Update docs on the output of resolve qlpacks
The output has changed and there are no more upgrades
packs. There are also other changes included here.
2022-01-11 15:54:53 -08:00
Mathias Vorreiter Pedersen
b3a7090068 C++: Fix join in reachesRefParameter by joining with 'getEnd' instead
of 'getANode'.

Before:

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

After:

Tuple counts for FlowVar::FlowVar::reachesRefParameter_dispred#ff/2@46f8bfn7 after 32ms:
  24806 ~1%     {2} r1 = JOIN FlowVar::FlowVar_internal::parameterIsNonConstReference#f WITH Parameter::Parameter::getFunction_dispred#ff ON FIRST 1 OUTPUT Lhs.0 'p', Rhs.1
  56985 ~1%     {3} r2 = JOIN r1 WITH num#FlowVar::FlowVar_internal::TBlockVar#fff_12#join_rhs ON FIRST 1 OUTPUT Lhs.1, Lhs.0 'p', Rhs.1 'this'
  56985 ~1%     {3} r3 = JOIN r2 WITH SubBasicBlocks::SubBasicBlock::getEnd_dispred#fb_10#join_rhs ON FIRST 1 OUTPUT Lhs.2 'this', Rhs.1, Lhs.1 'p'
  49457 ~0%     {2} r4 = JOIN r3 WITH FlowVar::FlowVar_internal::getAReachedBlockVarSBB#ff ON FIRST 2 OUTPUT Lhs.0 'this', Lhs.2 'p'
                return r4
2022-01-11 13:48:20 +00:00
Anders Schack-Mulligen
fdb4851521 Java: A few perf fixes for getASupertype*(). 2022-01-11 13:33:54 +01:00
Stephan Brandauer
132e0bf4b7 add database accesses as additional (heuristic) remote flow sources 2022-01-11 11:38:41 +01:00
Sebastian Bauersfeld
e2a9ced691 Java: Pass taint through Apache's StringEscapeUtils.escapeJson() method. 2022-01-11 15:49:44 +07:00
Sebastian Bauersfeld
f36ee95128 Java: Pass taint through Spring's AbstractMessageSource.getMessage() methods. 2022-01-11 15:48:29 +07:00
Robert Marsh
fe355a0bc9 C++: update test comments 2022-01-10 12:38:08 -05:00
Mathias Vorreiter Pedersen
2a02ce137a C++: Fix join orders in 'exprIsSubLeftOrLess'.
Before:

Tuple counts for UnsignedDifferenceExpressionComparedZero::exprIsSubLeftOrLess#ff/2@i3#a5071w3a after 24s:
  304220    ~2%      {2} r1 = JOIN UnsignedDifferenceExpressionComparedZero::exprIsSubLeftOrLess#ff#prev_delta WITH Expr::BinaryOperation#class#f#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.0 'sub'

  190061335 ~24%     {2} r2 = JOIN r1 WITH DataFlowUtil::localFlowStep#ff ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1 'n'

  3956      ~0%      {2} r3 = JOIN r1 WITH DataFlowUtil::localFlowStep#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1 'n'

  407983    ~1%      {2} r4 = JOIN Expr::BinaryOperation#class#f#join_rhs WITH UnsignedDifferenceExpressionComparedZero::exprIsSubLeftOrLess#ff#prev ON FIRST 1 OUTPUT Rhs.1 'n', Lhs.0 'sub'
  380823    ~0%      {2} r5 = JOIN r4 WITH DataFlowUtil::TExprNode#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1
  0         ~0%      {2} r6 = JOIN r5 WITH UnsignedDifferenceExpressionComparedZero::isGuarded#fff#prev_delta ON FIRST 2 OUTPUT Rhs.2, Lhs.0 'sub'
  0         ~0%      {2} r7 = JOIN r6 WITH DataFlowUtil::TExprNode#ff ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1 'n'

  3956      ~0%      {2} r8 = r3 UNION r7
  190065291 ~24%     {2} r9 = r2 UNION r8
  ...

After:

Tuple counts for UnsignedDifferenceExpressionComparedZero::interestingSubExpr#f/1@654e29g3 after 228ms:
  370 ~2%     {2} r1 = ComparisonOperation::RelationalOperation::getGreaterOperand_dispred#fb AND NOT Exclusions::isFromMacroDefinition#b(Lhs.1 'sub')
  370 ~0%     {2} r2 = SCAN r1 OUTPUT In.1 'sub', In.0
  370 ~3%     {3} r3 = JOIN r2 WITH Expr::Expr::getFullyConverted_dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0 'sub'
  210 ~1%     {2} r4 = JOIN r3 WITH SimpleRangeAnalysis::SimpleRangeAnalysisCached::exprMightOverflowNegatively#f ON FIRST 1 OUTPUT Lhs.2 'sub', Lhs.1
  210 ~0%     {3} r5 = JOIN r4 WITH Expr::Expr::getFullyConverted_dispred#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.0 'sub', Rhs.1
  210 ~1%     {3} r6 = JOIN r5 WITH ComparisonOperation::RelationalOperation::getLesserOperand_dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'sub', Lhs.2
  59  ~2%     {4} r7 = JOIN r6 WITH Expr::Expr::getValue_dispred#ff ON FIRST 1 OUTPUT Lhs.1 'sub', Lhs.2, Rhs.1, toInt(Rhs.1)
  17  ~0%     {4} r8 = SELECT r7 ON In.3 = 0
  17  ~0%     {2} r9 = SCAN r8 OUTPUT In.1, In.0 'sub'
  8   ~0%     {2} r10 = JOIN r9 WITH Expr::Expr::getUnspecifiedType_dispred#bb ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'sub'
  8   ~0%     {1} r11 = JOIN r10 WITH Type::IntegralType::isUnsigned_dispred#f ON FIRST 1 OUTPUT Lhs.1 'sub'
              return r11

Tuple counts for UnsignedDifferenceExpressionComparedZero::exprIsSubLeftOrLess#ff/2@i2#61800weu after 1ms:
  8  ~0%      {2} r1 = JOIN UnsignedDifferenceExpressionComparedZero::exprIsSubLeftOrLess#ff#prev_delta WITH UnsignedDifferenceExpressionComparedZero::interestingSubExpr#f ON FIRST 1 OUTPUT Lhs.1, Lhs.0 'sub'

  0  ~0%      {2} r2 = JOIN r1 WITH DataFlowUtil::localFlowStep#ff ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1 'n'

  1  ~0%      {2} r3 = JOIN r1 WITH DataFlowUtil::localFlowStep#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1 'n'

  0  ~0%      {3} r4 = JOIN UnsignedDifferenceExpressionComparedZero::isGuarded#fff#prev_delta WITH UnsignedDifferenceExpressionComparedZero::interestingSubExpr#f ON FIRST 1 OUTPUT Lhs.1, Lhs.0 'sub', Lhs.2
  0  ~0%      {3} r5 = JOIN r4 WITH DataFlowUtil::TExprNode#ff ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1 'n', Lhs.2
  0  ~0%      {2} r6 = JOIN r5 WITH UnsignedDifferenceExpressionComparedZero::exprIsSubLeftOrLess#ff#prev ON FIRST 2 OUTPUT Lhs.2, Lhs.0 'sub'
  0  ~0%      {2} r7 = JOIN r6 WITH DataFlowUtil::TExprNode#ff ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1 'n'

  1  ~0%      {2} r8 = r3 UNION r7
  1  ~0%      {2} r9 = r2 UNION r8
  ...
2022-01-10 17:28:14 +00:00
Mathias Vorreiter Pedersen
f2d6bcd767 C++: Fix join order in 'isGuarded'.
Before:

Tuple counts for UnsignedDifferenceExpressionComparedZero::isGuarded#bff/3@ec24001m after 1.7s:
  97431    ~0%     {2} r1 = JOIN UnsignedDifferenceExpressionComparedZero::isGuarded#bff#join_rhs WITH project#BasicBlocks::Cached::basic_block_member ON FIRST 1 OUTPUT Rhs.1, Lhs.0 'sub'
  11809769 ~1%     {2} r2 = JOIN r1 WITH Guards::GuardCondition::controls_dispred#fff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1 'sub', Rhs.1
  11809769 ~0%     {4} r3 = JOIN r2 WITH project#BasicBlocks::Cached::basic_block_member ON FIRST 1 OUTPUT Lhs.1, Rhs.1, false, Lhs.0 'sub'
  629277   ~4%     {7} r4 = JOIN r3 WITH Guards::GuardCondition::ensuresLt_dispred#ffffff_045123#join_rhs ON FIRST 3 OUTPUT Lhs.3 'sub', Lhs.0, Lhs.1, false, Rhs.3 'left', Rhs.4 'right', Rhs.5
  628120   ~4%     {7} r5 = SELECT r4 ON In.6 >= 0
  628120   ~1%     {3} r6 = SCAN r5 OUTPUT In.0 'sub', In.4 'left', In.5 'right'
                    return r6

After:

Tuple counts for UnsignedDifferenceExpressionComparedZero::isGuarded#fff/3@i2#a5071x3a after 392ms:
  103763 ~0%     {2} r1 = SCAN UnsignedDifferenceExpressionComparedZero::exprIsSubLeftOrLess#ff#prev_delta OUTPUT In.0 'sub', 26
  103763 ~0%     {1} r2 = JOIN r1 WITH exprs ON FIRST 2 OUTPUT Lhs.0 'sub'
  97431  ~0%     {3} r3 = JOIN r2 WITH project#BasicBlocks::Cached::basic_block_member ON FIRST 1 OUTPUT Rhs.1, false, Lhs.0 'sub'
  629277 ~0%     {7} r4 = JOIN r3 WITH Guards::GuardCondition::ensuresLt_dispred#ffffff_450123#join_rhs ON FIRST 2 OUTPUT Lhs.2 'sub', Lhs.0, false, Rhs.2, Rhs.3 'left', Rhs.4 'right', Rhs.5
  628120 ~0%     {7} r5 = SELECT r4 ON In.6 >= 0
  628120 ~1%     {6} r6 = SCAN r5 OUTPUT In.0 'sub', In.1, In.3, In.4 'left', In.5 'right', In.6
  628120 ~1%     {6} r7 = r6 AND NOT UnsignedDifferenceExpressionComparedZero::isGuarded#fff#prev(Lhs.0 'sub', Lhs.3 'left', Lhs.4 'right')
  628120 ~0%     {5} r8 = SCAN r7 OUTPUT In.2, In.1, In.0 'sub', In.3 'left', In.4 'right'
  628120 ~1%     {3} r9 = JOIN r8 WITH Guards::GuardCondition::controls_dispred#fff ON FIRST 2 OUTPUT Lhs.2 'sub', Lhs.3 'left', Lhs.4 'right'
                  return r9
2022-01-10 17:03:40 +00:00
Anders Schack-Mulligen
f590d2566e DataFlow: Fix test. 2022-01-10 11:25:52 +01:00
Anders Schack-Mulligen
c8a6798c05 Ruby: Workaround for optimiser problem.
A size 1 DataFlowType causes misoptimisations.
2022-01-10 11:21:18 +01:00
Robert Marsh
67fb48fcc1 C++: use range analysis for hex format lengths
The "new" result on line 189 is a tighter bound than was previously
established, not a newly introduced location.
2022-01-07 16:16:22 -05:00
Robert Marsh
fa9242befe C++: Add tests for bounded hex format values 2022-01-07 16:08:53 -05:00
Erik Krogh Kristensen
cc5e9fea77 add test 2022-01-07 18:44:04 +01:00
Erik Krogh Kristensen
f7a63d5ea0 remove duplicated line 2022-01-07 18:38:02 +01:00
Erik Krogh Kristensen
c8d29a9cf1 sync files 2022-01-07 18:38:02 +01:00
Erik Krogh Kristensen
1a8b6d7414 recognize ranges without upper bounds 2022-01-07 18:38:01 +01:00
Erik Krogh Kristensen
acaf294bee support a limited number of regexp ranges 2022-01-07 18:36:30 +01:00
Erik Krogh Kristensen
bb94c42a35 explicit this
Co-authored-by: Taus <tausbn@github.com>
2022-01-07 15:22:21 +01:00
Erik Krogh Kristensen
9afd360731 QL: recognize dependecies of the form: libraryPathDependencies: library-name 2022-01-06 23:35:28 +01:00
haby0
759ec31508 Delete shutil_path_injection.py file 2022-01-06 21:38:35 +08:00
haby0
05b0daa0b7 Add the test of shutil module in FileSystemAccess.py 2022-01-06 14:14:42 +08:00
Harry Maclean
43ddc54f2b Ruby: Add Module#const_get as a code execution
Module#const_get takes a single string argument and interprets it as the
name of a constant. It then looks up the constant and returns its value.

    Object.const_get("Math::PI")
    # => 3.141592653589793

By itself, this method is not as dangerous as e.g. eval, but if the
value returned is a class that is then instantiated, this can allow an
attacker to instantiate arbitrary Ruby classes.

As a result, I think it's safe to say that any remote input flowing into
this call is a potential vulnerability. A real-world example of this is
https://github.com/advisories/GHSA-52p9-v744-mwjj.
2022-01-06 13:03:41 +13:00
Tom Hvitved
ac9cac78bc Ruby: Fix typo 2022-01-06 12:27:03 +13:00
Tom Hvitved
c3fd272f9b Ruby: Simplify getValueText logic for StringlikeLiterals 2022-01-06 12:27:03 +13:00
Tom Hvitved
799ec23b0d Ruby: Generalize ExprChildMapping logic to AstNodes 2022-01-06 12:27:03 +13:00
Tom Hvitved
322f8356dd Ruby: Include StringComponents in the CFG 2022-01-06 12:27:03 +13:00
Tom Hvitved
301d0bbdf8 Ruby: Restructure test to avoid dead code 2022-01-06 12:27:03 +13:00
Harry Maclean
23f1352953 Add ReDoS test that uses string interpolation
This exercises the support for resolving string interpolations, and is
based on a real vulnerability:

https://github.com/advisories/GHSA-jxhc-q857-3j6g)
2022-01-06 12:27:03 +13:00
Harry Maclean
32c93e70e2 Include simple interpolations in getValueText
When calculating `StringlikeLiteral.getValueText`, include results from
interpolations where we can determine their string value. For example:

    b = "b" # local variable
    D = "d" # constant

    "a#{b}c"     # getValueText() = "abc"
    "a#{b}c{D}"  # getValueText() = "abcd"
    /#a#{b}c{D}/ # getValueText() = "abcd"
2022-01-06 12:27:03 +13:00
Harry Maclean
3df3fb092b Make room for new test code
This change is split over several commits so it is easier to see.
This change adds some extra lines, which will be populated in the next
commit.
2022-01-06 12:26:51 +13:00
Harry Maclean
b4b91e84a3 Ruby: Fix ConstantAccessCfgNode.getValueText
The superclass definition uses SSA, which doesn't track constants.
2022-01-06 12:25:19 +13:00
Anders Schack-Mulligen
ef714f7328 Dataflow: Sync 2022-01-05 14:25:35 +01:00
Anders Schack-Mulligen
6b6a9df0eb Dataflow: Remove abstract class 2022-01-05 14:13:26 +01:00
Tom Hvitved
fd60c6e1ad Merge pull request #7510 from github/release-prep/2.7.5
Release preparation for version 2.7.5
2022-01-04 18:57:43 +01:00
github-actions[bot]
1dfcf427aa Release preparation for version 2.7.5 2022-01-04 14:44:56 +00:00
Edoardo Pirovano
081765cbe8 Apply suggestions from code review
Co-authored-by: Asger F <asgerf@github.com>
2022-01-04 10:07:34 +00:00
Edoardo Pirovano
a616059761 Fix example in JavaScript query 2021-12-29 12:01:09 +00:00
haby0
fed1d88268 Add shutil module path injection sinks 2021-12-20 16:09:06 +08:00
Henry Mercer
144ec8c629 JS: Update featurization for absent features optimization
Absent features are now represented implicitly by the absence of a row
in the `tokenFeatures` relation, rather than explicitly by an empty
string. This leads to improved runtime performance. To enable this
implicit representation, we pass the set of supported token features to
the `scoreEndpoints` HOP. Requires CodeQL CLI v2.7.4.
2021-12-17 18:04:42 +00:00
Dave Bartolomeo
d5ef1cf28d Update docs/change-notes.md
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-12-15 15:58:14 -05:00
luchua-bc
29ce0e9ef1 Add sanitizer for virtual method calls 2021-12-15 16:19:50 +00:00
Tony Torralba
6dfe0ce7c5 Adapt chage note to new format 2021-12-15 16:57:20 +01:00
Tony Torralba
f0e9b768f2 Apply suggestions from code review
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2021-12-15 16:53:47 +01:00
Tony Torralba
65b6c16254 Fix stub after merge 2021-12-15 16:53:47 +01:00
Tony Torralba
6363ff3c08 QLDoc 2021-12-15 16:53:46 +01:00
Tony Torralba
7a1b854678 Add change note 2021-12-15 16:53:46 +01:00
Tony Torralba
85526d71da Add Fragment injection in PreferenceActivity query 2021-12-15 16:53:46 +01:00
Tony Torralba
701d12fb5b Add Fragment injection query 2021-12-15 16:53:45 +01:00
Tony Torralba
efb471687c Add stubs 2021-12-15 16:53:42 +01:00
Dave Bartolomeo
8b0c79d16f Add link to change-notes.md from CONTRIBUTING.md. 2021-12-14 14:30:45 -05:00
Dave Bartolomeo
744d139daf Add more examples 2021-12-14 14:24:39 -05:00
Dave Bartolomeo
97193f72b3 Update Adding change notes.md
Co-authored-by: Aditya Sharad <6874315+adityasharad@users.noreply.github.com>
2021-12-14 14:15:34 -05:00
Dave Bartolomeo
1a2899168f Remove stray text 2021-12-14 14:15:00 -05:00
Dave Bartolomeo
e1c9bf2b30 Fix PR feedback 2021-12-14 14:13:07 -05:00
Dave Bartolomeo
a23fe04ccb Add instructions for creating change notes. 2021-12-14 13:42:52 -05:00
Anders Schack-Mulligen
464b9c3991 Dataflow: Sync. 2021-12-10 11:20:01 +01:00
Anders Schack-Mulligen
32cb8f362b Dataflow: Add test for FlowState. 2021-12-10 11:20:01 +01:00
Anders Schack-Mulligen
219bf51ec2 Dataflow: Add support for flow state. 2021-12-10 11:20:01 +01:00
luchua-bc
8bcffc2886 Query to detect unsafe request dispatcher usage 2021-12-02 04:00:29 +00:00
luchua-bc
6a2c7d54cd Enhance the query to check more scenarios 2021-06-14 03:24:16 +00:00
luchua-bc
6bfe2f2ba6 Add more sinks 2021-02-11 17:53:42 +00:00
luchua-bc
f1788ed04e Revamp the query to handle more cases 2021-02-11 04:33:42 +00:00
luchua-bc
8ed2bc59ad Add the c# program to src and address the issue with algorithm type 2021-01-26 17:29:52 +00:00
luchua-bc
46fd5bd92e Move test files to the test folder 2021-01-20 03:51:46 +00:00
luchua-bc
07f45a51f8 Query to detect hash without salt 2021-01-13 02:49:00 +00:00
1124 changed files with 135341 additions and 75973 deletions

View File

@@ -27,4 +27,4 @@
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
# QL for QL reviewers
/ql/ @erik-krogh @tausbn
/ql/ @github/codeql-ql-for-ql-reviewers

View File

@@ -4,6 +4,9 @@ We welcome contributions to our CodeQL libraries and queries. Got an idea for a
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
## Change notes
Any nontrivial user-visible change to a query pack or library pack should have a change note. For details on how to add a change note for your change, see [this guide](docs/change-notes.md).
## Submitting a new experimental query

View File

@@ -7,6 +7,7 @@
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll",

View File

@@ -5,9 +5,11 @@
@name Badly bounded write (CWE-120)
+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWrite.ql: /CWE/CWE-120
@name Potentially overrunning write (CWE-120)
+ semmlecode-cpp-queries/Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql: /CWE/CWE-120
@name Likely overrunning write
+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWriteFloat.ql: /CWE/CWE-120
@name Potentially overrunning write with float to string conversion (CWE-120)
+ semmlecode-cpp-queries/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql: /CWE/CWE-120
@name Array offset used before range check (CWE-120)
+ semmlecode-cpp-queries/Likely Bugs/Memory Management/UnsafeUseOfStrcat.ql: /CWE/CWE-120
@name Potentially unsafe use of strcat (CWE-120)
@name Potentially unsafe use of strcat (CWE-120)

View File

@@ -1,3 +1,7 @@
## 0.0.7
## 0.0.6
## 0.0.5
## 0.0.4

View File

@@ -0,0 +1,4 @@
---
category: deprecated
---
* The `codeql/cpp-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/cpp-all` CodeQL pack.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* `FormatLiteral::getMaxConvertedLength` now uses range analysis to provide a
more accurate length for integers formatted with `%x`

View File

@@ -0,0 +1 @@
## 0.0.6

View File

@@ -0,0 +1 @@
## 0.0.7

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.5
lastReleaseVersion: 0.0.7

View File

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

View File

@@ -206,9 +206,7 @@ class Class extends UserType {
* it is callable by a particular caller. For C++11, there's also a question
* of whether to include members that are defaulted or deleted.
*/
deprecated predicate hasCopyConstructor() {
exists(CopyConstructor cc | cc = this.getAMemberFunction())
}
deprecated predicate hasCopyConstructor() { this.getAMemberFunction() instanceof CopyConstructor }
/**
* Holds if this class has a copy assignment operator that is either
@@ -224,7 +222,7 @@ class Class extends UserType {
* or deleted.
*/
deprecated predicate hasCopyAssignmentOperator() {
exists(CopyAssignmentOperator coa | coa = this.getAMemberFunction())
this.getAMemberFunction() instanceof CopyAssignmentOperator
}
/**
@@ -887,7 +885,7 @@ class NestedClass extends Class {
* pure virtual function.
*/
class AbstractClass extends Class {
AbstractClass() { exists(PureVirtualFunction f | this.getAMemberFunction() = f) }
AbstractClass() { this.getAMemberFunction() instanceof PureVirtualFunction }
override string getAPrimaryQlClass() { result = "AbstractClass" }
}

View File

@@ -286,13 +286,13 @@ class AttributeArgument extends Element, @attribute_arg {
override Location getLocation() { attribute_args(underlyingElement(this), _, _, _, result) }
override string toString() {
if exists(@attribute_arg_empty self | self = underlyingElement(this))
if underlyingElement(this) instanceof @attribute_arg_empty
then result = "empty argument"
else
exists(string prefix, string tail |
(if exists(this.getName()) then prefix = this.getName() + "=" else prefix = "") and
(
if exists(@attribute_arg_type self | self = underlyingElement(this))
if underlyingElement(this) instanceof @attribute_arg_type
then tail = this.getValueType().getName()
else tail = this.getValueText()
) and

View File

@@ -233,7 +233,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
XMLAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
/** Holds if this XML element has an attribute with the specified `name`. */
predicate hasAttribute(string name) { exists(XMLAttribute a | a = this.getAttribute(name)) }
predicate hasAttribute(string name) { exists(this.getAttribute(name)) }
/** Gets the value of the attribute with the specified `name`, if any. */
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }

View File

@@ -101,6 +101,21 @@ predicate functionArgumentMustBeNullTerminated(Function f, int i) {
f instanceof StrcatFunction and i = 0
}
/**
* Holds if `arg` is a string format argument to a formatting function call
* `ffc`.
*/
predicate formatArgumentMustBeNullTerminated(FormattingFunctionCall ffc, Expr arg) {
// String argument to a formatting function (such as `printf`)
exists(int n, FormatLiteral fl |
ffc.getConversionArgument(n) = arg and
fl = ffc.getFormat() and
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
not fl.hasPrecision(n) // exclude: `%.*s`
)
}
/**
* Holds if `va` is a variable access where the contents must be null terminated.
*/
@@ -113,13 +128,7 @@ predicate variableMustBeNullTerminated(VariableAccess va) {
)
or
// String argument to a formatting function (such as `printf`)
exists(int n, FormatLiteral fl |
fc.(FormattingFunctionCall).getConversionArgument(n) = va and
fl = fc.(FormattingFunctionCall).getFormat() and
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
not fl.hasPrecision(n) // exclude: `%.*s`
)
formatArgumentMustBeNullTerminated(fc, va)
or
// Call to a wrapper function that requires null termination
// (not itself adding a null terminator)

View File

@@ -10,10 +10,22 @@ private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
private newtype TBufferWriteEstimationReason =
TNoSpecifiedEstimateReason() or
TUnspecifiedEstimateReason() or
TTypeBoundsAnalysis() or
TWidenedValueFlowAnalysis() or
TValueFlowAnalysis()
private predicate gradeToReason(int grade, TBufferWriteEstimationReason reason) {
// when combining reasons, lower grade takes precedence
grade = 0 and reason = TUnspecifiedEstimateReason()
or
grade = 1 and reason = TTypeBoundsAnalysis()
or
grade = 2 and reason = TWidenedValueFlowAnalysis()
or
grade = 3 and reason = TValueFlowAnalysis()
}
/**
* A reason for a specific buffer write size estimate.
*/
@@ -32,7 +44,13 @@ abstract class BufferWriteEstimationReason extends TBufferWriteEstimationReason
* Combine estimate reasons. Used to give a reason for the size of a format string
* conversion given reasons coming from its individual specifiers.
*/
abstract BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other);
BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
exists(int grade, int otherGrade |
gradeToReason(grade, this) and gradeToReason(otherGrade, other)
|
if otherGrade < grade then result = other else result = this
)
}
}
/**
@@ -40,16 +58,10 @@ abstract class BufferWriteEstimationReason extends TBufferWriteEstimationReason
* classes derived from BufferWrite and overriding `getMaxData/0` still work with the
* queries as intended.
*/
class NoSpecifiedEstimateReason extends BufferWriteEstimationReason, TNoSpecifiedEstimateReason {
override string toString() { result = "NoSpecifiedEstimateReason" }
class UnspecifiedEstimateReason extends BufferWriteEstimationReason, TUnspecifiedEstimateReason {
override string toString() { result = "UnspecifiedEstimateReason" }
override string getDescription() { result = "no reason specified" }
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
// this reason should not be used in format specifiers, so it should not be combined
// with other reasons
none()
}
}
/**
@@ -60,9 +72,24 @@ class TypeBoundsAnalysis extends BufferWriteEstimationReason, TTypeBoundsAnalysi
override string toString() { result = "TypeBoundsAnalysis" }
override string getDescription() { result = "based on type bounds" }
}
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
other != TNoSpecifiedEstimateReason() and result = TTypeBoundsAnalysis()
/**
* The estimation comes from non trivial bounds found via actual flow analysis,
* but a widening aproximation might have been used for variables in loops.
* For example
* ```
* for (int i = 0; i < 10; ++i) {
* int j = i + i;
* //... <- estimation done here based on j
* }
* ```
*/
class WidenedValueFlowAnalysis extends BufferWriteEstimationReason, TWidenedValueFlowAnalysis {
override string toString() { result = "WidenedValueFlowAnalysis" }
override string getDescription() {
result = "based on flow analysis of value bounds with a widening approximation"
}
}
@@ -80,10 +107,6 @@ class ValueFlowAnalysis extends BufferWriteEstimationReason, TValueFlowAnalysis
override string toString() { result = "ValueFlowAnalysis" }
override string getDescription() { result = "based on flow analysis of value bounds" }
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
other != TNoSpecifiedEstimateReason() and result = other
}
}
class PrintfFormatAttribute extends FormatAttribute {
@@ -359,6 +382,38 @@ private int lengthInBase10(float f) {
result = f.log10().floor() + 1
}
pragma[nomagic]
private predicate isPointerTypeWithBase(Type base, PointerType pt) { base = pt.getBaseType() }
bindingset[expr]
private BufferWriteEstimationReason getEstimationReasonForIntegralExpression(Expr expr) {
// we consider the range analysis non trivial if it
// * constrained non-trivially both sides of a signed value, or
// * constrained non-trivially the positive side of an unsigned value
// expr should already be given as getFullyConverted
if
upperBound(expr) < exprMaxVal(expr) and
(exprMinVal(expr) >= 0 or lowerBound(expr) > exprMinVal(expr))
then
// next we check whether the estimate may have been widened
if upperBoundMayBeWidened(expr)
then result = TWidenedValueFlowAnalysis()
else result = TValueFlowAnalysis()
else result = TTypeBoundsAnalysis()
}
/**
* Gets the number of hex digits required to represent the integer represented by `f`.
*
* `f` is assumed to be nonnegative.
*/
bindingset[f]
private int lengthInBase16(float f) {
f = 0 and result = 1
or
result = (f.log2() / 4.0).floor() + 1
}
/**
* A class to represent format strings that occur as arguments to invocations of formatting functions.
*/
@@ -910,19 +965,19 @@ class FormatLiteral extends Literal {
(
conv = ["s", "S"] and
len = "h" and
result.(PointerType).getBaseType() instanceof PlainCharType
isPointerTypeWithBase(any(PlainCharType plainCharType), result)
or
conv = ["s", "S"] and
len = ["l", "w"] and
result.(PointerType).getBaseType() = this.getWideCharType()
isPointerTypeWithBase(this.getWideCharType(), result)
or
conv = "s" and
(len != "l" and len != "w" and len != "h") and
result.(PointerType).getBaseType() = this.getDefaultCharType()
isPointerTypeWithBase(this.getDefaultCharType(), result)
or
conv = "S" and
(len != "l" and len != "w" and len != "h") and
result.(PointerType).getBaseType() = this.getNonDefaultCharType()
isPointerTypeWithBase(this.getNonDefaultCharType(), result)
)
)
}
@@ -1067,7 +1122,7 @@ class FormatLiteral extends Literal {
* conversion specifier of this format string; has no result if this cannot
* be determined.
*/
int getMaxConvertedLength(int n) { result = max(getMaxConvertedLength(n, _)) }
int getMaxConvertedLength(int n) { result = max(this.getMaxConvertedLength(n, _)) }
/**
* Gets the maximum length of the string that can be produced by the nth
@@ -1157,12 +1212,10 @@ class FormatLiteral extends Literal {
1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1)) and
// The second case uses range analysis to deduce a length that's shorter than the length
// of the number -2^31.
exists(Expr arg, float lower, float upper, float typeLower, float typeUpper |
exists(Expr arg, float lower, float upper |
arg = this.getUse().getConversionArgument(n) and
lower = lowerBound(arg.getFullyConverted()) and
upper = upperBound(arg.getFullyConverted()) and
typeLower = exprMinVal(arg.getFullyConverted()) and
typeUpper = exprMaxVal(arg.getFullyConverted())
upper = upperBound(arg.getFullyConverted())
|
valueBasedBound =
max(int cand |
@@ -1179,11 +1232,9 @@ class FormatLiteral extends Literal {
else cand = lengthInBase10(upper)
)
) and
(
if lower > typeLower or upper < typeUpper
then reason = TValueFlowAnalysis()
else reason = TTypeBoundsAnalysis()
)
// we don't want to call this on `arg.getFullyConverted()` as we want
// to detect non-trivial range analysis without taking into account up-casting
reason = getEstimationReasonForIntegralExpression(arg)
) and
len = valueBasedBound.minimum(typeBasedBound)
)
@@ -1195,6 +1246,40 @@ class FormatLiteral extends Literal {
typeBasedBound = lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8) - 1) and
// The second case uses range analysis to deduce a length that's shorter than
// the length of the number 2^31 - 1.
exists(Expr arg, float lower, float upper |
arg = this.getUse().getConversionArgument(n) and
lower = lowerBound(arg.getFullyConverted()) and
upper = upperBound(arg.getFullyConverted())
|
valueBasedBound =
lengthInBase10(max(float cand |
// If lower can be negative we use `(unsigned)-1` as the candidate value.
lower < 0 and
cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
or
cand = upper
)) and
// we don't want to call this on `arg.getFullyConverted()` as we want
// to detect non-trivial range analysis without taking into account up-casting
reason = getEstimationReasonForIntegralExpression(arg)
) and
len = valueBasedBound.minimum(typeBasedBound)
)
or
this.getConversionChar(n).toLowerCase() = "x" and
// e.g. "12345678"
exists(int baseLen, int typeBasedBound, int valueBasedBound |
typeBasedBound =
min(int digits |
digits = 2 * this.getIntegralDisplayType(n).getSize()
or
exists(IntegralType t |
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
t.isUnsigned() and
digits = 2 * t.getSize()
)
) and
exists(Expr arg, float lower, float upper, float typeLower, float typeUpper |
arg = this.getUse().getConversionArgument(n) and
lower = lowerBound(arg.getFullyConverted()) and
@@ -1203,7 +1288,7 @@ class FormatLiteral extends Literal {
typeUpper = exprMaxVal(arg.getFullyConverted())
|
valueBasedBound =
lengthInBase10(max(float cand |
lengthInBase16(max(float cand |
// If lower can be negative we use `(unsigned)-1` as the candidate value.
lower < 0 and
cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
@@ -1216,29 +1301,10 @@ class FormatLiteral extends Literal {
else reason = TTypeBoundsAnalysis()
)
) and
len = valueBasedBound.minimum(typeBasedBound)
baseLen = valueBasedBound.minimum(typeBasedBound) and
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
)
or
this.getConversionChar(n).toLowerCase() = "x" and
// e.g. "12345678"
exists(int sizeBytes, int baseLen |
sizeBytes =
min(int bytes |
bytes = this.getIntegralDisplayType(n).getSize()
or
exists(IntegralType t |
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
t.isUnsigned() and bytes = t.getSize()
)
) and
baseLen = sizeBytes * 2 and
(
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
)
) and
reason = TTypeBoundsAnalysis()
or
this.getConversionChar(n).toLowerCase() = "p" and
exists(PointerType ptrType, int baseLen |
ptrType = this.getFullyConverted().getType() and
@@ -1287,7 +1353,7 @@ class FormatLiteral extends Literal {
* determining whether a buffer overflow is caused by long float to string
* conversions.
*/
int getMaxConvertedLengthLimited(int n) { result = max(getMaxConvertedLengthLimited(n, _)) }
int getMaxConvertedLengthLimited(int n) { result = max(this.getMaxConvertedLengthLimited(n, _)) }
/**
* Gets the maximum length of the string that can be produced by the nth

View File

@@ -29,7 +29,7 @@ class GuardCondition extends Expr {
exists(IRGuardCondition ir | this = ir.getUnconvertedResultExpression())
or
// no binary operators in the IR
exists(GuardCondition gc | this.(BinaryLogicalOperation).getAnOperand() = gc)
this.(BinaryLogicalOperation).getAnOperand() instanceof GuardCondition
or
// the IR short-circuits if(!x)
// don't produce a guard condition for `y = !x` and other non-short-circuited cases
@@ -98,7 +98,7 @@ class GuardCondition extends Expr {
*/
private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
GuardConditionFromBinaryLogicalOperator() {
exists(GuardCondition gc | this.(BinaryLogicalOperation).getAnOperand() = gc)
this.(BinaryLogicalOperation).getAnOperand() instanceof GuardCondition
}
override predicate controls(BasicBlock controlled, boolean testIsTrue) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,17 @@ private import DataFlowImplSpecific::Public
import Cached
module DataFlowImplCommonPublic {
/** A state value to track during data flow. */
class FlowState = string;
/**
* The default state, which is used when the state is unspecified for a source
* or a sink.
*/
class FlowStateEmpty extends FlowState {
FlowStateEmpty() { this = "" }
}
private newtype TFlowFeature =
TFeatureHasSourceCallContext() or
TFeatureHasSinkCallContext() or

View File

@@ -48,7 +48,7 @@ private class Argument extends Expr {
*/
class ArgumentNode extends Node {
ArgumentNode() {
exists(Argument arg | this.asExpr() = arg) or
this.asExpr() instanceof Argument or
this = getInstanceArgument(_)
}

View File

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

View File

@@ -47,6 +47,12 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
*/
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
/**
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
* but not in local taint.
*/
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
/**
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent

View File

@@ -61,7 +61,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSource(DataFlow::Node source);
override predicate isSource(DataFlow::Node source) { none() }
/**
* Holds if `sink` is a relevant taint sink.
@@ -69,7 +69,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSink(DataFlow::Node sink);
override predicate isSink(DataFlow::Node sink) { none() }
/** Holds if the node `node` is a taint sanitizer. */
predicate isSanitizer(DataFlow::Node node) { none() }
@@ -93,7 +93,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
}
/**

View File

@@ -61,7 +61,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSource(DataFlow::Node source);
override predicate isSource(DataFlow::Node source) { none() }
/**
* Holds if `sink` is a relevant taint sink.
@@ -69,7 +69,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSink(DataFlow::Node sink);
override predicate isSink(DataFlow::Node sink) { none() }
/** Holds if the node `node` is a taint sanitizer. */
predicate isSanitizer(DataFlow::Node node) { none() }
@@ -93,7 +93,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
}
/**

View File

@@ -84,8 +84,8 @@ class VariableAccess extends Access, @varaccess {
exists(Assignment a | a.getLValue() = this) or
exists(CrementOperation c | c.getOperand() = this) or
exists(AddressOfExpr addof | addof.getOperand() = this) or
exists(ReferenceToExpr rte | this.getConversion() = rte) or
exists(ArrayToPointerConversion atpc | this.getConversion() = atpc)
this.getConversion() instanceof ReferenceToExpr or
this.getConversion() instanceof ArrayToPointerConversion
}
/**
@@ -104,8 +104,8 @@ class VariableAccess extends Access, @varaccess {
predicate isRValue() {
not exists(AssignExpr ae | ae.getLValue() = this) and
not exists(AddressOfExpr addof | addof.getOperand() = this) and
not exists(ReferenceToExpr rte | this.getConversion() = rte) and
not exists(ArrayToPointerConversion atpc | this.getConversion() = atpc)
not this.getConversion() instanceof ReferenceToExpr and
not this.getConversion() instanceof ArrayToPointerConversion
}
/**
@@ -218,9 +218,7 @@ class PointerFieldAccess extends FieldAccess {
class DotFieldAccess extends FieldAccess {
override string getAPrimaryQlClass() { result = "DotFieldAccess" }
DotFieldAccess() {
exists(Class c | c = this.getQualifier().getFullyConverted().getUnspecifiedType())
}
DotFieldAccess() { this.getQualifier().getFullyConverted().getUnspecifiedType() instanceof Class }
}
/**

View File

@@ -35,7 +35,7 @@ class Call extends Expr, NameQualifiableElement, TCall {
*
* For example, `ptr->f()` has a qualifier, whereas plain `f()` does not.
*/
predicate hasQualifier() { exists(Expr e | this.getChild(-1) = e) }
predicate hasQualifier() { exists(this.getChild(-1)) }
/**
* Gets the expression to the left of the function name or function pointer variable name.

View File

@@ -724,7 +724,7 @@ class SizeofOperator extends Expr, @runtime_sizeof {
* ```
*/
class SizeofExprOperator extends SizeofOperator {
SizeofExprOperator() { exists(Expr e | this.getChild(0) = e) }
SizeofExprOperator() { exists(this.getChild(0)) }
override string getAPrimaryQlClass() { result = "SizeofExprOperator" }
@@ -787,7 +787,7 @@ class AlignofOperator extends Expr, @runtime_alignof {
* ```
*/
class AlignofExprOperator extends AlignofOperator {
AlignofExprOperator() { exists(Expr e | this.getChild(0) = e) }
AlignofExprOperator() { exists(this.getChild(0)) }
/**
* Gets the contained expression.

View File

@@ -3,6 +3,17 @@ private import DataFlowImplSpecific::Public
import Cached
module DataFlowImplCommonPublic {
/** A state value to track during data flow. */
class FlowState = string;
/**
* The default state, which is used when the state is unspecified for a source
* or a sink.
*/
class FlowStateEmpty extends FlowState {
FlowStateEmpty() { this = "" }
}
private newtype TFlowFeature =
TFeatureHasSourceCallContext() or
TFeatureHasSinkCallContext() or

View File

@@ -170,10 +170,16 @@ private class ReturnParameterIndirection extends Use, TReturnParamIndirection {
}
private predicate isExplicitUse(Operand op) {
op.getDef() instanceof VariableAddressInstruction and
not exists(LoadInstruction load |
load.getSourceAddressOperand() = op and
load.getAUse().getUse() instanceof InitializeIndirectionInstruction
exists(VariableAddressInstruction vai | vai = op.getDef() |
// Don't include this operand as a use if it only exists to initialize the
// indirection of a parameter.
not exists(LoadInstruction load |
load.getSourceAddressOperand() = op and
load.getAUse().getUse() instanceof InitializeIndirectionInstruction
) and
// Don't include this operand as a use if the only use of the address is for a write
// that definitely overrides a variable.
not (explicitWrite(true, _, vai) and exists(unique( | | vai.getAUse())))
)
}

View File

@@ -160,6 +160,12 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
*/
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
/**
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
* but not in local taint.
*/
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
/**
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
* modeled function.

View File

@@ -61,7 +61,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSource(DataFlow::Node source);
override predicate isSource(DataFlow::Node source) { none() }
/**
* Holds if `sink` is a relevant taint sink.
@@ -69,7 +69,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSink(DataFlow::Node sink);
override predicate isSink(DataFlow::Node sink) { none() }
/** Holds if the node `node` is a taint sanitizer. */
predicate isSanitizer(DataFlow::Node node) { none() }
@@ -93,7 +93,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
}
/**

View File

@@ -61,7 +61,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSource(DataFlow::Node source);
override predicate isSource(DataFlow::Node source) { none() }
/**
* Holds if `sink` is a relevant taint sink.
@@ -69,7 +69,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSink(DataFlow::Node sink);
override predicate isSink(DataFlow::Node sink) { none() }
/** Holds if the node `node` is a taint sanitizer. */
predicate isSanitizer(DataFlow::Node node) { none() }
@@ -93,7 +93,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
}
/**

View File

@@ -61,7 +61,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSource(DataFlow::Node source);
override predicate isSource(DataFlow::Node source) { none() }
/**
* Holds if `sink` is a relevant taint sink.
@@ -69,7 +69,7 @@ abstract class Configuration extends DataFlow::Configuration {
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSink(DataFlow::Node sink);
override predicate isSink(DataFlow::Node sink) { none() }
/** Holds if the node `node` is a taint sanitizer. */
predicate isSanitizer(DataFlow::Node node) { none() }
@@ -93,7 +93,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
}
/**

View File

@@ -308,45 +308,45 @@ class MetricClass extends Class {
}
private string getAUsedHalsteadN1Operator() {
exists(CommaExpr e | e = this.getAnEnclosedExpression()) and result = "comma"
this.getAnEnclosedExpression() instanceof CommaExpr and result = "comma"
or
exists(ReferenceToExpr e | e = this.getAnEnclosedExpression()) and result = "refTo"
this.getAnEnclosedExpression() instanceof ReferenceToExpr and result = "refTo"
or
exists(PointerDereferenceExpr e | e = this.getAnEnclosedExpression()) and result = "dereference"
this.getAnEnclosedExpression() instanceof PointerDereferenceExpr and result = "dereference"
or
exists(CStyleCast e | e = this.getAnEnclosedExpression()) and result = "cCast"
this.getAnEnclosedExpression() instanceof CStyleCast and result = "cCast"
or
exists(StaticCast e | e = this.getAnEnclosedExpression()) and result = "staticCast"
this.getAnEnclosedExpression() instanceof StaticCast and result = "staticCast"
or
exists(ConstCast e | e = this.getAnEnclosedExpression()) and result = "constCast"
this.getAnEnclosedExpression() instanceof ConstCast and result = "constCast"
or
exists(ReinterpretCast e | e = this.getAnEnclosedExpression()) and result = "reinterpretCast"
this.getAnEnclosedExpression() instanceof ReinterpretCast and result = "reinterpretCast"
or
exists(DynamicCast e | e = this.getAnEnclosedExpression()) and result = "dynamicCast"
this.getAnEnclosedExpression() instanceof DynamicCast and result = "dynamicCast"
or
exists(SizeofExprOperator e | e = this.getAnEnclosedExpression()) and result = "sizeofExpr"
this.getAnEnclosedExpression() instanceof SizeofExprOperator and result = "sizeofExpr"
or
exists(SizeofTypeOperator e | e = this.getAnEnclosedExpression()) and result = "sizeofType"
this.getAnEnclosedExpression() instanceof SizeofTypeOperator and result = "sizeofType"
or
exists(IfStmt e | e = this.getAnEnclosedStmt()) and result = "ifVal"
this.getAnEnclosedStmt() instanceof IfStmt and result = "ifVal"
or
exists(SwitchStmt e | e = this.getAnEnclosedStmt()) and result = "switchVal"
this.getAnEnclosedStmt() instanceof SwitchStmt and result = "switchVal"
or
exists(ForStmt e | e = this.getAnEnclosedStmt()) and result = "forVal"
this.getAnEnclosedStmt() instanceof ForStmt and result = "forVal"
or
exists(DoStmt e | e = this.getAnEnclosedStmt()) and result = "doVal"
this.getAnEnclosedStmt() instanceof DoStmt and result = "doVal"
or
exists(WhileStmt e | e = this.getAnEnclosedStmt()) and result = "whileVal"
this.getAnEnclosedStmt() instanceof WhileStmt and result = "whileVal"
or
exists(GotoStmt e | e = this.getAnEnclosedStmt()) and result = "gotoVal"
this.getAnEnclosedStmt() instanceof GotoStmt and result = "gotoVal"
or
exists(ContinueStmt e | e = this.getAnEnclosedStmt()) and result = "continueVal"
this.getAnEnclosedStmt() instanceof ContinueStmt and result = "continueVal"
or
exists(BreakStmt e | e = this.getAnEnclosedStmt()) and result = "breakVal"
this.getAnEnclosedStmt() instanceof BreakStmt and result = "breakVal"
or
exists(ReturnStmt e | e = this.getAnEnclosedStmt()) and result = "returnVal"
this.getAnEnclosedStmt() instanceof ReturnStmt and result = "returnVal"
or
exists(SwitchCase e | e = this.getAnEnclosedStmt()) and result = "caseVal"
this.getAnEnclosedStmt() instanceof SwitchCase and result = "caseVal"
or
exists(IfStmt s | s = this.getAnEnclosedStmt() and s.hasElse()) and
result = "elseVal"

View File

@@ -65,4 +65,6 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
}
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
override predicate hasSocketInput(FunctionInput input) { input.isParameter(2) }
}

View File

@@ -20,8 +20,9 @@ abstract class RemoteFlowSourceFunction extends Function {
abstract predicate hasRemoteFlowSource(FunctionOutput output, string description);
/**
* Holds if remote data from this source comes from a socket described by
* `input`. There is no result if a socket is not specified.
* Holds if remote data from this source comes from a socket or stream
* described by `input`. There is no result if none is specified by a
* parameter.
*/
predicate hasSocketInput(FunctionInput input) { none() }
}
@@ -59,8 +60,9 @@ abstract class RemoteFlowSinkFunction extends Function {
abstract predicate hasRemoteFlowSink(FunctionInput input, string description);
/**
* Holds if data put into this sink is transmitted through a socket described
* by `input`. There is no result if a socket is not specified.
* Holds if data put into this sink is transmitted through a socket or stream
* described by `input`. There is no result if none is specified by a
* parameter.
*/
predicate hasSocketInput(FunctionInput input) { none() }
}

View File

@@ -397,7 +397,7 @@ class PaddedType extends Class {
// Support only single inheritance for now. If multiple inheritance is
// supported, be sure to fix up the calls to getABaseClass*() to correctly
// handle the presence of multiple base class subojects with the same type.
not exists(ClassDerivation cd | cd = this.getDerivation(1))
not exists(this.getDerivation(1))
}
/**

View File

@@ -72,7 +72,7 @@ predicate lvalue(Element e) {
or
exists(Cast c | lvalue(c) and e.(Expr).getConversion() = c)
or
exists(ReferenceToExpr toref | e.(Expr).getConversion() = toref)
e.(Expr).getConversion() instanceof ReferenceToExpr
or
// If f is a function-pointer, then the following two
// calls are equivalent: f() and (*f)()

View File

@@ -76,7 +76,7 @@ abstract class BufferWrite extends Expr {
* can be found), specifying the reason for the estimation.
*/
int getMaxData(BufferWriteEstimationReason reason) {
reason instanceof NoSpecifiedEstimateReason and result = getMaxData()
reason instanceof UnspecifiedEstimateReason and result = this.getMaxData()
}
/**
@@ -85,7 +85,7 @@ abstract class BufferWrite extends Expr {
* much smaller (8 bytes) than their true maximum length. This can be
* helpful in determining the cause of a buffer overflow issue.
*/
int getMaxDataLimited() { result = getMaxData() }
int getMaxDataLimited() { result = this.getMaxData() }
/**
* Gets an upper bound to the amount of data that's being written (if one
@@ -94,7 +94,7 @@ abstract class BufferWrite extends Expr {
* than their true maximum length. This can be helpful in determining the
* cause of a buffer overflow issue.
*/
int getMaxDataLimited(BufferWriteEstimationReason reason) { result = getMaxData(reason) }
int getMaxDataLimited(BufferWriteEstimationReason reason) { result = this.getMaxData(reason) }
/**
* Gets the size of a single character of the type this
@@ -159,9 +159,11 @@ class StrCopyBW extends BufferWriteCall {
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData(BufferWriteEstimationReason reason) {
result = this.getMaxDataImpl(reason)
}
override int getMaxData() { result = max(getMaxDataImpl(_)) }
override int getMaxData() { result = max(this.getMaxDataImpl(_)) }
}
/**
@@ -203,9 +205,11 @@ class StrCatBW extends BufferWriteCall {
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData(BufferWriteEstimationReason reason) {
result = this.getMaxDataImpl(reason)
}
override int getMaxData() { result = max(getMaxDataImpl(_)) }
override int getMaxData() { result = max(this.getMaxDataImpl(_)) }
}
/**
@@ -269,9 +273,11 @@ class SprintfBW extends BufferWriteCall {
)
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData(BufferWriteEstimationReason reason) {
result = this.getMaxDataImpl(reason)
}
override int getMaxData() { result = max(getMaxDataImpl(_)) }
override int getMaxData() { result = max(this.getMaxDataImpl(_)) }
private int getMaxDataLimitedImpl(BufferWriteEstimationReason reason) {
exists(FormatLiteral fl |
@@ -281,10 +287,10 @@ class SprintfBW extends BufferWriteCall {
}
override int getMaxDataLimited(BufferWriteEstimationReason reason) {
result = getMaxDataLimitedImpl(reason)
result = this.getMaxDataLimitedImpl(reason)
}
override int getMaxDataLimited() { result = max(getMaxDataLimitedImpl(_)) }
override int getMaxDataLimited() { result = max(this.getMaxDataLimitedImpl(_)) }
}
/**
@@ -382,9 +388,11 @@ class SnprintfBW extends BufferWriteCall {
)
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData(BufferWriteEstimationReason reason) {
result = this.getMaxDataImpl(reason)
}
override int getMaxData() { result = max(getMaxDataImpl(_)) }
override int getMaxData() { result = max(this.getMaxDataImpl(_)) }
private int getMaxDataLimitedImpl(BufferWriteEstimationReason reason) {
exists(FormatLiteral fl |
@@ -394,10 +402,10 @@ class SnprintfBW extends BufferWriteCall {
}
override int getMaxDataLimited(BufferWriteEstimationReason reason) {
result = getMaxDataLimitedImpl(reason)
result = this.getMaxDataLimitedImpl(reason)
}
override int getMaxDataLimited() { result = max(getMaxDataLimitedImpl(_)) }
override int getMaxDataLimited() { result = max(this.getMaxDataLimitedImpl(_)) }
}
/**
@@ -495,9 +503,11 @@ class ScanfBW extends BufferWrite {
)
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData(BufferWriteEstimationReason reason) {
result = this.getMaxDataImpl(reason)
}
override int getMaxData() { result = max(getMaxDataImpl(_)) }
override int getMaxData() { result = max(this.getMaxDataImpl(_)) }
override string getBWDesc() {
exists(FunctionCall fc |
@@ -536,7 +546,9 @@ class RealpathBW extends BufferWriteCall {
this = this // Suppress a compiler warning
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData(BufferWriteEstimationReason reason) {
result = this.getMaxDataImpl(reason)
}
override int getMaxData() { result = max(getMaxDataImpl(_)) }
override int getMaxData() { result = max(this.getMaxDataImpl(_)) }
}

View File

@@ -258,7 +258,7 @@ private predicate insideFunctionValueMoveTo(Element src, Element dest) {
format.getConversionChar(sourceArg - ffc.getTarget().getNumberOfParameters()) = ["s", "S"]
)
or
not exists(FormatLiteral fl | fl = c.(FormattingFunctionCall).getFormat())
not c.(FormattingFunctionCall).getFormat() instanceof FormatLiteral
or
not c instanceof FormattingFunctionCall
) and

View File

@@ -271,7 +271,7 @@ class IfStmt extends ConditionalStmt, @stmt_if {
* if (b) { x = 1; }
* ```
*/
predicate hasElse() { exists(Stmt s | this.getElse() = s) }
predicate hasElse() { exists(this.getElse()) }
override string toString() { result = "if (...) ... " }
@@ -357,7 +357,7 @@ class ConstexprIfStmt extends ConditionalStmt, @stmt_constexpr_if {
* if constexpr (b) { x = 1; }
* ```
*/
predicate hasElse() { exists(Stmt s | this.getElse() = s) }
predicate hasElse() { exists(this.getElse()) }
override string toString() { result = "if constexpr (...) ... " }

View File

@@ -1,3 +1,7 @@
## 0.0.7
## 0.0.6
## 0.0.5
### New Queries

View File

@@ -30,8 +30,8 @@ where
// the next statement isn't breaking out of a switch
not s.(BreakStmt).getBreakable() instanceof SwitchStmt and
// the next statement isn't a loop that can be jumped into
not exists(LabelStmt ls | s.(Loop).getStmt().getAChild*() = ls) and
not exists(SwitchCase sc | s.(Loop).getStmt().getAChild*() = sc) and
not s.(Loop).getStmt().getAChild*() instanceof LabelStmt and
not s.(Loop).getStmt().getAChild*() instanceof SwitchCase and
// no preprocessor logic applies
not functionContainsPreprocCode(js.getEnclosingFunction())
select js, "This statement makes $@ unreachable.", s, s.toString()

View File

@@ -55,7 +55,7 @@ abstract class LeapYearFieldAccess extends YearFieldAccess {
op.getAnOperand() = this and
(
op instanceof AssignArithmeticOperation or
exists(BinaryArithmeticOperation bao | bao = op.getAnOperand()) or
op.getAnOperand() instanceof BinaryArithmeticOperation or
op instanceof CrementOperation
)
)
@@ -212,9 +212,7 @@ class ChecksForLeapYearFunctionCall extends FunctionCall {
class LeapYearCheckConfiguration extends DataFlow::Configuration {
LeapYearCheckConfiguration() { this = "LeapYearCheckConfiguration" }
override predicate isSource(DataFlow::Node source) {
exists(VariableAccess va | va = source.asExpr())
}
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof VariableAccess }
override predicate isSink(DataFlow::Node sink) {
exists(ChecksForLeapYearFunctionCall fc | sink.asExpr() = fc.getAnArgument())

View File

@@ -23,6 +23,10 @@ DeclStmt declWithNoInit(LocalVariable v) {
not exists(v.getInitializer())
}
/**
* Control flow reachability from a buffer that is not not null terminated to a
* sink that requires null termination.
*/
class ImproperNullTerminationReachability extends StackVariableReachabilityWithReassignment {
ImproperNullTerminationReachability() { this = "ImproperNullTerminationReachability" }
@@ -52,12 +56,44 @@ class ImproperNullTerminationReachability extends StackVariableReachabilityWithR
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
exprDefinition(v, node, _) or
mayAddNullTerminator(node, v.getAnAccess()) or
node.(AddressOfExpr).getOperand() = v.getAnAccess() or // address taken
isSinkActual(node, v) // only report first use
}
}
from ImproperNullTerminationReachability r, LocalVariable v, VariableAccess va
where r.reaches(_, v, va)
select va, "Variable $@ may not be null terminated.", v, v.getName()
/**
* Flow from a place where null termination is added, to a sink of
* `ImproperNullTerminationReachability`. This was previously implemented as a
* simple barrier in `ImproperNullTerminationReachability`, but there were
* false positive results involving multiple paths from source to sink. We'd
* prefer to report only the results we are sure of.
*/
class NullTerminationReachability extends StackVariableReachabilityWithReassignment {
NullTerminationReachability() { this = "NullTerminationReachability" }
override predicate isSourceActual(ControlFlowNode node, StackVariable v) {
mayAddNullTerminator(node, v.getAnAccess()) or // null termination
node.(AddressOfExpr).getOperand() = v.getAnAccess() // address taken (possible null termination)
}
override predicate isSinkActual(ControlFlowNode node, StackVariable v) {
// have the same sinks as `ImproperNullTerminationReachability`.
exists(ImproperNullTerminationReachability r | r.isSinkActual(node, v))
}
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
// don't look further back than the source, or further forward than the sink
exists(ImproperNullTerminationReachability r | r.isSourceActual(node, v)) or
exists(ImproperNullTerminationReachability r | r.isSinkActual(node, v))
}
}
from
ImproperNullTerminationReachability reaches, NullTerminationReachability nullTermReaches,
ControlFlowNode source, LocalVariable v, VariableAccess sink
where
reaches.reaches(source, v, sink) and
not exists(ControlFlowNode termination |
nullTermReaches.reaches(termination, _, sink) and
termination != source
)
select sink, "Variable $@ may not be null terminated.", v, v.getName()

View File

@@ -4,4 +4,4 @@ Record* fixRecord(Record* r) {
myRecord.fix();
return &myRecord; //returns reference to myRecord, which is a stack-allocated object
}
}

View File

@@ -3,68 +3,169 @@
* @description A function returns a pointer to a stack-allocated region of
* memory. This memory is deallocated at the end of the function,
* which may lead the caller to dereference a dangling pointer.
* @kind problem
* @kind path-problem
* @id cpp/return-stack-allocated-memory
* @problem.severity warning
* @security-severity 9.3
* @precision high
* @tags reliability
* security
* external/cwe/cwe-825
*/
import cpp
import semmle.code.cpp.dataflow.EscapesTree
import semmle.code.cpp.models.interfaces.PointerWrapper
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow
/**
* Holds if `n1` may flow to `n2`, ignoring flow through fields because these
* are currently modeled as an overapproximation that assumes all objects may
* alias.
*/
predicate conservativeDataFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
DataFlow::localFlowStep(n1, n2) and
not n2.asExpr() instanceof FieldAccess and
not hasNontrivialConversion(n2.asExpr())
/** Holds if `f` has a name that we intrepret as evidence of intentionally returning the value of the stack pointer. */
predicate intentionallyReturnsStackPointer(Function f) {
f.getName().toLowerCase().matches(["%stack%", "%sp%"])
}
/**
* Holds if `e` has a conversion that changes it from lvalue to pointer or
* back. As the data-flow library does not support conversions, we cannot track
* data flow through such expressions.
* Holds if `source` is a node that represents the use of a stack variable
*/
predicate hasNontrivialConversion(Expr e) {
e instanceof Conversion and
not (
e instanceof Cast
or
e instanceof ParenthesisExpr
predicate isSource(Node source) {
exists(VariableAddressInstruction var, Function func |
var = source.asInstruction() and
func = var.getEnclosingFunction() and
var.getASTVariable() instanceof StackVariable and
// Pointer-to-member types aren't properly handled in the dbscheme.
not var.getResultType() instanceof PointerToMemberType and
// Rule out FPs caused by extraction errors.
not any(ErrorExpr e).getEnclosingFunction() = func and
not intentionallyReturnsStackPointer(func)
)
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())
}
from StackVariable var, VariableAccess va, ReturnStmt r
where
not var.getUnspecifiedType() instanceof ReferenceType and
not r.isFromUninstantiatedTemplate(_) and
va = var.getAnAccess() and
/**
* Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in
* a `ReturnValueInstruction`. We use the `StoreInstruction` instead of the instruction that defines the
* `ReturnValueInstruction`'s source value oprand because the former has better location information.
*/
predicate isSink(Node sink) {
exists(StoreInstruction store |
store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof
IRReturnVariable and
sink.asOperand() = store.getSourceValueOperand()
)
}
/** Holds if `node1` _must_ flow to `node2`. */
predicate step(Node node1, Node node2) {
instructionToOperandStep(node1.asInstruction(), node2.asOperand())
or
operandToInstructionStep(node1.asOperand(), node2.asInstruction())
}
predicate instructionToOperandStep(Instruction instr, Operand operand) { operand.getDef() = instr }
/**
* Holds if `operand` flows to the result of `instr`.
*
* This predicate ignores flow through `PhiInstruction`s to create a 'must flow' relation. It also
* intentionally conflates addresses of fields and their object, and pointer offsets with their
* base pointer as this allows us to detect cases where an object's address flows to a return statement
* via a field. For example:
*
* ```cpp
* struct S { int x, y };
* int* test() {
* S s;
* return &s.x; // BAD: &s.x is an address of a variable on the stack.
* }
* ```
*/
predicate operandToInstructionStep(Operand operand, Instruction instr) {
instr.(CopyInstruction).getSourceValueOperand() = operand
or
instr.(ConvertInstruction).getUnaryOperand() = operand
or
instr.(CheckedConvertOrNullInstruction).getUnaryOperand() = operand
or
instr.(InheritanceConversionInstruction).getUnaryOperand() = operand
or
instr.(FieldAddressInstruction).getObjectAddressOperand() = operand
or
instr.(PointerOffsetInstruction).getLeftOperand() = operand
}
/** Holds if a source node flows to `n`. */
predicate branchlessLocalFlow0(Node n) {
isSource(n)
or
exists(Node mid |
branchlessLocalFlow0(mid) and
step(mid, n)
)
}
/** Holds if `n` is reachable through some source node, and `n` also eventually reaches a sink. */
predicate branchlessLocalFlow1(Node n) {
branchlessLocalFlow0(n) and
(
// To check if the address escapes directly from `e` in `return e`, we need
// to check the fully-converted `e` in case there are implicit
// array-to-pointer conversions or reference conversions.
variableAddressEscapesTree(va, r.getExpr().getFullyConverted())
isSink(n)
or
// The data flow library doesn't support conversions, so here we check that
// the address escapes into some expression `pointerToLocal`, which flows
// in one or more steps to a returned expression.
exists(Expr pointerToLocal |
variableAddressEscapesTree(va, pointerToLocal.getFullyConverted()) and
not hasNontrivialConversion(pointerToLocal) and
conservativeDataFlowStep+(DataFlow::exprNode(pointerToLocal), DataFlow::exprNode(r.getExpr()))
exists(Node mid |
branchlessLocalFlow1(mid) and
step(n, mid)
)
)
select r, "May return stack-allocated memory from $@.", va, va.toString()
}
newtype TLocalPathNode =
TLocalPathNodeMid(Node n) {
branchlessLocalFlow1(n) and
(
isSource(n) or
exists(LocalPathNodeMid mid | step(mid.getNode(), n))
)
}
abstract class LocalPathNode extends TLocalPathNode {
Node n;
/** Gets the underlying node. */
Node getNode() { result = n }
/** Gets a textual representation of this node. */
string toString() { result = n.toString() }
/** Gets the location of this element. */
Location getLocation() { result = n.getLocation() }
/** Gets a successor `LocalPathNode`, if any. */
LocalPathNode getASuccessor() { step(this.getNode(), result.getNode()) }
}
class LocalPathNodeMid extends LocalPathNode, TLocalPathNodeMid {
LocalPathNodeMid() { this = TLocalPathNodeMid(n) }
}
class LocalPathNodeSink extends LocalPathNodeMid {
LocalPathNodeSink() { isSink(this.getNode()) }
}
/**
* Holds if `source` is a source node, `sink` is a sink node, and there's flow
* from `source` to `sink` using `step` relation.
*/
predicate hasFlow(LocalPathNode source, LocalPathNodeSink sink) {
isSource(source.getNode()) and
source.getASuccessor+() = sink
}
predicate reach(LocalPathNode n) { n instanceof LocalPathNodeSink or reach(n.getASuccessor()) }
query predicate edges(LocalPathNode a, LocalPathNode b) { a.getASuccessor() = b and reach(b) }
query predicate nodes(LocalPathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
from LocalPathNode source, LocalPathNodeSink sink, VariableAddressInstruction var
where
hasFlow(source, sink) and
source.getNode().asInstruction() = var
select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAST(),
var.getAST().toString()

View File

@@ -18,8 +18,5 @@
<p>To fix the problem, either the second argument to <code>snprintf</code> should be changed to 80, or the buffer extended to 256 characters. A further improvement is to use a preprocessor define so that the size is only specified in one place, potentially preventing future recurrence of this issue.</p>
</example>
<references>
</references>
<include src="OverrunWriteReferences.inc.qhelp" />
</qhelp>

View File

@@ -1,9 +1,9 @@
void sayHello()
void sayHello(uint32_t userId)
{
char buffer[10];
char buffer[18];
// BAD: this message overflows the buffer
strcpy(buffer, "Hello, world!");
// BAD: this message overflows the buffer if userId >= 10000
sprintf(buffer, "Hello, user %d!", userId);
MessageBox(hWnd, buffer, "New Message", MB_OK);
}

View File

@@ -6,30 +6,20 @@
<p>The program performs a buffer copy or write operation with no upper limit on the size of the copy, and it appears that certain inputs will cause a buffer overflow to occur in this case. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.</p>
</overview>
<recommendation>
<p>Always control the length of buffer copy and buffer write operations. <code>strncpy</code> should be used over <code>strcpy</code>, <code>snprintf</code> over <code>sprintf</code>, and in other cases 'n-variant' functions should be preferred.</p>
</recommendation>
<include src="OverrunWriteRecommendation.inc.qhelp" />
<example>
<sample src="OverrunWrite.c" />
<p>In this example, the call to <code>strcpy</code> copies a message of 14 characters (including the terminating null) into a buffer with space for just 10 characters. As such, the last four characters overflow the buffer resulting in undefined behavior.</p>
<p>In this example, the call to <code>sprintf</code> writes a message of 14 characters (including the terminating null) plus the length of the string conversion of `userId` into a buffer with space for just 18 characters. As such, if `userId` is greater or equal to `10000`, the last characters overflow the buffer resulting in undefined behavior.</p>
<p>To fix this issue three changes should be made:</p>
<p>To fix this issue these changes should be made:</p>
<ul>
<li>Control the size of the buffer using a preprocessor define.</li>
<li>Replace the call to <code>strcpy</code> with <code>strncpy</code>, specifying the define as the maximum length to copy. This will prevent the buffer overflow.</li>
<li>Consider increasing the buffer size, say to 20 characters, so that the message is displayed correctly.</li>
<li>Control the size of the buffer by declaring it with a compile time constant.</li>
<li>Preferably, replace the call to <code>sprintf</code> with <code>snprintf</code>, using the defined constant size of the buffer or `sizeof(buffer)` as maximum length to write. This will prevent the buffer overflow.</li>
<li>Optionally, if `userId` is expected to be less than `10000`, then return or throw an error if `userId` is out of bounds.</li>
<li>Otherwise, consider increasing the buffer size to at least 25 characters, so that the message is displayed correctly regardless of the value of `userId`.</li>
</ul>
</example>
<references>
<li>CERT C Coding Standard: <a href="https://www.securecoding.cert.org/confluence/display/c/STR31-C.+Guarantee+that+storage+for+strings+has+sufficient+space+for+character+data+and+the+null+terminator">STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator</a>.</li>
<!-- LocalWords: preprocessor CWE STR
-->
</references>
<include src="OverrunWriteReferences.inc.qhelp" />
</qhelp>

View File

@@ -21,12 +21,14 @@ import semmle.code.cpp.commons.Alloc
* See CWE-120/UnboundedWrite.ql for a summary of CWE-120 alert cases.
*/
from BufferWrite bw, Expr dest, int destSize, int estimated
from BufferWrite bw, Expr dest, int destSize, int estimated, BufferWriteEstimationReason reason
where
not bw.hasExplicitLimit() and // has no explicit size limit
dest = bw.getDest() and
destSize = getBufferSize(dest, _) and
estimated = bw.getMaxDataLimited(_) and
estimated = bw.getMaxDataLimited(reason) and
// we exclude ValueFlowAnalysis as it is reported in cpp/very-likely-overruning-write
not reason instanceof ValueFlowAnalysis and
// we can deduce that too much data may be copied (even without
// long '%f' conversions)
estimated > destSize

View File

@@ -6,30 +6,19 @@
<p>The program performs a buffer copy or write operation that includes one or more float to string conversions (i.e. the %f format specifier), which may overflow the destination buffer if extreme inputs are given. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.</p>
</overview>
<recommendation>
<p>Always control the length of buffer copy and buffer write operations. <code>strncpy</code> should be used over <code>strcpy</code>, <code>snprintf</code> over <code>sprintf</code>, and in other cases 'n-variant' functions should be preferred.</p>
</recommendation>
<include src="OverrunWriteRecommendation.inc.qhelp" />
<example>
<sample src="OverrunWriteFloat.c" />
<p>In this example, the call to <code>sprintf</code> contains a %f format specifier. Though a 256 character buffer has been allowed, it is not sufficient for the most extreme floating point inputs. For example the representation of double value 1e304 (that is 1 with 304 zeroes after it) will overflow a buffer of this length.</p>
<p>In this example, the call to <code>sprintf</code> contains a <code>%f</code> format specifier. Though a 256 character buffer has been allowed, it is not sufficient for the most extreme floating point inputs. For example the representation of double value 1e304 (that is 1 with 304 zeroes after it) will overflow a buffer of this length.</p>
<p>To fix this issue three changes should be made:</p>
<ul>
<li>Control the size of the buffer using a preprocessor define.</li>
<li>Replace the call to <code>sprintf</code> with <code>snprintf</code>, specifying the define as the maximum length to copy. This will prevent the buffer overflow.</li>
<li>Consider using the %g format specifier instead of %f.</li>
<li>Consider using the <code>%g</code> format specifier instead of <code>%f</code>.</li>
</ul>
</example>
<references>
<li>CERT C Coding
Standard: <a href="https://www.securecoding.cert.org/confluence/display/c/STR31-C.+Guarantee+that+storage+for+strings+has+sufficient+space+for+character+data+and+the+null+terminator">STR31-C. Guarantee
that storage for strings has sufficient space for character data and
the null terminator</a>.</li>
</references>
<include src="OverrunWriteReferences.inc.qhelp" />
</qhelp>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<recommendation>
<p>Always control the length of buffer copy and buffer write operations. <code>strncpy</code> should be used over <code>strcpy</code>, <code>snprintf</code> over <code>sprintf</code>, and in other cases 'n-variant' functions should be preferred.</p>
</recommendation>
</qhelp>

View File

@@ -0,0 +1,14 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<references>
<li>CERT C Coding Standard: <a href="https://www.securecoding.cert.org/confluence/display/c/STR31-C.+Guarantee+that+storage+for+strings+has+sufficient+space+for+character+data+and+the+null+terminator">STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator</a>.</li>
<li>CERT C++ Coding Standard: <a href="https://www.securecoding.cert.org/confluence/display/cplusplus/STR50-CPP.+Guarantee+that+storage+for+strings+has+sufficient+space+for+character+data+and+the+null+terminator">STR50-CPP. Guarantee that storage for strings has sufficient space for character data and the null terminator</a>.</li>
<!-- LocalWords: preprocessor CWE STR
-->
</references>
</qhelp>

View File

@@ -6,10 +6,7 @@
<p>The program performs a buffer copy or write operation with no upper limit on the size of the copy. An unexpectedly long input that reaches this code will cause the buffer to overflow. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.</p>
</overview>
<recommendation>
<p>Always control the length of buffer copy and buffer write operations. <code>strncpy</code> should be used over <code>strcpy</code>, <code>snprintf</code> over <code>sprintf</code> etc. In general 'n-variant' functions should be preferred.</p>
</recommendation>
<include src="OverrunWriteRecommendation.inc.qhelp" />
<example>
<sample src="UnboundedWrite.c" />
@@ -18,13 +15,5 @@
<p>To fix the problem the call to <code>sprintf</code> should be replaced with <code>snprintf</code>, specifying a maximum length of 80 characters.</p>
</example>
<references>
<li>CERT C++ Coding Standard: <a href="https://www.securecoding.cert.org/confluence/display/cplusplus/STR50-CPP.+Guarantee+that+storage+for+strings+has+sufficient+space+for+character+data+and+the+null+terminator">STR50-CPP. Guarantee that storage for strings has sufficient space for character data and the null terminator</a>.</li>
<!-- LocalWords: CWE STR
-->
</references>
<include src="OverrunWriteReferences.inc.qhelp" />
</qhelp>

View File

@@ -33,7 +33,7 @@ import TaintedWithPath
* hasExplicitLimit() exists(getMaxData()) exists(getBufferSize(bw.getDest(), _))) handled by
* NO NO either UnboundedWrite.ql isUnboundedWrite()
* NO YES NO UnboundedWrite.ql isMaybeUnboundedWrite()
* NO YES YES OverrunWrite.ql, OverrunWriteFloat.ql
* NO YES YES VeryLikelyOverrunWrite.ql, OverrunWrite.ql, OverrunWriteFloat.ql
* YES either YES BadlyBoundedWrite.ql
* YES either NO (assumed OK)
*/

View File

@@ -0,0 +1,14 @@
int sayHello(uint32_t userId)
{
char buffer[17];
if (userId > 9999) return USER_ID_OUT_OF_BOUNDS;
// BAD: this message overflows the buffer if userId >= 1000,
// as no space for the null terminator was accounted for
sprintf(buffer, "Hello, user %d!", userId);
MessageBox(hWnd, buffer, "New Message", MB_OK);
return SUCCESS;
}

View File

@@ -0,0 +1,24 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The program performs a buffer copy or write operation with no upper limit on the size of the copy. By analyzing the bounds of the expressions involved, it appears that certain inputs will cause a buffer overflow to occur in this case. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.</p>
</overview>
<include src="OverrunWriteRecommendation.inc.qhelp" />
<example>
<sample src="VeryLikelyOverrunWrite.c" />
<p>In this example, the call to <code>sprintf</code> writes a message of 14 characters (including the terminating null) plus the length of the string conversion of `userId` into a buffer with space for just 17 characters. While `userId` is checked to occupy no more than 4 characters when converted, there is no space in the buffer for the terminating null character if `userId >= 1000`. In this case, the null character overflows the buffer resulting in undefined behavior.</p>
<p>To fix this issue these changes should be made:</p>
<ul>
<li>Control the size of the buffer by declaring it with a compile time constant.</li>
<li>Preferably, replace the call to <code>sprintf</code> with <code>snprintf</code>, using the defined constant size of the buffer or `sizeof(buffer)` as maximum length to write. This will prevent the buffer overflow.</li>
<li>Increasing the buffer size to account for the full range of `userId` and the terminating null character.</li>
</ul>
</example>
<include src="OverrunWriteReferences.inc.qhelp" />
</qhelp>

View File

@@ -0,0 +1,34 @@
/**
* @name Likely overrunning write
* @description Buffer write operations that do not control the length
* of data written may overflow
* @kind problem
* @problem.severity error
* @security-severity 9.3
* @precision high
* @id cpp/very-likely-overrunning-write
* @tags reliability
* security
* external/cwe/cwe-120
* external/cwe/cwe-787
* external/cwe/cwe-805
*/
import semmle.code.cpp.security.BufferWrite
import semmle.code.cpp.commons.Alloc
/*
* See CWE-120/UnboundedWrite.ql for a summary of CWE-120 alert cases.
*/
from BufferWrite bw, Expr dest, int destSize, int estimated, ValueFlowAnalysis reason
where
not bw.hasExplicitLimit() and // has no explicit size limit
dest = bw.getDest() and
destSize = getBufferSize(dest, _) and
estimated = bw.getMaxDataLimited(reason) and
// we can deduce from non-trivial range analysis that too much data may be copied
estimated > destSize
select bw,
"This '" + bw.getBWDesc() + "' operation requires " + estimated +
" bytes but the destination is only " + destSize + " bytes."

View File

@@ -19,6 +19,7 @@ import cpp
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Allocation
import semmle.code.cpp.commons.NullTermination
predicate terminationProblem(AllocationExpr malloc, string msg) {
// malloc(strlen(...))
@@ -35,13 +36,7 @@ predicate terminationProblem(AllocationExpr malloc, string msg) {
af.hasArrayWithUnknownSize(arg)
or
// flows into string argument to a formatting function (such as `printf`)
exists(int n, FormatLiteral fl |
fc.getArgument(arg) = fc.(FormattingFunctionCall).getConversionArgument(n) and
fl = fc.(FormattingFunctionCall).getFormat() and
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
not fl.hasPrecision(n) // exclude: `%.*s`
)
formatArgumentMustBeNullTerminated(fc, fc.getArgument(arg))
)
) and
msg = "This allocation does not include space to null-terminate the string."

View File

@@ -22,11 +22,13 @@ import semmle.code.cpp.dataflow.DataFlow
* Holds if `sub` is guarded by a condition which ensures that
* `left >= right`.
*/
pragma[noinline]
pragma[nomagic]
predicate isGuarded(SubExpr sub, Expr left, Expr right) {
exists(GuardCondition guard, int k |
guard.controls(sub.getBasicBlock(), _) and
guard.ensuresLt(left, right, k, sub.getBasicBlock(), false) and
exprIsSubLeftOrLess(pragma[only_bind_into](sub), _) and // Manual magic
exists(GuardCondition guard, int k, BasicBlock bb |
pragma[only_bind_into](bb) = sub.getBasicBlock() and
guard.controls(pragma[only_bind_into](bb), _) and
guard.ensuresLt(left, right, k, bb, false) and
k >= 0
)
}
@@ -36,47 +38,56 @@ predicate isGuarded(SubExpr sub, Expr left, Expr right) {
* `sub.getLeftOperand()`.
*/
predicate exprIsSubLeftOrLess(SubExpr sub, DataFlow::Node n) {
n.asExpr() = sub.getLeftOperand()
or
exists(DataFlow::Node other |
// dataflow
exprIsSubLeftOrLess(sub, other) and
(
DataFlow::localFlowStep(n, other) or
DataFlow::localFlowStep(other, n)
interestingSubExpr(sub, _) and // Manual magic
(
n.asExpr() = sub.getLeftOperand()
or
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
)
)
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
)
}
from RelationalOperation ro, SubExpr sub
where
not isFromMacroDefinition(ro) and
predicate interestingSubExpr(SubExpr sub, RelationalOperation ro) {
not isFromMacroDefinition(sub) and
ro.getLesserOperand().getValue().toInt() = 0 and
ro.getGreaterOperand() = sub and
sub.getFullyConverted().getUnspecifiedType().(IntegralType).isUnsigned() and
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
// generally catches false positives involving constants
exprMightOverflowNegatively(sub.getFullyConverted())
}
from RelationalOperation ro, SubExpr sub
where
interestingSubExpr(sub, ro) and
not isFromMacroDefinition(ro) and
// generally catches false positives where there's a relation between the left and right operands
not exprIsSubLeftOrLess(sub, DataFlow::exprNode(sub.getRightOperand()))
select ro, "Unsigned subtraction can never be negative."

View File

@@ -2,7 +2,7 @@
* @name Cleartext storage of sensitive information in file
* @description Storing sensitive information in cleartext can expose it
* to an attacker.
* @kind problem
* @kind path-problem
* @problem.severity warning
* @security-severity 7.5
* @precision high
@@ -17,6 +17,19 @@ import semmle.code.cpp.security.SensitiveExprs
import semmle.code.cpp.security.FileWrite
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph
/**
* Taint flow from a sensitive expression to a `FileWrite` sink.
*/
class FromSensitiveConfiguration extends TaintTracking::Configuration {
FromSensitiveConfiguration() { this = "FromSensitiveConfiguration" }
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveExpr }
override predicate isSink(DataFlow::Node sink) { any(FileWrite w).getASource() = sink.asExpr() }
}
/**
* An operation on a filename.
@@ -43,12 +56,17 @@ predicate isFileName(GVN gvn) {
)
}
from FileWrite w, SensitiveExpr source, Expr mid, Expr dest
from
FromSensitiveConfiguration config, SensitiveExpr source, DataFlow::PathNode sourceNode, Expr mid,
DataFlow::PathNode midNode, FileWrite w, Expr dest
where
DataFlow::localFlow(DataFlow::exprNode(source), DataFlow::exprNode(mid)) and
config.hasFlowPath(sourceNode, midNode) and
sourceNode.getNode().asExpr() = source and
midNode.getNode().asExpr() = mid and
mid = w.getASource() and
dest = w.getDest() and
not isFileName(globalValueNumber(source)) and // file names are not passwords
not exists(string convChar | convChar = w.getSourceConvChar(mid) | not convChar = ["s", "S"]) // ignore things written with other conversion characters
select w, "This write into file '" + dest.toString() + "' may contain unencrypted data from $@",
source, "this source."
select w, sourceNode, midNode,
"This write into file '" + dest.toString() + "' may contain unencrypted data from $@", source,
"this source."

View File

@@ -105,8 +105,8 @@ class Recv extends SendRecv instanceof RemoteFlowSourceFunction {
* practice it usually isn't very important which query reports a result as
* long as its reported exactly once.
*
* We do exclude function calls that specify a constant socket, which is
* likely to mean standard input, standard output or a similar channel.
* We do exclude function calls that specify an apparently constant socket,
* which is likely to mean standard input, standard output or a similar channel.
*/
abstract class NetworkSendRecv extends FunctionCall {
SendRecv target;
@@ -125,6 +125,13 @@ abstract class NetworkSendRecv extends FunctionCall {
v.getInitializer().getExpr() instanceof Literal and
g = globalValueNumber(v.getAnAccess())
)
or
// result of a function call with literal inputs (likely constant)
exists(FunctionCall fc |
forex(Expr arg | arg = fc.getAnArgument() | arg instanceof Literal) and
g = globalValueNumber(fc)
)
// (this is far from exhaustive)
)
)
}
@@ -147,18 +154,28 @@ class NetworkRecv extends NetworkSendRecv {
}
/**
* An expression that is an argument or return value from an encryption or
* decryption call.
* An expression that is an argument or return value from an encryption /
* decryption call. This is quite inclusive to minimize false positives, for
* example `SecureZeroMemory` is not an encryption routine but a clue that
* encryption may be present.
*/
class Encrypted extends Expr {
Encrypted() {
exists(FunctionCall fc |
fc.getTarget().getName().toLowerCase().regexpMatch(".*(crypt|encode|decode).*") and
fc.getTarget()
.getName()
.toLowerCase()
.regexpMatch(".*(crypt|encode|decode|hash|securezero).*") and
(
this = fc or
this = fc.getAnArgument()
)
)
or
exists(Type t |
this.getType().refersTo(t) and
t.getName().toLowerCase().regexpMatch(".*(crypt|encode|decode|hash|securezero).*")
)
}
}

View File

@@ -34,9 +34,7 @@ class SetSecurityDescriptorDaclFunctionCall extends FunctionCall {
class NullDaclConfig extends DataFlow::Configuration {
NullDaclConfig() { this = "NullDaclConfig" }
override predicate isSource(DataFlow::Node source) {
exists(NullValue nullExpr | source.asExpr() = nullExpr)
}
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof NullValue }
override predicate isSink(DataFlow::Node sink) {
exists(SetSecurityDescriptorDaclFunctionCall call, VariableAccess val | val = sink.asExpr() |

View File

@@ -0,0 +1,4 @@
---
category: newQuery
---
* A new `cpp/very-likely-overruning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overruning-write`.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Potential improper null termination" (`cpp/improper-null-termination`) query now produces fewer false positive results around control flow branches and loops.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query has been improved in several ways to reduce false positive results.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* The `cpp/return-stack-allocated-memory` query has been improved to produce fewer false positives. The
query has also been converted to a `path-problem` query.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `cpp/cleartext-storage-file` query has been upgraded with non-local taint flow and has been converted to a `path-problem` query.

View File

@@ -0,0 +1,4 @@
---
category: newQuery
---
* The `security` tag has been added to the `cpp/return-stack-allocated-memory` query. As a result, its results will now appear by default.

View File

@@ -0,0 +1 @@
## 0.0.6

View File

@@ -0,0 +1 @@
## 0.0.7

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.5
lastReleaseVersion: 0.0.7

View File

@@ -24,10 +24,10 @@ class CallUsedToHandleErrors extends FunctionCall {
not exists(this.(ControlFlowNode).getASuccessor())
or
// call throwing an exception
exists(ThrowExpr tex | tex = this.(ControlFlowNode).getASuccessor())
this.(ControlFlowNode).getASuccessor() instanceof ThrowExpr
or
// call logging a message, possibly an error
exists(FormattingFunction ff | ff = this.(ControlFlowNode).getASuccessor())
this.(ControlFlowNode).getASuccessor() instanceof FormattingFunction
or
// enabling recursive search
exists(CallUsedToHandleErrors fr | getTarget() = fr.getEnclosingFunction())
@@ -37,9 +37,9 @@ class CallUsedToHandleErrors extends FunctionCall {
/** Holds if the conditions for a call outside the wrapper function are met. */
predicate conditionsOutsideWrapper(FunctionCall fcp) {
fcp.getNumberOfArguments() > 0 and
not exists(ConditionalStmt cdtmp | fcp.getEnclosingStmt().getParentStmt*() = cdtmp) and
not exists(Loop lptmp | fcp.getEnclosingStmt().getParentStmt*() = lptmp) and
not exists(ReturnStmt rttmp | fcp.getEnclosingStmt().getParentStmt*() = rttmp) and
not fcp.getEnclosingStmt().getParentStmt*() instanceof ConditionalStmt and
not fcp.getEnclosingStmt().getParentStmt*() instanceof Loop and
not fcp.getEnclosingStmt().getParentStmt*() instanceof ReturnStmt and
not exists(FunctionCall fctmp2 | fcp = fctmp2.getAnArgument().getAChild*()) and
not exists(Assignment astmp | fcp = astmp.getRValue().getAChild*()) and
not exists(Initializer intmp | fcp = intmp.getExpr().getAChild*()) and

View File

@@ -53,7 +53,15 @@ where
fctmp.getTarget().hasGlobalOrStdName("fopen") or
fctmp.getTarget().hasGlobalOrStdName("open")
) and
not fctmp.getArgument(1).getValue().matches("r%") and
(
fctmp.getArgument(1).getValue().matches("%a%") or
fctmp.getArgument(1).getValue().matches("%w%") or
// unfortunately cannot use numeric value here because // O_CREAT is defined differently on different OSes:
// https://github.com/red/red/blob/92feb0c0d5f91e087ab35fface6906afbf99b603/runtime/definitions.reds#L477-L491
// this may introduce false negatives
fctmp.getArgument(1).(BitwiseOrExpr).getAChild*().getValueText().matches("O_CREAT") or
fctmp.getArgument(1).getValueText().matches("%O_CREAT%")
) and
fctmp.getNumberOfArguments() = 2 and
not fctmp.getArgument(0).getValue() = "/dev/null" and
fcsnd = fctmp

View File

@@ -92,7 +92,7 @@ where
) and
exists(Variable vrtmp |
vrtmp = fc.getArgument(0).(VariableAccess).getTarget() and
vrtmp = fctmp.getArgument(0).(AddressOfExpr).getAddressable().(Variable) and
vrtmp = fctmp.getArgument(0).(AddressOfExpr).getAddressable() and
not vrtmp instanceof Field
)
) and

View File

@@ -26,7 +26,7 @@ class CallMayNotReturn extends FunctionCall {
// call to another function that may not return
exists(CallMayNotReturn exit | getTarget() = exit.getEnclosingFunction())
or
exists(ThrowExpr tex | tex = this.(ControlFlowNode).getASuccessor())
this.(ControlFlowNode).getASuccessor() instanceof ThrowExpr
}
}
@@ -127,7 +127,7 @@ predicate similarArguments(FunctionCall fc, FunctionCall fc1) {
from FunctionCall fc, FunctionCall fc1
where
not exists(CallMayNotReturn fctmp | fctmp = fc.getASuccessor*()) and
not fc.getASuccessor*() instanceof CallMayNotReturn and
not exists(IfStmt ifs | ifs.getCondition().getAChild*() = fc) and
(
// detecting a repeated call situation within one function

View File

@@ -15,6 +15,6 @@ from EqualityOperation e, PointerToMemberType t, Class c
where
e.getAnOperand().getType() = t and
t.getClass() = c and
exists(VirtualFunction f | c.getAMemberFunction() = f)
c.getAMemberFunction() instanceof VirtualFunction
select e,
"AV Rule 97.1: Neither operand of an equality operator shall be a pointer to a virtual member function."

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.0.6-dev
version: 0.0.8-dev
groups: cpp
dependencies:
codeql/cpp-all: "*"

View File

@@ -570,6 +570,9 @@ postWithInFlow
| test.cpp:481:24:481:30 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:481:24:481:30 | content [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:482:8:482:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:489:7:489:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:491:5:491:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:494:5:494:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:9:7:9:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:10:12:10:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:10:27:10:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |

View File

@@ -481,4 +481,16 @@ void local_field_flow_def_by_ref_steps_with_local_flow(MyStruct * s) {
writes_to_content(s->content);
int* p_content = s->content;
sink(*p_content);
}
}
bool unknown();
void regression_with_phi_flow(int clean1) {
int x = 0;
while (unknown()) {
x = clean1;
if (unknown()) { }
sink(x); // clean
x = source();
}
}

View File

@@ -1403,6 +1403,8 @@ subpaths
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | A.cpp:29:15:29:18 | ReturnValue [c] | A.cpp:48:12:48:18 | call to make [c] |
| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c | A.cpp:27:28:27:28 | c [post update] | A.cpp:55:5:55:5 | b [post update] [c] |
| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:8:28:10 | ReturnValue | A.cpp:56:13:56:15 | call to get |
| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:8:28:10 | ReturnValue | A.cpp:56:13:56:15 | call to get |
| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:8:28:10 | ReturnValue | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:8:28:10 | ReturnValue | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c | A.cpp:25:13:25:13 | c [post update] | A.cpp:57:11:57:24 | new [post update] [c] |
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c | A.cpp:85:9:85:14 | ReturnValue [c] | A.cpp:64:10:64:15 | call to setOnB [c] |
@@ -1420,6 +1422,7 @@ subpaths
| B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:44:16:44:17 | b1 [elem2] | B.cpp:46:13:46:16 | box1 [post update] [elem2] | B.cpp:17:16:17:27 | new [post update] [box1, elem2] |
| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:17:11:17:17 | this [box, elem] | D.cpp:17:11:17:17 | ReturnValue [elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] | D.cpp:10:11:10:17 | ReturnValue | D.cpp:22:25:22:31 | call to getElem |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] | D.cpp:10:11:10:17 | ReturnValue | D.cpp:22:25:22:31 | call to getElem |
| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | elem [post update] | D.cpp:37:8:37:10 | box [post update] [elem] |
| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | elem [post update] | D.cpp:51:8:51:14 | call to getBox1 [post update] [elem] |
| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:11:16:11 | a [post update] | by_reference.cpp:20:5:20:8 | this [post update] [a] |

View File

@@ -10,35 +10,29 @@ edges
| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c |
| A.cpp:31:20:31:20 | c | A.cpp:31:14:31:21 | call to B [c] |
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... |
| A.cpp:43:10:43:12 | & ... | A.cpp:173:26:173:26 | o |
| A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c |
| A.cpp:48:12:48:18 | call to make [c] | A.cpp:49:10:49:10 | b [c] |
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c |
| A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make [c] |
| A.cpp:49:10:49:10 | b [c] | A.cpp:49:13:49:13 | c |
| A.cpp:49:13:49:13 | c | A.cpp:173:26:173:26 | o |
| A.cpp:55:5:55:5 | ref arg b [c] | A.cpp:56:10:56:10 | b [c] |
| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c |
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | ref arg b [c] |
| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] |
| A.cpp:56:10:56:10 | b [c] | A.cpp:56:13:56:15 | call to get |
| A.cpp:56:13:56:15 | call to get | A.cpp:173:26:173:26 | o |
| A.cpp:57:11:57:24 | call to B [c] | A.cpp:57:11:57:24 | new [c] |
| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] |
| A.cpp:57:11:57:24 | new [c] | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c |
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | call to B [c] |
| A.cpp:57:28:57:30 | call to get | A.cpp:173:26:173:26 | o |
| A.cpp:64:10:64:15 | call to setOnB [c] | A.cpp:66:10:66:11 | b2 [c] |
| A.cpp:64:21:64:28 | new | A.cpp:64:10:64:15 | call to setOnB [c] |
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c |
| A.cpp:66:10:66:11 | b2 [c] | A.cpp:66:14:66:14 | c |
| A.cpp:66:14:66:14 | c | A.cpp:173:26:173:26 | o |
| A.cpp:73:10:73:19 | call to setOnBWrap [c] | A.cpp:75:10:75:11 | b2 [c] |
| A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | call to setOnBWrap [c] |
| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c |
| A.cpp:75:10:75:11 | b2 [c] | A.cpp:75:14:75:14 | c |
| A.cpp:75:14:75:14 | c | A.cpp:173:26:173:26 | o |
| A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c |
| A.cpp:81:10:81:15 | call to setOnB [c] | A.cpp:82:12:82:24 | ... ? ... : ... [c] |
| A.cpp:81:21:81:21 | c | A.cpp:81:10:81:15 | call to setOnB [c] |
@@ -54,9 +48,7 @@ edges
| A.cpp:103:14:103:14 | c [a] | A.cpp:107:12:107:13 | c1 [a] |
| A.cpp:103:14:103:14 | c [a] | A.cpp:120:12:120:13 | c1 [a] |
| A.cpp:107:12:107:13 | c1 [a] | A.cpp:107:16:107:16 | a |
| A.cpp:107:16:107:16 | a | A.cpp:173:26:173:26 | o |
| A.cpp:120:12:120:13 | c1 [a] | A.cpp:120:16:120:16 | a |
| A.cpp:120:16:120:16 | a | A.cpp:173:26:173:26 | o |
| A.cpp:124:14:124:14 | b [c] | A.cpp:131:8:131:8 | ref arg b [c] |
| A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:124:14:124:14 | b [c] |
| A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:131:8:131:8 | ref arg b [c] |
@@ -64,7 +56,6 @@ edges
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | ref arg b [c] |
| A.cpp:131:8:131:8 | ref arg b [c] | A.cpp:132:10:132:10 | b [c] |
| A.cpp:132:10:132:10 | b [c] | A.cpp:132:13:132:13 | c |
| A.cpp:132:13:132:13 | c | A.cpp:173:26:173:26 | o |
| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... |
| A.cpp:140:13:140:13 | b [c] | A.cpp:151:18:151:18 | ref arg b [c] |
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:140:13:140:13 | b [c] |
@@ -88,15 +79,12 @@ edges
| A.cpp:152:10:152:10 | d [b, c] | A.cpp:152:13:152:13 | b [c] |
| A.cpp:152:10:152:10 | d [b] | A.cpp:152:13:152:13 | b |
| A.cpp:152:10:152:10 | d [post update] [b, c] | A.cpp:153:10:153:10 | d [b, c] |
| A.cpp:152:13:152:13 | b | A.cpp:173:26:173:26 | o |
| A.cpp:152:13:152:13 | b [c] | A.cpp:152:13:152:13 | ref arg b [c] |
| A.cpp:152:13:152:13 | b [c] | A.cpp:173:26:173:26 | o [c] |
| A.cpp:152:13:152:13 | ref arg b [c] | A.cpp:152:10:152:10 | d [post update] [b, c] |
| A.cpp:153:10:153:10 | d [b, c] | A.cpp:153:13:153:13 | b [c] |
| A.cpp:153:13:153:13 | b [c] | A.cpp:153:16:153:16 | c |
| A.cpp:153:16:153:16 | c | A.cpp:173:26:173:26 | o |
| A.cpp:154:10:154:10 | b [c] | A.cpp:154:13:154:13 | c |
| A.cpp:154:13:154:13 | c | A.cpp:173:26:173:26 | o |
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 [head] |
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] |
@@ -123,7 +111,6 @@ edges
| A.cpp:167:47:167:50 | next [head] | A.cpp:169:12:169:12 | l [head] |
| A.cpp:167:47:167:50 | next [next, head] | A.cpp:167:44:167:44 | l [next, head] |
| A.cpp:169:12:169:12 | l [head] | A.cpp:169:15:169:18 | head |
| A.cpp:169:15:169:18 | head | A.cpp:173:26:173:26 | o |
| A.cpp:173:26:173:26 | o | A.cpp:173:26:173:26 | o |
| A.cpp:173:26:173:26 | o [c] | A.cpp:173:26:173:26 | o [c] |
| A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... |
@@ -182,7 +169,6 @@ edges
| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:22:25:22:31 | call to getElem |
| D.cpp:22:25:22:31 | call to getElem | realistic.cpp:41:17:41:17 | o |
| D.cpp:28:15:28:24 | new | D.cpp:30:5:30:20 | ... = ... |
| D.cpp:30:5:30:5 | b [post update] [box, elem] | D.cpp:31:14:31:14 | b [box, elem] |
| D.cpp:30:5:30:20 | ... = ... | D.cpp:30:8:30:10 | box [post update] [elem] |
@@ -215,20 +201,16 @@ edges
| D.cpp:64:10:64:17 | boxfield [box, elem] | D.cpp:64:20:64:22 | box [elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, elem] | D.cpp:64:10:64:17 | boxfield [box, elem] |
| D.cpp:64:20:64:22 | box [elem] | D.cpp:64:25:64:28 | elem |
| D.cpp:64:25:64:28 | elem | realistic.cpp:41:17:41:17 | o |
| E.cpp:19:27:19:27 | p [data, buffer] | E.cpp:21:10:21:10 | p [data, buffer] |
| E.cpp:21:10:21:10 | p [data, buffer] | E.cpp:21:13:21:16 | data [buffer] |
| E.cpp:21:13:21:16 | data [buffer] | E.cpp:21:18:21:23 | buffer |
| E.cpp:21:18:21:23 | buffer | realistic.cpp:41:17:41:17 | o |
| E.cpp:28:21:28:23 | ref arg raw | E.cpp:31:10:31:12 | raw |
| E.cpp:29:21:29:21 | b [post update] [buffer] | E.cpp:32:10:32:10 | b [buffer] |
| E.cpp:29:24:29:29 | ref arg buffer | E.cpp:29:21:29:21 | b [post update] [buffer] |
| E.cpp:30:21:30:21 | p [post update] [data, buffer] | E.cpp:33:18:33:19 | & ... [data, buffer] |
| E.cpp:30:23:30:26 | data [post update] [buffer] | E.cpp:30:21:30:21 | p [post update] [data, buffer] |
| E.cpp:30:28:30:33 | ref arg buffer | E.cpp:30:23:30:26 | data [post update] [buffer] |
| E.cpp:31:10:31:12 | raw | realistic.cpp:41:17:41:17 | o |
| E.cpp:32:10:32:10 | b [buffer] | E.cpp:32:13:32:18 | buffer |
| E.cpp:32:13:32:18 | buffer | realistic.cpp:41:17:41:17 | o |
| E.cpp:33:18:33:19 | & ... [data, buffer] | E.cpp:19:27:19:27 | p [data, buffer] |
| aliasing.cpp:8:23:8:23 | s [m1] | aliasing.cpp:25:17:25:19 | ref arg & ... [m1] |
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | aliasing.cpp:8:23:8:23 | s [m1] |
@@ -243,21 +225,17 @@ edges
| aliasing.cpp:25:17:25:19 | ref arg & ... [m1] | aliasing.cpp:29:8:29:9 | s1 [m1] |
| aliasing.cpp:26:19:26:20 | ref arg s2 [m1] | aliasing.cpp:30:8:30:9 | s2 [m1] |
| aliasing.cpp:29:8:29:9 | s1 [m1] | aliasing.cpp:29:11:29:12 | m1 |
| aliasing.cpp:29:11:29:12 | m1 | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:30:8:30:9 | s2 [m1] | aliasing.cpp:30:11:30:12 | m1 |
| aliasing.cpp:30:11:30:12 | m1 | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:60:3:60:4 | s2 [post update] [m1] | aliasing.cpp:62:8:62:12 | copy2 [m1] |
| aliasing.cpp:60:3:60:22 | ... = ... | aliasing.cpp:60:3:60:4 | s2 [post update] [m1] |
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | ... = ... |
| aliasing.cpp:62:8:62:12 | copy2 [m1] | aliasing.cpp:62:14:62:15 | m1 |
| aliasing.cpp:62:14:62:15 | m1 | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:92:3:92:3 | w [post update] [s, m1] | aliasing.cpp:93:8:93:8 | w [s, m1] |
| aliasing.cpp:92:3:92:23 | ... = ... | aliasing.cpp:92:5:92:5 | s [post update] [m1] |
| aliasing.cpp:92:5:92:5 | s [post update] [m1] | aliasing.cpp:92:3:92:3 | w [post update] [s, m1] |
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... |
| aliasing.cpp:93:8:93:8 | w [s, m1] | aliasing.cpp:93:10:93:10 | s [m1] |
| aliasing.cpp:93:10:93:10 | s [m1] | aliasing.cpp:93:12:93:13 | m1 |
| aliasing.cpp:93:12:93:13 | m1 | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:158:17:158:20 | ref arg data |
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:164:17:164:20 | ref arg data |
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:175:15:175:22 | ref arg & ... |
@@ -272,13 +250,11 @@ edges
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:4:106:5 | pa [inner post update] |
| aliasing.cpp:158:15:158:15 | s [post update] [data] | aliasing.cpp:159:9:159:9 | s [data] |
| aliasing.cpp:158:17:158:20 | ref arg data | aliasing.cpp:158:15:158:15 | s [post update] [data] |
| aliasing.cpp:159:8:159:14 | * ... | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:159:9:159:9 | s [data] | aliasing.cpp:159:11:159:14 | data |
| aliasing.cpp:159:11:159:14 | data | aliasing.cpp:159:8:159:14 | * ... |
| aliasing.cpp:164:15:164:15 | s [post update] [data] | aliasing.cpp:165:8:165:8 | s [data] |
| aliasing.cpp:164:17:164:20 | ref arg data | aliasing.cpp:164:15:164:15 | s [post update] [data] |
| aliasing.cpp:165:8:165:8 | s [data] | aliasing.cpp:165:10:165:13 | data |
| aliasing.cpp:165:8:165:16 | access to array | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:165:10:165:13 | data | aliasing.cpp:165:8:165:16 | access to array |
| aliasing.cpp:175:15:175:22 | ref arg & ... | aliasing.cpp:175:21:175:22 | m1 [inner post update] |
| aliasing.cpp:175:16:175:17 | s2 [post update] [s, m1] | aliasing.cpp:176:8:176:9 | s2 [s, m1] |
@@ -286,33 +262,24 @@ edges
| aliasing.cpp:175:21:175:22 | m1 [inner post update] | aliasing.cpp:175:19:175:19 | s [post update] [m1] |
| aliasing.cpp:176:8:176:9 | s2 [s, m1] | aliasing.cpp:176:11:176:11 | s [m1] |
| aliasing.cpp:176:11:176:11 | s [m1] | aliasing.cpp:176:13:176:14 | m1 |
| aliasing.cpp:176:13:176:14 | m1 | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:187:15:187:22 | ref arg & ... | aliasing.cpp:187:21:187:22 | m1 [inner post update] |
| aliasing.cpp:187:16:187:17 | s2 [post update] [s, m1] | aliasing.cpp:189:8:189:11 | s2_2 [s, m1] |
| aliasing.cpp:187:19:187:19 | s [post update] [m1] | aliasing.cpp:187:16:187:17 | s2 [post update] [s, m1] |
| aliasing.cpp:187:21:187:22 | m1 [inner post update] | aliasing.cpp:187:19:187:19 | s [post update] [m1] |
| aliasing.cpp:189:8:189:11 | s2_2 [s, m1] | aliasing.cpp:189:13:189:13 | s [m1] |
| aliasing.cpp:189:13:189:13 | s [m1] | aliasing.cpp:189:15:189:16 | m1 |
| aliasing.cpp:189:15:189:16 | m1 | realistic.cpp:41:17:41:17 | o |
| aliasing.cpp:200:15:200:24 | ref arg & ... | aliasing.cpp:200:23:200:24 | m1 [inner post update] |
| aliasing.cpp:200:16:200:18 | ps2 [post update] [s, m1] | aliasing.cpp:201:8:201:10 | ps2 [s, m1] |
| aliasing.cpp:200:21:200:21 | s [post update] [m1] | aliasing.cpp:200:16:200:18 | ps2 [post update] [s, m1] |
| aliasing.cpp:200:23:200:24 | m1 [inner post update] | aliasing.cpp:200:21:200:21 | s [post update] [m1] |
| aliasing.cpp:201:8:201:10 | ps2 [s, m1] | aliasing.cpp:201:13:201:13 | s [m1] |
| aliasing.cpp:201:13:201:13 | s [m1] | aliasing.cpp:201:15:201:16 | m1 |
| aliasing.cpp:201:15:201:16 | m1 | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
| arrays.cpp:7:8:7:13 | access to array | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:8:8:8:13 | access to array | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:9:8:9:11 | * ... | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:10:8:10:15 | * ... | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array |
| arrays.cpp:16:8:16:13 | access to array | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:17:8:17:13 | access to array | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:37:8:37:8 | o [nested, arr, data] |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:38:8:38:8 | o [nested, arr, data] |
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | arrays.cpp:36:12:36:14 | arr [inner post update] [data] |
@@ -336,7 +303,6 @@ edges
| arrays.cpp:38:8:38:22 | access to array [data] | arrays.cpp:38:24:38:27 | data |
| arrays.cpp:38:10:38:15 | nested [arr, data] | arrays.cpp:38:17:38:19 | arr [data] |
| arrays.cpp:38:17:38:19 | arr [data] | arrays.cpp:38:8:38:22 | access to array [data] |
| arrays.cpp:38:24:38:27 | data | realistic.cpp:41:17:41:17 | o |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:43:8:43:8 | o [indirect, arr, data] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:44:8:44:8 | o [indirect, arr, data] |
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | arrays.cpp:42:15:42:17 | arr [inner post update] [data] |
@@ -360,7 +326,6 @@ edges
| arrays.cpp:44:8:44:25 | access to array [data] | arrays.cpp:44:27:44:30 | data |
| arrays.cpp:44:10:44:17 | indirect [arr, data] | arrays.cpp:44:20:44:22 | arr [data] |
| arrays.cpp:44:20:44:22 | arr [data] | arrays.cpp:44:8:44:25 | access to array [data] |
| arrays.cpp:44:27:44:30 | data | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... |
| by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:11:39:11:39 | s [a] |
| by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:5:12:5 | s [post update] [a] |
@@ -387,23 +352,19 @@ edges
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | ref arg s [a] |
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:35:9:35:19 | this [a] |
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:51:10:51:20 | call to getDirectly | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:56:3:56:3 | ref arg s [a] | by_reference.cpp:57:8:57:8 | s [a] |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:19:28:19:32 | value |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | ref arg s [a] |
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:39:9:39:21 | this [a] |
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:57:10:57:22 | call to getIndirectly | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:62:3:62:3 | ref arg s [a] | by_reference.cpp:63:8:63:8 | s [a] |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | ref arg s [a] |
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:43:9:43:27 | this [a] |
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:68:17:68:18 | ref arg & ... [a] | by_reference.cpp:69:22:69:23 | & ... [a] |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:31:46:31:46 | s [a] |
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| by_reference.cpp:83:31:83:35 | inner [a] | by_reference.cpp:102:21:102:39 | ref arg & ... [a] |
@@ -455,20 +416,14 @@ edges
| by_reference.cpp:108:24:108:24 | a [inner post update] | by_reference.cpp:108:16:108:21 | pouter [post update] [a] |
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested [a] |
| by_reference.cpp:110:14:110:25 | inner_nested [a] | by_reference.cpp:110:27:110:27 | a |
| by_reference.cpp:110:27:110:27 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | by_reference.cpp:111:14:111:22 | inner_ptr [a] |
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | by_reference.cpp:111:25:111:25 | a |
| by_reference.cpp:111:25:111:25 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:112:8:112:12 | outer [a] | by_reference.cpp:112:14:112:14 | a |
| by_reference.cpp:112:14:112:14 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested [a] |
| by_reference.cpp:114:16:114:27 | inner_nested [a] | by_reference.cpp:114:29:114:29 | a |
| by_reference.cpp:114:29:114:29 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | by_reference.cpp:115:16:115:24 | inner_ptr [a] |
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | by_reference.cpp:115:27:115:27 | a |
| by_reference.cpp:115:27:115:27 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:116:8:116:13 | pouter [a] | by_reference.cpp:116:16:116:16 | a |
| by_reference.cpp:116:16:116:16 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | by_reference.cpp:130:8:130:12 | outer [inner_nested, a] |
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] |
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] |
@@ -485,20 +440,14 @@ edges
| by_reference.cpp:128:23:128:23 | ref arg a | by_reference.cpp:128:15:128:20 | pouter [post update] [a] |
| by_reference.cpp:130:8:130:12 | outer [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested [a] |
| by_reference.cpp:130:14:130:25 | inner_nested [a] | by_reference.cpp:130:27:130:27 | a |
| by_reference.cpp:130:27:130:27 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] | by_reference.cpp:131:14:131:22 | inner_ptr [a] |
| by_reference.cpp:131:14:131:22 | inner_ptr [a] | by_reference.cpp:131:25:131:25 | a |
| by_reference.cpp:131:25:131:25 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:132:8:132:12 | outer [a] | by_reference.cpp:132:14:132:14 | a |
| by_reference.cpp:132:14:132:14 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested [a] |
| by_reference.cpp:134:16:134:27 | inner_nested [a] | by_reference.cpp:134:29:134:29 | a |
| by_reference.cpp:134:29:134:29 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
| by_reference.cpp:135:27:135:27 | a | realistic.cpp:41:17:41:17 | o |
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
| by_reference.cpp:136:16:136:16 | a | realistic.cpp:41:17:41:17 | o |
| complex.cpp:9:7:9:7 | this [a_] | complex.cpp:9:20:9:21 | this [a_] |
| complex.cpp:9:20:9:21 | this [a_] | complex.cpp:9:20:9:21 | a_ |
| complex.cpp:10:7:10:7 | this [b_] | complex.cpp:10:20:10:21 | this [b_] |
@@ -542,31 +491,26 @@ edges
| complex.cpp:65:7:65:8 | b3 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
| complex.cpp:65:7:65:8 | b3 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
| conflated.cpp:19:19:19:21 | ref arg raw | conflated.cpp:20:8:20:10 | raw |
| conflated.cpp:20:8:20:10 | raw | realistic.cpp:41:17:41:17 | o |
| conflated.cpp:29:3:29:4 | pa [post update] [x] | conflated.cpp:30:8:30:9 | pa [x] |
| conflated.cpp:29:3:29:22 | ... = ... | conflated.cpp:29:3:29:4 | pa [post update] [x] |
| conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:29:3:29:22 | ... = ... |
| conflated.cpp:30:8:30:9 | pa [x] | conflated.cpp:30:12:30:12 | x |
| conflated.cpp:30:12:30:12 | x | realistic.cpp:41:17:41:17 | o |
| conflated.cpp:36:3:36:4 | pa [post update] [x] | conflated.cpp:37:8:37:9 | pa [x] |
| conflated.cpp:36:3:36:22 | ... = ... | conflated.cpp:36:3:36:4 | pa [post update] [x] |
| conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:36:3:36:22 | ... = ... |
| conflated.cpp:37:8:37:9 | pa [x] | conflated.cpp:37:12:37:12 | x |
| conflated.cpp:37:12:37:12 | x | realistic.cpp:41:17:41:17 | o |
| conflated.cpp:54:3:54:4 | ll [post update] [next, y] | conflated.cpp:55:8:55:9 | ll [next, y] |
| conflated.cpp:54:3:54:28 | ... = ... | conflated.cpp:54:7:54:10 | next [post update] [y] |
| conflated.cpp:54:7:54:10 | next [post update] [y] | conflated.cpp:54:3:54:4 | ll [post update] [next, y] |
| conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... |
| conflated.cpp:55:8:55:9 | ll [next, y] | conflated.cpp:55:12:55:15 | next [y] |
| conflated.cpp:55:12:55:15 | next [y] | conflated.cpp:55:18:55:18 | y |
| conflated.cpp:55:18:55:18 | y | realistic.cpp:41:17:41:17 | o |
| conflated.cpp:60:3:60:4 | ll [post update] [next, y] | conflated.cpp:61:8:61:9 | ll [next, y] |
| conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:7:60:10 | next [post update] [y] |
| conflated.cpp:60:7:60:10 | next [post update] [y] | conflated.cpp:60:3:60:4 | ll [post update] [next, y] |
| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... |
| conflated.cpp:61:8:61:9 | ll [next, y] | conflated.cpp:61:12:61:15 | next [y] |
| conflated.cpp:61:12:61:15 | next [y] | conflated.cpp:61:18:61:18 | y |
| conflated.cpp:61:18:61:18 | y | realistic.cpp:41:17:41:17 | o |
| constructors.cpp:18:9:18:9 | this [a_] | constructors.cpp:18:22:18:23 | this [a_] |
| constructors.cpp:18:22:18:23 | this [a_] | constructors.cpp:18:22:18:23 | a_ |
| constructors.cpp:19:9:19:9 | this [b_] | constructors.cpp:19:22:19:23 | this [b_] |
@@ -611,21 +555,18 @@ edges
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
| qualifiers.cpp:23:10:23:14 | outer [inner, a] | qualifiers.cpp:23:16:23:20 | inner [a] |
| qualifiers.cpp:23:16:23:20 | inner [a] | qualifiers.cpp:23:23:23:23 | a |
| qualifiers.cpp:23:23:23:23 | a | realistic.cpp:41:17:41:17 | o |
| qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | qualifiers.cpp:28:10:28:14 | outer [inner, a] |
| qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] |
| qualifiers.cpp:28:10:28:14 | outer [inner, a] | qualifiers.cpp:28:16:28:20 | inner [a] |
| qualifiers.cpp:28:16:28:20 | inner [a] | qualifiers.cpp:28:23:28:23 | a |
| qualifiers.cpp:28:23:28:23 | a | realistic.cpp:41:17:41:17 | o |
| qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | qualifiers.cpp:33:10:33:14 | outer [inner, a] |
| qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
| qualifiers.cpp:33:10:33:14 | outer [inner, a] | qualifiers.cpp:33:16:33:20 | inner [a] |
| qualifiers.cpp:33:16:33:20 | inner [a] | qualifiers.cpp:33:23:33:23 | a |
| qualifiers.cpp:33:23:33:23 | a | realistic.cpp:41:17:41:17 | o |
| qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] |
| qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | qualifiers.cpp:38:10:38:14 | outer [inner, a] |
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] |
@@ -633,7 +574,6 @@ edges
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
| qualifiers.cpp:38:10:38:14 | outer [inner, a] | qualifiers.cpp:38:16:38:20 | inner [a] |
| qualifiers.cpp:38:16:38:20 | inner [a] | qualifiers.cpp:38:23:38:23 | a |
| qualifiers.cpp:38:23:38:23 | a | realistic.cpp:41:17:41:17 | o |
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:6:42:22 | * ... [post update] [a] |
| qualifiers.cpp:42:6:42:22 | * ... [post update] [a] | qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] |
| qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] | qualifiers.cpp:43:10:43:14 | outer [inner, a] |
@@ -641,14 +581,12 @@ edges
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
| qualifiers.cpp:43:10:43:14 | outer [inner, a] | qualifiers.cpp:43:16:43:20 | inner [a] |
| qualifiers.cpp:43:16:43:20 | inner [a] | qualifiers.cpp:43:23:43:23 | a |
| qualifiers.cpp:43:23:43:23 | a | realistic.cpp:41:17:41:17 | o |
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] |
| qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] | qualifiers.cpp:48:10:48:14 | outer [inner, a] |
| qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] | qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] |
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
| qualifiers.cpp:48:23:48:23 | a | realistic.cpp:41:17:41:17 | o |
| realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o |
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] |
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] |
@@ -756,7 +694,6 @@ edges
| struct_init.c:31:23:31:23 | ref arg a | struct_init.c:31:14:31:21 | nestedAB [post update] [a] |
| struct_init.c:33:8:33:12 | outer [pointerAB, a] | struct_init.c:33:14:33:22 | pointerAB [a] |
| struct_init.c:33:14:33:22 | pointerAB [a] | struct_init.c:33:25:33:25 | a |
| struct_init.c:33:25:33:25 | a | realistic.cpp:41:17:41:17 | o |
| struct_init.c:36:10:36:24 | & ... [a] | struct_init.c:14:24:14:25 | ab [a] |
| struct_init.c:36:11:36:15 | outer [nestedAB, a] | struct_init.c:36:17:36:24 | nestedAB [a] |
| struct_init.c:36:17:36:24 | nestedAB [a] | struct_init.c:36:10:36:24 | & ... [a] |

View File

@@ -18,10 +18,6 @@
| test.cpp:302:10:302:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:297:8:297:14 | buffer2 | buffer2 |
| test.cpp:314:10:314:15 | buffer | Variable $@ may not be null terminated. | test.cpp:310:8:310:13 | buffer | buffer |
| test.cpp:336:18:336:23 | buffer | Variable $@ may not be null terminated. | test.cpp:335:8:335:13 | buffer | buffer |
| test.cpp:355:11:355:16 | buffer | Variable $@ may not be null terminated. | test.cpp:350:8:350:13 | buffer | buffer |
| test.cpp:364:11:364:16 | buffer | Variable $@ may not be null terminated. | test.cpp:359:8:359:13 | buffer | buffer |
| test.cpp:392:11:392:16 | buffer | Variable $@ may not be null terminated. | test.cpp:381:8:381:13 | buffer | buffer |
| test.cpp:410:11:410:16 | buffer | Variable $@ may not be null terminated. | test.cpp:397:8:397:13 | buffer | buffer |
| test.cpp:421:19:421:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:419:8:419:14 | buffer2 | buffer2 |
| test.cpp:448:17:448:22 | buffer | Variable $@ may not be null terminated. | test.cpp:446:8:446:13 | buffer | buffer |
| test.cpp:454:18:454:23 | buffer | Variable $@ may not be null terminated. | test.cpp:452:8:452:13 | buffer | buffer |

View File

@@ -352,7 +352,7 @@ void test_strlen(bool cond1, bool cond2)
if (cond1)
buffer[0] = 0;
if (cond1)
strlen(buffer); // GOOD [FALSE POSITIVE]
strlen(buffer); // GOOD
}
{
@@ -361,7 +361,7 @@ void test_strlen(bool cond1, bool cond2)
if (cond1)
buffer[0] = 0;
if (cond2)
strlen(buffer); // BAD
strlen(buffer); // BAD [NOT DETECTED]
}
{
@@ -389,7 +389,7 @@ void test_strlen(bool cond1, bool cond2)
if (init != 0)
{
strlen(buffer); // GOOD [FALSE POSITIVE]
strlen(buffer); // GOOD
}
}
@@ -407,7 +407,7 @@ void test_strlen(bool cond1, bool cond2)
{
// ...
} else {
strlen(buffer); // GOOD [FALSE POSITIVE]
strlen(buffer); // GOOD
}
}
}

View File

@@ -1,8 +1,231 @@
| test.cpp:17:2:17:12 | return ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
| test.cpp:25:2:25:12 | return ... | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
| test.cpp:47:2:47:11 | return ... | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc |
| test.cpp:54:2:54:16 | return ... | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc |
| test.cpp:92:2:92:12 | return ... | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc |
| test.cpp:112:2:112:12 | return ... | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr |
| test.cpp:119:2:119:19 | return ... | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr |
| test.cpp:171:3:171:24 | return ... | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal |
edges
| test.cpp:17:9:17:11 | & ... | test.cpp:17:9:17:11 | StoreValue |
| test.cpp:17:10:17:11 | Unary | test.cpp:17:9:17:11 | & ... |
| test.cpp:17:10:17:11 | mc | test.cpp:17:10:17:11 | Unary |
| test.cpp:23:17:23:19 | & ... | test.cpp:23:17:23:19 | StoreValue |
| test.cpp:23:17:23:19 | Store | test.cpp:25:9:25:11 | Load |
| test.cpp:23:17:23:19 | StoreValue | test.cpp:23:17:23:19 | Store |
| test.cpp:23:18:23:19 | Unary | test.cpp:23:17:23:19 | & ... |
| test.cpp:23:18:23:19 | mc | test.cpp:23:18:23:19 | Unary |
| test.cpp:25:9:25:11 | Load | test.cpp:25:9:25:11 | ptr |
| test.cpp:25:9:25:11 | ptr | test.cpp:25:9:25:11 | StoreValue |
| test.cpp:39:17:39:18 | (reference to) | test.cpp:39:17:39:18 | StoreValue |
| test.cpp:39:17:39:18 | Store | test.cpp:41:10:41:12 | Load |
| test.cpp:39:17:39:18 | StoreValue | test.cpp:39:17:39:18 | Store |
| test.cpp:39:17:39:18 | Unary | test.cpp:39:17:39:18 | (reference to) |
| test.cpp:39:17:39:18 | mc | test.cpp:39:17:39:18 | Unary |
| test.cpp:41:9:41:12 | & ... | test.cpp:41:9:41:12 | StoreValue |
| test.cpp:41:10:41:12 | (reference dereference) | test.cpp:41:10:41:12 | Unary |
| test.cpp:41:10:41:12 | Load | test.cpp:41:10:41:12 | ref |
| test.cpp:41:10:41:12 | Unary | test.cpp:41:9:41:12 | & ... |
| test.cpp:41:10:41:12 | Unary | test.cpp:41:10:41:12 | (reference dereference) |
| test.cpp:41:10:41:12 | ref | test.cpp:41:10:41:12 | Unary |
| test.cpp:47:9:47:10 | (reference to) | test.cpp:47:9:47:10 | StoreValue |
| test.cpp:47:9:47:10 | Unary | test.cpp:47:9:47:10 | (reference to) |
| test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | Unary |
| test.cpp:54:9:54:15 | & ... | test.cpp:54:9:54:15 | StoreValue |
| test.cpp:54:11:54:12 | Unary | test.cpp:54:14:54:14 | a |
| test.cpp:54:11:54:12 | mc | test.cpp:54:11:54:12 | Unary |
| test.cpp:54:14:54:14 | Unary | test.cpp:54:9:54:15 | & ... |
| test.cpp:54:14:54:14 | a | test.cpp:54:14:54:14 | Unary |
| test.cpp:89:3:89:11 | Store | test.cpp:92:9:92:11 | Load |
| test.cpp:89:9:89:11 | & ... | test.cpp:89:9:89:11 | StoreValue |
| test.cpp:89:9:89:11 | StoreValue | test.cpp:89:3:89:11 | Store |
| test.cpp:89:10:89:11 | Unary | test.cpp:89:9:89:11 | & ... |
| test.cpp:89:10:89:11 | mc | test.cpp:89:10:89:11 | Unary |
| test.cpp:92:9:92:11 | Load | test.cpp:92:9:92:11 | ptr |
| test.cpp:92:9:92:11 | ptr | test.cpp:92:9:92:11 | StoreValue |
| test.cpp:112:9:112:11 | Unary | test.cpp:112:9:112:11 | array to pointer conversion |
| test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | Unary |
| test.cpp:112:9:112:11 | array to pointer conversion | test.cpp:112:9:112:11 | StoreValue |
| test.cpp:119:9:119:18 | & ... | test.cpp:119:9:119:18 | StoreValue |
| test.cpp:119:11:119:13 | Left | test.cpp:119:11:119:17 | access to array |
| test.cpp:119:11:119:13 | Unary | test.cpp:119:11:119:13 | array to pointer conversion |
| test.cpp:119:11:119:13 | arr | test.cpp:119:11:119:13 | Unary |
| test.cpp:119:11:119:13 | array to pointer conversion | test.cpp:119:11:119:13 | Left |
| test.cpp:119:11:119:17 | Unary | test.cpp:119:9:119:18 | & ... |
| test.cpp:119:11:119:17 | access to array | test.cpp:119:11:119:17 | Unary |
| test.cpp:134:2:134:14 | Store | test.cpp:135:2:135:4 | Load |
| test.cpp:134:8:134:10 | Left | test.cpp:134:8:134:14 | ... + ... |
| test.cpp:134:8:134:10 | Unary | test.cpp:134:8:134:10 | array to pointer conversion |
| test.cpp:134:8:134:10 | arr | test.cpp:134:8:134:10 | Unary |
| test.cpp:134:8:134:10 | array to pointer conversion | test.cpp:134:8:134:10 | Left |
| test.cpp:134:8:134:14 | ... + ... | test.cpp:134:8:134:14 | StoreValue |
| test.cpp:134:8:134:14 | StoreValue | test.cpp:134:2:134:14 | Store |
| test.cpp:135:2:135:4 | Left | test.cpp:135:2:135:6 | PointerAdd |
| test.cpp:135:2:135:4 | Load | test.cpp:135:2:135:4 | ptr |
| test.cpp:135:2:135:4 | ptr | test.cpp:135:2:135:4 | Left |
| test.cpp:135:2:135:6 | PointerAdd | test.cpp:135:2:135:6 | StoreValue |
| test.cpp:135:2:135:6 | Store | test.cpp:137:9:137:11 | Load |
| test.cpp:135:2:135:6 | StoreValue | test.cpp:135:2:135:6 | Store |
| test.cpp:137:9:137:11 | Load | test.cpp:137:9:137:11 | ptr |
| test.cpp:137:9:137:11 | ptr | test.cpp:137:9:137:11 | StoreValue |
| test.cpp:170:26:170:41 | (void *)... | test.cpp:170:26:170:41 | StoreValue |
| test.cpp:170:26:170:41 | Store | test.cpp:171:10:171:23 | Load |
| test.cpp:170:26:170:41 | StoreValue | test.cpp:170:26:170:41 | Store |
| test.cpp:170:34:170:41 | & ... | test.cpp:170:34:170:41 | Unary |
| test.cpp:170:34:170:41 | Unary | test.cpp:170:26:170:41 | (void *)... |
| test.cpp:170:35:170:41 | Unary | test.cpp:170:34:170:41 | & ... |
| test.cpp:170:35:170:41 | myLocal | test.cpp:170:35:170:41 | Unary |
| test.cpp:171:10:171:23 | Load | test.cpp:171:10:171:23 | pointerToLocal |
| test.cpp:171:10:171:23 | pointerToLocal | test.cpp:171:10:171:23 | StoreValue |
| test.cpp:176:25:176:34 | Store | test.cpp:177:10:177:23 | Load |
| test.cpp:176:25:176:34 | StoreValue | test.cpp:176:25:176:34 | Store |
| test.cpp:176:25:176:34 | Unary | test.cpp:176:25:176:34 | array to pointer conversion |
| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:176:25:176:34 | StoreValue |
| test.cpp:176:25:176:34 | localArray | test.cpp:176:25:176:34 | Unary |
| test.cpp:177:10:177:23 | (void *)... | test.cpp:177:10:177:23 | StoreValue |
| test.cpp:177:10:177:23 | Load | test.cpp:177:10:177:23 | pointerToLocal |
| test.cpp:177:10:177:23 | Unary | test.cpp:177:10:177:23 | (void *)... |
| test.cpp:177:10:177:23 | pointerToLocal | test.cpp:177:10:177:23 | Unary |
| test.cpp:182:21:182:27 | (reference to) | test.cpp:182:21:182:27 | StoreValue |
| test.cpp:182:21:182:27 | Store | test.cpp:183:10:183:19 | Load |
| test.cpp:182:21:182:27 | StoreValue | test.cpp:182:21:182:27 | Store |
| test.cpp:182:21:182:27 | Unary | test.cpp:182:21:182:27 | (reference to) |
| test.cpp:182:21:182:27 | myLocal | test.cpp:182:21:182:27 | Unary |
| test.cpp:183:10:183:19 | (reference dereference) | test.cpp:183:10:183:19 | Unary |
| test.cpp:183:10:183:19 | (reference to) | test.cpp:183:10:183:19 | StoreValue |
| test.cpp:183:10:183:19 | Load | test.cpp:183:10:183:19 | refToLocal |
| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference dereference) |
| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference to) |
| test.cpp:183:10:183:19 | refToLocal | test.cpp:183:10:183:19 | Unary |
| test.cpp:189:16:189:16 | (reference to) | test.cpp:189:16:189:16 | StoreValue |
| test.cpp:189:16:189:16 | Store | test.cpp:190:10:190:13 | Load |
| test.cpp:189:16:189:16 | StoreValue | test.cpp:189:16:189:16 | Store |
| test.cpp:189:16:189:16 | Unary | test.cpp:189:16:189:16 | (reference to) |
| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | Unary |
| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | Unary |
| test.cpp:190:10:190:13 | (reference to) | test.cpp:190:10:190:13 | StoreValue |
| test.cpp:190:10:190:13 | Load | test.cpp:190:10:190:13 | pRef |
| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference dereference) |
| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference to) |
| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | Unary |
nodes
| test.cpp:17:9:17:11 | & ... | semmle.label | & ... |
| test.cpp:17:9:17:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:17:10:17:11 | Unary | semmle.label | Unary |
| test.cpp:17:10:17:11 | mc | semmle.label | mc |
| test.cpp:23:17:23:19 | & ... | semmle.label | & ... |
| test.cpp:23:17:23:19 | Store | semmle.label | Store |
| test.cpp:23:17:23:19 | StoreValue | semmle.label | StoreValue |
| test.cpp:23:18:23:19 | Unary | semmle.label | Unary |
| test.cpp:23:18:23:19 | mc | semmle.label | mc |
| test.cpp:25:9:25:11 | Load | semmle.label | Load |
| test.cpp:25:9:25:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:25:9:25:11 | ptr | semmle.label | ptr |
| test.cpp:39:17:39:18 | (reference to) | semmle.label | (reference to) |
| test.cpp:39:17:39:18 | Store | semmle.label | Store |
| test.cpp:39:17:39:18 | StoreValue | semmle.label | StoreValue |
| test.cpp:39:17:39:18 | Unary | semmle.label | Unary |
| test.cpp:39:17:39:18 | mc | semmle.label | mc |
| test.cpp:41:9:41:12 | & ... | semmle.label | & ... |
| test.cpp:41:9:41:12 | StoreValue | semmle.label | StoreValue |
| test.cpp:41:10:41:12 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:41:10:41:12 | Load | semmle.label | Load |
| test.cpp:41:10:41:12 | Unary | semmle.label | Unary |
| test.cpp:41:10:41:12 | Unary | semmle.label | Unary |
| test.cpp:41:10:41:12 | ref | semmle.label | ref |
| test.cpp:47:9:47:10 | (reference to) | semmle.label | (reference to) |
| test.cpp:47:9:47:10 | StoreValue | semmle.label | StoreValue |
| test.cpp:47:9:47:10 | Unary | semmle.label | Unary |
| test.cpp:47:9:47:10 | mc | semmle.label | mc |
| test.cpp:54:9:54:15 | & ... | semmle.label | & ... |
| test.cpp:54:9:54:15 | StoreValue | semmle.label | StoreValue |
| test.cpp:54:11:54:12 | Unary | semmle.label | Unary |
| test.cpp:54:11:54:12 | mc | semmle.label | mc |
| test.cpp:54:14:54:14 | Unary | semmle.label | Unary |
| test.cpp:54:14:54:14 | a | semmle.label | a |
| test.cpp:89:3:89:11 | Store | semmle.label | Store |
| test.cpp:89:9:89:11 | & ... | semmle.label | & ... |
| test.cpp:89:9:89:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:89:10:89:11 | Unary | semmle.label | Unary |
| test.cpp:89:10:89:11 | mc | semmle.label | mc |
| test.cpp:92:9:92:11 | Load | semmle.label | Load |
| test.cpp:92:9:92:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:92:9:92:11 | ptr | semmle.label | ptr |
| test.cpp:112:9:112:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:112:9:112:11 | Unary | semmle.label | Unary |
| test.cpp:112:9:112:11 | arr | semmle.label | arr |
| test.cpp:112:9:112:11 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:119:9:119:18 | & ... | semmle.label | & ... |
| test.cpp:119:9:119:18 | StoreValue | semmle.label | StoreValue |
| test.cpp:119:11:119:13 | Left | semmle.label | Left |
| test.cpp:119:11:119:13 | Unary | semmle.label | Unary |
| test.cpp:119:11:119:13 | arr | semmle.label | arr |
| test.cpp:119:11:119:13 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:119:11:119:17 | Unary | semmle.label | Unary |
| test.cpp:119:11:119:17 | access to array | semmle.label | access to array |
| test.cpp:134:2:134:14 | Store | semmle.label | Store |
| test.cpp:134:8:134:10 | Left | semmle.label | Left |
| test.cpp:134:8:134:10 | Unary | semmle.label | Unary |
| test.cpp:134:8:134:10 | arr | semmle.label | arr |
| test.cpp:134:8:134:10 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:134:8:134:14 | ... + ... | semmle.label | ... + ... |
| test.cpp:134:8:134:14 | StoreValue | semmle.label | StoreValue |
| test.cpp:135:2:135:4 | Left | semmle.label | Left |
| test.cpp:135:2:135:4 | Load | semmle.label | Load |
| test.cpp:135:2:135:4 | ptr | semmle.label | ptr |
| test.cpp:135:2:135:6 | PointerAdd | semmle.label | PointerAdd |
| test.cpp:135:2:135:6 | Store | semmle.label | Store |
| test.cpp:135:2:135:6 | StoreValue | semmle.label | StoreValue |
| test.cpp:137:9:137:11 | Load | semmle.label | Load |
| test.cpp:137:9:137:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:137:9:137:11 | ptr | semmle.label | ptr |
| test.cpp:170:26:170:41 | (void *)... | semmle.label | (void *)... |
| test.cpp:170:26:170:41 | Store | semmle.label | Store |
| test.cpp:170:26:170:41 | StoreValue | semmle.label | StoreValue |
| test.cpp:170:34:170:41 | & ... | semmle.label | & ... |
| test.cpp:170:34:170:41 | Unary | semmle.label | Unary |
| test.cpp:170:35:170:41 | Unary | semmle.label | Unary |
| test.cpp:170:35:170:41 | myLocal | semmle.label | myLocal |
| test.cpp:171:10:171:23 | Load | semmle.label | Load |
| test.cpp:171:10:171:23 | StoreValue | semmle.label | StoreValue |
| test.cpp:171:10:171:23 | pointerToLocal | semmle.label | pointerToLocal |
| test.cpp:176:25:176:34 | Store | semmle.label | Store |
| test.cpp:176:25:176:34 | StoreValue | semmle.label | StoreValue |
| test.cpp:176:25:176:34 | Unary | semmle.label | Unary |
| test.cpp:176:25:176:34 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:176:25:176:34 | localArray | semmle.label | localArray |
| test.cpp:177:10:177:23 | (void *)... | semmle.label | (void *)... |
| test.cpp:177:10:177:23 | Load | semmle.label | Load |
| test.cpp:177:10:177:23 | StoreValue | semmle.label | StoreValue |
| test.cpp:177:10:177:23 | Unary | semmle.label | Unary |
| test.cpp:177:10:177:23 | pointerToLocal | semmle.label | pointerToLocal |
| test.cpp:182:21:182:27 | (reference to) | semmle.label | (reference to) |
| test.cpp:182:21:182:27 | Store | semmle.label | Store |
| test.cpp:182:21:182:27 | StoreValue | semmle.label | StoreValue |
| test.cpp:182:21:182:27 | Unary | semmle.label | Unary |
| test.cpp:182:21:182:27 | myLocal | semmle.label | myLocal |
| test.cpp:183:10:183:19 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:183:10:183:19 | (reference to) | semmle.label | (reference to) |
| test.cpp:183:10:183:19 | Load | semmle.label | Load |
| test.cpp:183:10:183:19 | StoreValue | semmle.label | StoreValue |
| test.cpp:183:10:183:19 | Unary | semmle.label | Unary |
| test.cpp:183:10:183:19 | Unary | semmle.label | Unary |
| test.cpp:183:10:183:19 | refToLocal | semmle.label | refToLocal |
| test.cpp:189:16:189:16 | (reference to) | semmle.label | (reference to) |
| test.cpp:189:16:189:16 | Store | semmle.label | Store |
| test.cpp:189:16:189:16 | StoreValue | semmle.label | StoreValue |
| test.cpp:189:16:189:16 | Unary | semmle.label | Unary |
| test.cpp:189:16:189:16 | p | semmle.label | p |
| test.cpp:190:10:190:13 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:190:10:190:13 | (reference to) | semmle.label | (reference to) |
| test.cpp:190:10:190:13 | Load | semmle.label | Load |
| test.cpp:190:10:190:13 | StoreValue | semmle.label | StoreValue |
| test.cpp:190:10:190:13 | Unary | semmle.label | Unary |
| test.cpp:190:10:190:13 | Unary | semmle.label | Unary |
| test.cpp:190:10:190:13 | pRef | semmle.label | pRef |
#select
| test.cpp:17:9:17:11 | StoreValue | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
| test.cpp:25:9:25:11 | StoreValue | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
| test.cpp:41:9:41:12 | StoreValue | test.cpp:39:17:39:18 | mc | test.cpp:41:9:41:12 | StoreValue | May return stack-allocated memory from $@. | test.cpp:39:17:39:18 | mc | mc |
| test.cpp:47:9:47:10 | StoreValue | test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | StoreValue | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc |
| test.cpp:54:9:54:15 | StoreValue | test.cpp:54:11:54:12 | mc | test.cpp:54:9:54:15 | StoreValue | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc |
| test.cpp:92:9:92:11 | StoreValue | test.cpp:89:10:89:11 | mc | test.cpp:92:9:92:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc |
| test.cpp:112:9:112:11 | StoreValue | test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr |
| test.cpp:119:9:119:18 | StoreValue | test.cpp:119:11:119:13 | arr | test.cpp:119:9:119:18 | StoreValue | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr |
| test.cpp:137:9:137:11 | StoreValue | test.cpp:134:8:134:10 | arr | test.cpp:137:9:137:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:134:8:134:10 | arr | arr |
| test.cpp:171:10:171:23 | StoreValue | test.cpp:170:35:170:41 | myLocal | test.cpp:171:10:171:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal |
| test.cpp:177:10:177:23 | StoreValue | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray |
| test.cpp:183:10:183:19 | StoreValue | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | StoreValue | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal |
| test.cpp:190:10:190:13 | StoreValue | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | StoreValue | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p |

View File

@@ -38,7 +38,7 @@ MyClass *test4()
MyClass mc;
MyClass &ref = mc;
return &ref; // BAD [NOT DETECTED]
return &ref; // BAD
}
MyClass &test5()
@@ -134,7 +134,7 @@ char *testArray4()
ptr = arr + 1;
ptr++;
return ptr; // BAD [NOT DETECTED]
return ptr; // BAD
}
char *testArray5()
@@ -174,20 +174,20 @@ void *conversionBeforeDataFlow() {
void *arrayConversionBeforeDataFlow() {
int localArray[4];
int *pointerToLocal = localArray; // has conversion
return pointerToLocal; // BAD [NOT DETECTED]
return pointerToLocal; // BAD
}
int &dataFlowThroughReference() {
int myLocal;
int &refToLocal = myLocal; // has conversion
return refToLocal; // BAD [NOT DETECTED]
return refToLocal; // BAD
}
int *&conversionInFlow() {
int myLocal;
int *p = &myLocal;
int *&pRef = p; // has conversion in the middle of data flow
return pRef; // BAD [NOT DETECTED]
return pRef; // BAD
}
namespace std {
@@ -215,4 +215,9 @@ auto make_read_port()
auto port = std::shared_ptr<int>(new int);
auto ptr = port.get();
return ptr; // GOOD
}
void* get_sp() {
int p;
return (void*)&p; // GOOD: The function name makes it sound like the programmer intended to get the value of the stack pointer.
}

View File

@@ -0,0 +1 @@
Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql

View File

@@ -0,0 +1 @@
Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql

View File

@@ -1,21 +0,0 @@
| tests2.cpp:17:3:17:8 | call to wcscpy | This 'call to wcscpy' operation requires 12 bytes but the destination is only 8 bytes. |
| tests2.cpp:22:3:22:8 | call to wcscpy | This 'call to wcscpy' operation requires 16 bytes but the destination is only 12 bytes. |
| tests2.cpp:27:3:27:8 | call to wcscpy | This 'call to wcscpy' operation requires 20 bytes but the destination is only 16 bytes. |
| tests2.cpp:31:3:31:8 | call to wcscpy | This 'call to wcscpy' operation requires 24 bytes but the destination is only 20 bytes. |
| tests2.cpp:36:3:36:8 | call to wcscpy | This 'call to wcscpy' operation requires 28 bytes but the destination is only 24 bytes. |
| tests2.cpp:41:3:41:8 | call to wcscpy | This 'call to wcscpy' operation requires 32 bytes but the destination is only 28 bytes. |
| tests2.cpp:46:3:46:8 | call to wcscpy | This 'call to wcscpy' operation requires 36 bytes but the destination is only 32 bytes. |
| tests.c:54:3:54:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
| tests.c:58:3:58:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
| tests.c:62:17:62:24 | buffer10 | This 'scanf string argument' operation requires 11 bytes but the destination is only 10 bytes. |
| tests.c:63:17:63:24 | buffer10 | This 'scanf string argument' operation requires 12 bytes but the destination is only 10 bytes. |
| tests.c:86:3:86:8 | call to strcpy | This 'call to strcpy' operation requires 6 bytes but the destination is only 5 bytes. |
| tests.c:93:3:93:8 | call to strcpy | This 'call to strcpy' operation requires 6 bytes but the destination is only 5 bytes. |
| tests.c:120:3:120:9 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 1 bytes. |
| tests.c:121:3:121:9 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 16 bytes. |
| tests.c:136:2:136:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
| unions.c:32:2:32:7 | call to strcpy | This 'call to strcpy' operation requires 31 bytes but the destination is only 25 bytes. |
| var_size_struct.cpp:22:3:22:8 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 9 bytes. |

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