Compare commits

..

222 Commits

Author SHA1 Message Date
Arthur Baars
ff65ffafb0 Merge pull request #14830 from aibaars/csharp/fixintegrationtests
C# fix integration tests
2023-11-17 11:17:31 +01:00
Michael B. Gale
97402fdf36 C#: Fix dotnet_test_mstest 2023-11-17 10:35:14 +01:00
Michael Nebel
2662a4c651 C#: Fix the dotnet pack integration test. 2023-11-17 10:35:14 +01:00
Arthur Baars
dce03569e5 Merge pull request #14813 from github/release-prep/2.15.3
Release preparation for version 2.15.3
2023-11-16 18:42:17 +01:00
github-actions[bot]
6ec9b95072 Release preparation for version 2.15.3 2023-11-16 13:07:16 +00:00
Arthur Baars
641646ac08 Rename change note 2023-11-16 14:04:25 +01:00
Tom Hvitved
75f42f4614 Merge pull request #14783 from hvitved/ruby/hash-array-literal
Ruby: Include more nodes in `{Hash,Array}LiteralCfgNode`
2023-11-16 13:51:35 +01:00
Henry Mercer
0c1fb8c881 Merge pull request #14811 from github/henrymercer/remove-lines-of-non-user-code-from-summary
Remove LoC metrics from the analysis summary
2023-11-16 12:30:55 +00:00
Rasmus Wriedt Larsen
4f9303eb02 Merge pull request #14790 from RasmusWL/clean-tests
Python: Accept new ordering of query predicates in `.expected`
2023-11-16 13:23:35 +01:00
Tom Hvitved
2c23dacca1 Ruby: Add more hash/array literal tests 2023-11-16 12:58:53 +01:00
Henry Mercer
de83929a60 Remove LoC metrics from the analysis summary 2023-11-16 11:36:44 +00:00
Stephan Brandauer
f1001374fd Merge pull request #14642 from github/kaeluka/publish-automodel-querypack-007
Java: Publish Automodel query pack 0.0.7
2023-11-16 11:50:32 +01:00
Rasmus Wriedt Larsen
25d3af9236 Merge branch 'main' into clean-tests 2023-11-16 11:21:01 +01:00
Jeroen Ketema
1f3f1b5ec4 Merge pull request #14809 from MathiasVP/move-change-note
C++: Move change note
2023-11-16 11:14:14 +01:00
Mathias Vorreiter Pedersen
5c0fb2030d C++: Move change note. 2023-11-16 09:57:08 +00:00
Rasmus Wriedt Larsen
71ef98584d Merge pull request #14791 from RasmusWL/python-3.12
Python: Update `.expected` to support Python 3.12
2023-11-16 10:42:48 +01:00
Tom Hvitved
6bba191407 Merge pull request #14710 from hvitved/type-tracking/prepare-ruby
Prepare shared type tracking library for adoption by Ruby
2023-11-16 10:34:32 +01:00
Rasmus Wriedt Larsen
df144f3a1e Merge pull request #14406 from amammad/amammad-python-FileSystemAccess
Python: New FileSystem Access
2023-11-16 10:25:34 +01:00
Rasmus Wriedt Larsen
a46dc55e84 Merge branch 'main' into python-3.12 2023-11-16 09:34:06 +01:00
Tamás Vajk
14268f3c63 Merge pull request #14792 from tamasvajk/standalone/assembly-attribute
C#: Fix assembly attribute extraction in standalone mode
2023-11-16 08:09:14 +01:00
Sam Browning
408ba517e5 Merge pull request #14776 from github/sabrowning1/queries-panel-language-selector
Add content for the queries panel and language selector
2023-11-15 17:30:21 -05:00
Mathias Vorreiter Pedersen
4d4ca6b948 Merge pull request #14794 from MathiasVP/catch-more-return-stack-allocated-memory
C++: Catch more returns of stack-allocated memory
2023-11-15 19:23:24 +00:00
Sam Browning
d443354651 Apply feedback and fix syntax 2023-11-15 11:35:33 -05:00
Tom Hvitved
57f6859ddc Shared: Update type tracking consistency checks 2023-11-15 17:08:05 +01:00
Tom Hvitved
5f087f0084 Shared: Port features from Ruby's type tracking library to the shared library
- Cache relevant predicates.
- Expose some predicates and classes (only exposed internally).
- Make some top-level `inline_late` predicates member predicates.
- Actually eliminate type check in `flowsTo`.
- Fix bug in `getACompatibleTypeTracker`.
- Adopt the `CallGraphConstruction` module.
2023-11-15 17:08:05 +01:00
Tom Hvitved
f66f7ce8d7 Shared: Split up TypeTracking.qll into two files 2023-11-15 17:07:27 +01:00
Jeroen Ketema
f22979f4b6 Merge pull request #14561 from jketema/rewrite-uncontrolled-process-operation
C++: Rewrite `cpp/uncontrolled-process-operation` to not use `DefaultTaintTracking`
2023-11-15 16:03:58 +01:00
Jeroen Ketema
46e6e72593 C++: Address review comments 2023-11-15 14:57:53 +01:00
Jeroen Ketema
92c18960c5 C++: Rewrite cpp/uncontrolled-process-operation to not use DefaultTaintTracking 2023-11-15 14:57:53 +01:00
Rasmus Wriedt Larsen
e349891cff Python: Apply suggestions from code review 2023-11-15 14:35:52 +01:00
Rasmus Wriedt Larsen
e02c32f3d4 Python: options file was not enough, split into 2/3
I reckon this is due to the Python 3 version used by the Python 2 tests
is different from 3.12, so even with --lang=3 the tests are still using
an incompatible version :(
2023-11-15 14:24:11 +01:00
Rasmus Wriedt Larsen
0f1dc9b2d9 Python: Add missing options file 2023-11-15 13:24:08 +01:00
Rasmus Wriedt Larsen
ae6c95ff95 Python: Fix asyncio.coroutine deprecation
Was removed in 3.11, see https://docs.python.org/3.10/library/asyncio-task.html#asyncio.coroutine

I couldn't make the __awwait__ actually give the result to the agen function...

I also tried looking into
https://docs.python.org/3/library/types.html#types.coroutine, but also
failed to make that work.

Without the Future, such as doing `yield SOURCE` inside `__await__` it
complains `RuntimeError: Task got bad yield: 'source'`
2023-11-15 13:24:08 +01:00
Mathias Vorreiter Pedersen
bae7e10e46 C++: Also add MSVC-related 'alloca'-like functions. 2023-11-15 12:07:17 +00:00
Mathias Vorreiter Pedersen
ec63099c54 C++: Add change note. 2023-11-15 11:57:09 +00:00
Mathias Vorreiter Pedersen
2b8b5cf1b8 C++: Accept test changes. 2023-11-15 11:52:14 +00:00
Mathias Vorreiter Pedersen
6730f57d5c C++: Also flag up 'alloca' and friends. 2023-11-15 11:51:57 +00:00
Mathias Vorreiter Pedersen
118d50236f C++: Add failing tests. 2023-11-15 11:48:37 +00:00
Tamas Vajk
7a001f4905 C#: Fix assembly attribute extraction in standalone mode 2023-11-15 12:21:03 +01:00
Owen Mansel-Chan
803ed20962 Merge pull request #14778 from owen-mc/go/improve-value-flow-through-arrays
Go: improve value flow through arrays
2023-11-15 11:13:15 +00:00
Rasmus Wriedt Larsen
4256fbf11a Python: Accept changes from Python 3.12 2023-11-15 11:42:38 +01:00
Rasmus Wriedt Larsen
f3dd002ba9 Python: Copy tests to Python 3 2023-11-15 11:42:38 +01:00
Rasmus Wriedt Larsen
f9e9ae91f7 Python: Move tests that would change under Python 3.12 to lang specific directory
This moves the tests to Python 2, next we copy them to Python 3.
2023-11-15 11:42:38 +01:00
Rasmus Wriedt Larsen
23419ee634 Python: Update .expected to support Python 3.12
You might wonder why the number of lines changed, but it's due to `tty`
module receiving its' first update since 2001, so the actual number of
lines DID change :phew:

https://github.com/python/cpython/commits/3.12/Lib/tty.py

Since there is now a difference between Python 2 and Python 3, we need to restrict the lines of code test to only run as Python 3.
2023-11-15 11:42:38 +01:00
Mathias Vorreiter Pedersen
b8f0f85840 Merge pull request #14784 from MathiasVP/no-dtt-in-tainted-arithmetic
C++: Rewrite `cpp/tainted-arithmetic` away from `DefaultTaintTracking`
2023-11-15 10:19:25 +00:00
Rasmus Wriedt Larsen
69453aa144 Python: Fix missing newline in .expected 2023-11-15 10:10:23 +01:00
Rasmus Wriedt Larsen
55f5b26ba6 Python: Accept new ordering of query predicates in .expected 2023-11-15 10:09:54 +01:00
Rasmus Wriedt Larsen
721bde1ce8 Python: Delete orphaned .expected files 2023-11-15 09:59:26 +01:00
Rasmus Wriedt Larsen
2e9d548083 Merge pull request #14706 from RasmusWL/class-attribute-flow
Python: Add basic flow for class attributes
2023-11-15 09:06:25 +01:00
Owen Mansel-Chan
83d1fc33e1 Add change note 2023-11-14 23:16:32 +00:00
Erik Krogh Kristensen
14e51627c5 Merge pull request #14419 from rvermeulen/rvermeulen/javascript-adjust-security-severity
JavaScript: Adjust XSS and log injection query severities
2023-11-14 21:34:25 +01:00
Remco Vermeulen
52540b42fc Merge branch 'main' into rvermeulen/javascript-adjust-security-severity 2023-11-14 11:21:38 -08:00
Remco Vermeulen
6bd7047e41 Restore XssThroughDom.ql's severity 2023-11-14 11:20:51 -08:00
AlexDenisov
57f1f5b829 Merge pull request #14768 from github/alexdenisov/move-semantics
Swift: extract AST nodes related to move semantics
2023-11-14 19:13:27 +01:00
Mathias Vorreiter Pedersen
bff93c4484 Merge branch 'main' into no-dtt-in-tainted-arithmetic 2023-11-14 17:12:34 +00:00
Geoffrey White
0342b3eba2 Merge pull request #14772 from geoffw0/webview
Swift: Use TaintInheritingContent in WebView.qll
2023-11-14 16:29:32 +00:00
Geoffrey White
d28e7920b3 Merge pull request #14773 from geoffw0/fixmodel
Swift: Fix odds and ends
2023-11-14 16:28:33 +00:00
Tamás Vajk
331ca61be9 Merge pull request #14789 from tamasvajk/autobuild/arm-nuget-restore
C#: Do not call nuget.exe on Apple Silicon
2023-11-14 17:13:42 +01:00
Alex Denisov
559b965e74 Swift: add change note 2023-11-14 16:11:28 +01:00
Felicity Chapman
6299b844f8 Merge pull request #14785 from github/felicitymay-security-severity
Update metadata-for-codeql-queries.rst
2023-11-14 14:13:53 +00:00
Sam Browning
4385b316c0 Apply feedback from code review 2023-11-14 09:10:07 -05:00
Sam Browning
b1dc6099ff Apply feedback from code review 2023-11-14 09:01:54 -05:00
Sam Browning
15099b3db0 Update docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
2023-11-14 08:57:52 -05:00
Tamas Vajk
8334c6db91 C#: Do not call nuget.exe on Apple Silicon 2023-11-14 14:50:29 +01:00
Alex Denisov
1c75e5b2a6 Swift: add database migration scripts for move semantics 2023-11-14 14:35:58 +01:00
Mathias Vorreiter Pedersen
1623bba18a Merge branch 'main' into no-dtt-in-tainted-arithmetic 2023-11-14 13:35:15 +00:00
Tom Hvitved
475d8da342 Ruby: Include more nodes in {Hash,Array}LiteralCfgNode 2023-11-14 13:50:46 +01:00
Tom Hvitved
ae09499905 Merge pull request #14781 from hvitved/ruby/ssa-unitialized-to-string
Ruby: Include name of variable in `UninitializedDefinition.toString`
2023-11-14 13:49:27 +01:00
Mathias Vorreiter Pedersen
c950e26b3e C++: Rewrite 'cpp/cpp/tainted-arithmetic' away from DefaultTaintTracking. 2023-11-14 12:19:12 +00:00
Felicity Chapman
f75c062949 Update metadata-for-codeql-queries.rst
Replace link to blog with trackable GH.io link
2023-11-14 12:06:44 +00:00
Mathias Vorreiter Pedersen
f22d87b7c7 Merge pull request #14771 from MathiasVP/fix-missing-unbounded-write-results
C++: Fix missing results in `cpp/unbounded-write`
2023-11-14 12:03:13 +00:00
Tamás Vajk
e11a68803e Merge pull request #14782 from github/criemen/disable-int-test
Disable the nuget standalone dependencies test on ARM-osx.
2023-11-14 12:32:48 +01:00
Owen Mansel-Chan
45faed057c Improve SliceExpr documentation 2023-11-14 11:25:16 +00:00
Tom Hvitved
f1b67ade9b Ruby: Include name of variable in UninitializedDefinition.toString 2023-11-14 11:33:59 +01:00
Cornelius Riemenschneider
f9ae7c5454 Disable the nuget standalone dependencies test on ARM-osx.
The test is failing currently, and that needs further investigation.
This is a temporary workaround to allow us to continue to work on
some necessary infrastructure investments around these tests.
2023-11-14 11:13:55 +01:00
Geoffrey White
296dee90dd Merge remote-tracking branch 'upstream/main' into fixmodel 2023-11-14 09:38:14 +00:00
Mathias Vorreiter Pedersen
967bbbc1a7 C++: Block flow out of sinks that are qualifiers. This removes the new result duplication and keeps the new result. 2023-11-14 09:29:47 +00:00
Tamás Vajk
28a5a1d507 Merge pull request #14760 from tamasvajk/apple-silicon-check
C#: Change IsARM to Apple silicon check
2023-11-14 10:27:42 +01:00
Tamas Vajk
5b38ba87df Code quality improvement 2023-11-14 08:08:46 +01:00
Erik Krogh Kristensen
db42b60015 Merge pull request #14779 from github/dependabot/cargo/ql/tracing-subscriber-0.3.18
Bump tracing-subscriber from 0.3.17 to 0.3.18 in /ql
2023-11-14 07:57:55 +01:00
dependabot[bot]
f8c8d59cb5 Bump tracing-subscriber from 0.3.17 to 0.3.18 in /ql
Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.3.17 to 0.3.18.
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.3.17...tracing-subscriber-0.3.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-14 03:56:51 +00:00
Owen Mansel-Chan
c8779d0d0b Fix another test
No change in alerts, just 3 extra nodes.
2023-11-13 23:56:25 +00:00
Owen Mansel-Chan
28160e418c Update tests 2023-11-13 23:26:30 +00:00
Owen Mansel-Chan
ed349f7d6b Improve value flow through arrays 2023-11-13 23:26:16 +00:00
Sam Browning
fa569dcef4 Delete requirements.txt 2023-11-13 17:28:14 -05:00
Sam Browning
040d971588 Merge branch 'main' into sabrowning1/queries-panel-language-selector 2023-11-13 17:27:35 -05:00
Sam Browning
e95bfc816e Clarify that queries run against selected database 2023-11-13 17:15:41 -05:00
Sam Browning
44935cef63 Tweak for style 2023-11-13 17:08:31 -05:00
Sam Browning
190050f577 Tweak formatting and styling 2023-11-13 16:52:33 -05:00
Sam Browning
458baeff32 Add content on queries panel and language selector 2023-11-13 15:59:51 -05:00
Geoffrey White
c14d4042e0 Merge pull request #14748 from geoffw0/pathinjectionsinks
Swift: Add more path injection sinks
2023-11-13 20:15:16 +00:00
Geoffrey White
5a451e964d Swift: Model mainDocumentURL. 2023-11-13 19:51:51 +00:00
Geoffrey White
b157d73c10 Swift: Make the URLRequest test more accurate. 2023-11-13 19:36:03 +00:00
Geoffrey White
985d1990eb Swift: Fix typo. 2023-11-13 18:55:11 +00:00
Geoffrey White
463096e4be Swift: Modernize tainted content in WebView.qll. 2023-11-13 18:30:40 +00:00
Geoffrey White
892beeab6d Swift: Add test case. 2023-11-13 18:25:59 +00:00
Geoffrey White
9ec2f9204b Swift: Correct components(separatedBy:) models. 2023-11-13 17:43:21 +00:00
Mathias Vorreiter Pedersen
c73e6f1fa8 C++: Accept more test changes. 2023-11-13 16:51:07 +00:00
Mathias Vorreiter Pedersen
9aafbfce13 C++: Fix test annotation. 2023-11-13 16:17:18 +00:00
Mathias Vorreiter Pedersen
cc6268339b C++: Fix failing test and accept test cases. 2023-11-13 15:57:22 +00:00
Mathias Vorreiter Pedersen
834b07e6ad C++: Add failing tests. 2023-11-13 15:54:41 +00:00
Mathias Vorreiter Pedersen
8be6aeda3e Merge pull request #14769 from MathiasVP/fix-nonterminating-test
C++: Fix nonterminating test
2023-11-13 15:49:39 +00:00
Owen Mansel-Chan
359dcf37e9 Merge pull request #14649 from Kwstubbs/go-cors
Go: Add Cors Gin Support
2023-11-13 15:46:59 +00:00
Mathias Vorreiter Pedersen
eb263e747f C++: Make sure the test terminates. 2023-11-13 15:25:48 +00:00
Mathias Vorreiter Pedersen
bc576f658e C++: Add a test that fails because of a non-terminating test that dominates this one. 2023-11-13 15:24:56 +00:00
Geoffrey White
6f56a656e4 Merge pull request #14761 from geoffw0/moderntest
Swift: Update the inline dataflow tests
2023-11-13 14:59:08 +00:00
Alex Denisov
031f453af8 Swift: CFG for Copy/Consume expressions 2023-11-13 15:55:37 +01:00
Alex Denisov
002f2a0985 Swift: extract BorrowExpr 2023-11-13 15:55:37 +01:00
Alex Denisov
d21e27c717 Swift: extract ConsumeExpr 2023-11-13 15:55:37 +01:00
Alex Denisov
30e4822fb7 Swift: extract CopyExpr 2023-11-13 15:55:37 +01:00
Owen Mansel-Chan
d931ade182 Merge pull request #13366 from maikypedia/maikypedia/go-ldap-improper-auth
Go: Add Improper LDAP Authentication query (CWE-287)
2023-11-13 14:48:19 +00:00
Sam Browning
ed9a0ea155 Merge branch 'main' of https://github.com/github/codeql 2023-11-13 08:40:42 -05:00
Geoffrey White
c3577b34d3 Swift: Clean up logic. 2023-11-13 12:37:35 +00:00
Geoffrey White
e4da8da5d9 Swift: Update the example code. 2023-11-13 12:33:20 +00:00
Tamas Vajk
b455b2c1a6 C#: Change IsARM to Apple silicon check 2023-11-13 13:20:13 +01:00
Anders Schack-Mulligen
dc4dda1dbc Merge pull request #14757 from aschackmull/rangeanalysis/simplify
Rangeanalysis: Misc simplifications
2023-11-13 13:16:04 +01:00
Geoffrey White
098ea50068 Swift: Repair non-inline dataflow test. 2023-11-13 12:09:08 +00:00
Geoffrey White
6e291711ac Swift: Update just enough tests to prove that that source labels are working. 2023-11-13 11:47:24 +00:00
Geoffrey White
fca6ccd2f1 Swift: Remove more unused code. 2023-11-13 11:47:22 +00:00
AlexDenisov
291bb2210c Merge pull request #14759 from github/alexdenisov/experimental-tuple
Swift: mark BuiltinTuple as experimental
2023-11-13 12:24:06 +01:00
Geoffrey White
4bf717c3e4 Swift: Use InlineFlowTest.qll in the data flow inline tests, so that we have less code duplication and can use flow labels. 2023-11-13 11:06:05 +00:00
Geoffrey White
d15c46836b Swift: Add features tom InlineFlowTest.qll: extended source/sink names, custom flow tags, use of line-numbers as a fallback value. 2023-11-13 10:55:17 +00:00
Alex Denisov
c0fce80b7d Swift: mark BuiltinTuple as experimental 2023-11-13 11:34:51 +01:00
Cornelius Riemenschneider
1b7e3814b0 Merge pull request #14719 from github/criemen/java-int-tests
Java integration tests: More preparations to be executed on GH M1 machines
2023-11-13 11:16:51 +01:00
Anders Schack-Mulligen
bf6cfd3bef Rangeanalysis: Simplify api. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
30aefabb2a Rangeanalysis: Rename predicate. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
f05b75e04f Rangeanalysis: RIP standard order. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
c28f54a78b Rangeanalysis: Remove superfluous pragmas. These appear useless after the abolishment of the different delta orders. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
66b03bfb12 Java: Remove unused import 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
71e25521cf Rangeanalysis: Use SsaReadPositionBlock.getAnSsaRead. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
27e6173bb7 C++: Remove SemSsaExplicitUpdate.getSourceExpr. 2023-11-13 10:35:43 +01:00
Anders Schack-Mulligen
3a73faf061 Rangeanalysis: Remove unused getAlternateType predicates. 2023-11-13 10:35:43 +01:00
AlexDenisov
352ec91a08 Merge pull request #14756 from github/alexdenisov/do-not-extract-non-ast-types
Swift: do not extract non-AST types, NFC
2023-11-13 10:35:00 +01:00
Anders Schack-Mulligen
00549e36ed Merge pull request #14742 from aschackmull/rangeanalysis/share-util-3
Java/C++/Rangeanalysis: Share more range analysis utility predicates.
2023-11-13 10:19:41 +01:00
Alex Denisov
b385ddbab1 Swift: do not extract non-AST types 2023-11-13 09:12:22 +01:00
AlexDenisov
f599c6d8a9 Merge pull request #14734 from github/alexdenisov/parameter-packs
Swift: extract parameter packs
2023-11-13 08:44:39 +01:00
Paolo Tranquilli
df967ce43f Merge pull request #14750 from github/alexdenisov/update-wordings
Swift: update wordings in a downgrade script
2023-11-13 07:00:39 +01:00
Maiky
6e533c6284 Import PathGraph 2023-11-12 18:22:14 +01:00
Maiky
2b1b4cd85d Remove unused LdapConn 2023-11-12 18:18:43 +01:00
Maiky
5280d69500 Change to DataFlow::ConfigSig 2023-11-12 18:17:09 +01:00
Maiky
39ed7876c3 Merge branch 'github:main' into maikypedia/go-ldap-improper-auth 2023-11-12 18:14:05 +01:00
Maiky
882280309f equalityAsSanitizerGuard and add empty string comment 2023-11-12 17:42:56 +01:00
Mathias Vorreiter Pedersen
01a074c146 Merge pull request #14749 from MathiasVP/less-code-duplication 2023-11-10 19:45:56 +00:00
Geoffrey White
d56625cb8b Swift: Rename the capture test to look more like the others. 2023-11-10 17:59:44 +00:00
Alex Denisov
8f10667ee1 Swift: update wordings in a downgrade script 2023-11-10 18:10:43 +01:00
AlexDenisov
837cdc8301 Merge pull request #14745 from github/alexdenisov/parameter-packs-db-upgrade
Swift: parameter packs migration scripts
2023-11-10 18:07:10 +01:00
Jeroen Ketema
3a62628938 Merge pull request #14735 from jketema/strl
C++: Add models for `strlcpy` and `strlcat`
2023-11-10 17:51:59 +01:00
Mathias Vorreiter Pedersen
9062fb666a C++: Move a couple of predicates to 'Node0Impl'. 2023-11-10 16:26:03 +00:00
Jeroen Ketema
b48d483eba C++: Add change note 2023-11-10 17:25:19 +01:00
Geoffrey White
c327f0f0a7 Merge branch 'main' into pathinjectionsinks 2023-11-10 16:04:56 +00:00
Alex Denisov
393aad5935 Swift: downgrade parameter packs 2023-11-10 16:22:09 +01:00
Geoffrey White
8f141cb157 Swift: Change note. 2023-11-10 15:13:51 +00:00
Geoffrey White
5a09a325f2 Swift: Add heuristic path injection sinks. 2023-11-10 15:13:51 +00:00
Rasmus Wriedt Larsen
5fc8a00487 Python: Rename test function 2023-11-10 15:58:20 +01:00
Rasmus Wriedt Larsen
b3feb4d7e9 Update python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll
Co-authored-by: yoff <lerchedahl@gmail.com>
2023-11-10 15:57:00 +01:00
Anders Schack-Mulligen
0d8986cfad Java: Accept test changes. 2023-11-10 14:04:45 +01:00
Jeroen Ketema
617d950a25 Apply suggestions from code review
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2023-11-10 13:55:39 +01:00
Jeroen Ketema
1c87875049 C++: Drop the size return value of strlcat from hasTaintFlow 2023-11-10 13:15:57 +01:00
Jeroen Ketema
5e21a5d284 C++: Fix flow for return values of strlcat and strlcpy 2023-11-10 12:28:48 +01:00
Alex Denisov
0fb439b54d Swift: test ElementArchetypeType via PackType 2023-11-10 11:44:45 +01:00
Alex Denisov
e865c3cbd3 Swift: extract parameter packs 2023-11-10 10:20:14 +01:00
Jeroen Ketema
e4c8406365 C++: Split strlcat off in a separate model 2023-11-10 10:11:57 +01:00
Maiky
2d387a98ce Add go.mod 2023-11-10 01:00:01 +01:00
Maiky
78a65a7787 Remove import 2023-11-09 23:35:33 +01:00
Maiky
6d7598115e Undo changes in modules 2023-11-09 23:26:38 +01:00
Maiky
a7264c2b5c Requested Changes 2023-11-09 23:17:45 +01:00
Maiky
dc265e7542 Requested Changes 2023-11-09 23:17:15 +01:00
Anders Schack-Mulligen
657c29f409 Java/C++: Share valueFlowStep. 2023-11-09 20:24:28 +01:00
Geoffrey White
ebf7231be7 Swift: Make the 'completePath' models work. 2023-11-09 18:21:12 +00:00
Geoffrey White
9b5556e245 Swift: Test 'completePath' more carefully. 2023-11-09 18:21:12 +00:00
Geoffrey White
2d313ef4c7 Swift: Add some path injection sink models. 2023-11-09 18:21:12 +00:00
Jeroen Ketema
a051a57e00 Update cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2023-11-09 17:48:45 +01:00
Jeroen Ketema
0b91310357 C++: Add models for strlcpy and strlcat 2023-11-09 17:21:37 +01:00
Anders Schack-Mulligen
b8e7e1d15e Java/C++: Share ssaUpdateStep. 2023-11-09 16:02:44 +01:00
Anders Schack-Mulligen
daffae020b Java/C++: Share eqFlowCond. 2023-11-09 16:00:46 +01:00
Geoffrey White
cd147038cd Swift: Fill some gaps in the URL, NSURL models. 2023-11-09 11:51:18 +00:00
Geoffrey White
a86862d578 Swift: Add test cases (heuristic). 2023-11-09 11:33:10 +00:00
Geoffrey White
04016ebd20 Swift: Add test cases (more library functions). 2023-11-09 11:31:58 +00:00
Geoffrey White
f99df55e94 Swift: Add test stubs. 2023-11-09 11:28:33 +00:00
Cornelius Riemenschneider
3dcb039c76 Merge branch 'main' into criemen/java-int-tests 2023-11-09 11:19:04 +01:00
Rasmus Wriedt Larsen
9b0ad8295e Python: Add test of nested classes 2023-11-08 14:58:40 +01:00
Rasmus Wriedt Larsen
9d5cf0b331 Merge branch 'main' into class-attribute-flow 2023-11-08 14:30:53 +01:00
Cornelius Riemenschneider
f12310cb86 The java-version-too-old relies on a Java 8 installation.
We don't have a Java 8 build on the M1 machines, therefore skip this test.
2023-11-08 10:36:47 +01:00
Cornelius Riemenschneider
137403f649 Java: Move more tests to use the try_use_java11() helper.
This is in preparation of executing these tests on GH-hosted M1 runners,
where we need to have architecture-specific path handling.
It's nicer to fix all of this in one place (the helper), than to run around
fixing individual tests.
2023-11-08 10:33:50 +01:00
Rasmus Wriedt Larsen
5433907c33 Python: Accept more test changes
All are for the better 🎉
2023-11-07 15:49:14 +01:00
Rasmus Wriedt Larsen
5bee44dcfe Python: add change-note 2023-11-07 11:27:11 +01:00
Rasmus Wriedt Larsen
6568332e3d Python: Add basic flow for class attributes 2023-11-07 11:23:42 +01:00
Rasmus Wriedt Larsen
6c50c2bfe6 Python: Highlight missing flow for class attributes 2023-11-07 11:23:42 +01:00
amammad
e8eff78799 fix tests because of error in Frameworks.qll 2023-11-06 19:19:36 +01:00
amammad
ad756d59c8 put new frameworks in Frameworks.qll and fix some mistakes of Baize 2023-11-06 19:17:50 +01:00
amammad
315bdc2b48 add tests for new frameworks 2023-11-06 19:13:57 +01:00
amammad
637c52d10a separate each new FileSystemAccess packages. 2023-11-06 19:03:55 +01:00
Rasmus Wriedt Larsen
92b13c4259 Merge branch 'main' into amammad-python-FileSystemAccess 2023-11-06 11:30:09 +01:00
Rasmus Wriedt Larsen
3d8a7e0ee3 Python: Add change-note 2023-11-06 11:29:52 +01:00
Kevin Stubbings
57c645bd24 Added support for same struct and added new test 2023-11-05 22:34:35 -08:00
Kevin Stubbings
1f2e8d898d Address Feedback 2023-11-05 14:28:34 -08:00
Sam Browning
225c96ec9f Merge branch 'main' of https://github.com/github/codeql 2023-11-03 09:42:55 -04:00
Sam Browning
37361d9f79 Merge branch 'main' of https://github.com/github/codeql 2023-11-01 11:43:33 -04:00
Kevin Stubbings
3697ef72c4 Small changes 2023-10-31 12:23:18 -07:00
Kevin Stubbings
5cab25662c Address issues 2023-10-31 11:50:51 -07:00
Kevin Stubbings
8ed10317bd Test comment changes 2023-10-31 11:07:41 -07:00
Kevin Stubbings
dd9a2db137 Minor name changes 2023-10-31 11:03:54 -07:00
Kevin Stubbings
020b4becfd Finish up 2023-10-31 11:00:00 -07:00
Stephan Brandauer
5385cc3aaa Merge branch 'main' into kaeluka/publish-automodel-querypack-007 2023-10-31 11:48:22 +01:00
Stephan Brandauer
9087259b1b Java: add instructions to automodel query publish script 2023-10-31 11:11:22 +01:00
Stephan Brandauer
968127eaa3 Java: release automodel extraction queries 0.0.7 2023-10-31 11:09:02 +01:00
Kevin Stubbings
e0782683eb Added gin cors framework 2023-10-27 17:50:43 -07:00
Kevin Stubbings
dafcd5ec98 Added support for Gin CORS 2023-10-25 17:23:10 -07:00
Maiky
a1e38c3444 Remove unnecessary imports and add returns 2023-10-26 01:16:43 +02:00
Maiky
eccde3f4f1 Add Tests 2023-10-25 18:31:51 +02:00
amammad
a0e2e1ef21 add to Frameworks.qll 2023-10-21 19:49:27 +02:00
amammad
1fe565a46f cherrypy framework file system access Sinks are added 2023-10-21 19:47:30 +02:00
Maiky
20bf3c7f67 Apply suggestions from code review
Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com>
2023-10-15 15:47:19 +02:00
Remco Vermeulen
76e56cdac7 Adjust query severities 2023-10-09 12:52:09 -07:00
amammad
ad2631202d fix comments 2023-10-08 21:32:04 +02:00
amammad
6c8cc79b4d v1 2023-10-08 21:24:54 +02:00
Maiky
52007fb9a2 Change v3 to v2 2023-09-17 21:42:18 +02:00
Maiky
08c54767f2 Correct Ldap Unauth Bind Sink 2023-07-05 17:56:49 +02:00
Maiky
d654e98650 Add empty string as source 2023-06-18 22:21:12 +02:00
Maiky
1a9bfb38aa Correct barrier 2023-06-05 01:25:17 +02:00
Maiky
bf9d0b93d7 Add Improper LDAP Auth Query (CWE-287) 2023-06-03 23:20:11 +02:00
Sam Browning
1a51c015b4 Add requirements.txt 2023-04-27 15:19:45 -04:00
668 changed files with 29396 additions and 2419 deletions

View File

@@ -1,3 +1,17 @@
## 0.12.0
### Breaking Changes
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
### Minor Analysis Improvements
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
* Added models for `strlcpy` and `strlcat`.
* Added models for the `sprintf` variants from the `StrSafe.h` header.
* Added SQL API models for `ODBC`.
* Added taint models for `realloc` and related functions.
## 0.11.0
### Breaking Changes

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added taint models for `realloc` and related functions.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added models for the `sprintf` variants from the `StrSafe.h` header.

View File

@@ -0,0 +1,13 @@
## 0.12.0
### Breaking Changes
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
### Minor Analysis Improvements
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
* Added models for `strlcpy` and `strlcat`.
* Added models for the `sprintf` variants from the `StrSafe.h` header.
* Added SQL API models for `ODBC`.
* Added taint models for `realloc` and related functions.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.11.0
lastReleaseVersion: 0.12.0

View File

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

View File

@@ -81,6 +81,14 @@ class Node0Impl extends TIRDataFlowNode0 {
/** Gets the operands corresponding to this node, if any. */
Operand asOperand() { result = this.(OperandNode0).getOperand() }
/** Gets the location of this node. */
final Location getLocation() { result = this.getLocationImpl() }
/** INTERNAL: Do not use. */
Location getLocationImpl() {
none() // overridden by subclasses
}
/** INTERNAL: Do not use. */
string toStringImpl() {
none() // overridden by subclasses
@@ -131,9 +139,15 @@ abstract class InstructionNode0 extends Node0Impl {
override DataFlowType getType() { result = getInstructionType(instr, _) }
override string toStringImpl() {
// This predicate is overridden in subclasses. This default implementation
// does not use `Instruction.toString` because that's expensive to compute.
result = instr.getOpcode().toString()
if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = instr.getAst().toString()
}
override Location getLocationImpl() {
if exists(instr.getAst().getLocation())
then result = instr.getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
final override predicate isGLValue() { exists(getInstructionType(instr, true)) }
@@ -173,7 +187,17 @@ abstract class OperandNode0 extends Node0Impl {
override DataFlowType getType() { result = getOperandType(op, _) }
override string toStringImpl() { result = op.toString() }
override string toStringImpl() {
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = op.getDef().getAst().toString()
}
override Location getLocationImpl() {
if exists(op.getDef().getAst().getLocation())
then result = op.getDef().getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
final override predicate isGLValue() { exists(getOperandType(op, true)) }
}

View File

@@ -432,6 +432,10 @@ private class Node0 extends Node, TNode0 {
override Declaration getFunction() { result = node.getFunction() }
override Location getLocationImpl() { result = node.getLocation() }
override string toStringImpl() { result = node.toString() }
override DataFlowType getType() { result = node.getType() }
override predicate isGLValue() { node.isGLValue() }
@@ -448,18 +452,6 @@ class InstructionNode extends Node0 {
/** Gets the instruction corresponding to this node. */
Instruction getInstruction() { result = instr }
override Location getLocationImpl() {
if exists(instr.getAst().getLocation())
then result = instr.getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = instr.getAst().toString()
}
}
/**
@@ -473,18 +465,6 @@ class OperandNode extends Node, Node0 {
/** Gets the operand corresponding to this node. */
Operand getOperand() { result = op }
override Location getLocationImpl() {
if exists(op.getDef().getAst().getLocation())
then result = op.getDef().getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = op.getDef().getAst().toString()
}
}
/**

View File

@@ -10,6 +10,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
/**
* The standard function `strcat` and its wide, sized, and Microsoft variants.
*
* Does not include `strlcat`, which is covered by `StrlcatFunction`
*/
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
StrcatFunction() {
@@ -90,3 +92,64 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
buffer = true
}
}
/**
* The `strlcat` function.
*/
class StrlcatFunction extends TaintFunction, ArrayFunction, SideEffectFunction {
StrlcatFunction() {
this.hasGlobalName("strlcat") // strlcat(dst, src, dst_size)
}
/**
* Gets the index of the parameter that is the size of the copy (in characters).
*/
int getParamSize() { result = 2 }
/**
* Gets the index of the parameter that is the source of the copy.
*/
int getParamSrc() { result = 1 }
/**
* Gets the index of the parameter that is the destination to be appended to.
*/
int getParamDest() { result = 0 }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
(
input.isParameter(2)
or
input.isParameterDeref(0)
or
input.isParameterDeref(1)
) and
output.isParameterDeref(0)
}
override predicate hasArrayInput(int param) {
param = 0 or
param = 1
}
override predicate hasArrayOutput(int param) { param = 0 }
override predicate hasArrayWithNullTerminator(int param) { param = 1 }
override predicate hasArrayWithUnknownSize(int param) { param = 0 }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = 0 and
buffer = true and
mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
(i = 0 or i = 1) and
buffer = true
}
}

View File

@@ -32,7 +32,8 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
"wcsxfrm_l", // _strxfrm_l(dest, src, max_amount, locale)
"_mbsnbcpy", // _mbsnbcpy(dest, src, max_amount)
"stpcpy", // stpcpy(dest, src)
"stpncpy" // stpcpy(dest, src, max_amount)
"stpncpy", // stpncpy(dest, src, max_amount)
"strlcpy" // strlcpy(dst, src, dst_size)
])
or
(
@@ -53,6 +54,11 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
*/
private predicate isSVariant() { this.getName().matches("%\\_s") }
/**
* Holds if the function returns the total length the string would have had if the size was unlimited.
*/
private predicate returnsTotalLength() { this.getName() = "strlcpy" }
/**
* Gets the index of the parameter that is the maximum size of the copy (in characters).
*/
@@ -60,7 +66,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
if this.isSVariant()
then result = 1
else (
this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%", "strlcpy"]) and
result = 2
)
}
@@ -100,6 +106,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
input.isParameterDeref(this.getParamSrc()) and
output.isReturnValueDeref()
or
not this.returnsTotalLength() and
input.isParameter(this.getParamDest()) and
output.isReturnValue()
}
@@ -110,8 +117,9 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
exists(this.getParamSize()) and
input.isParameterDeref(this.getParamSrc()) and
(
output.isParameterDeref(this.getParamDest()) or
output.isReturnValueDeref()
output.isParameterDeref(this.getParamDest())
or
not this.returnsTotalLength() and output.isReturnValueDeref()
)
}

View File

@@ -22,8 +22,6 @@ class SemSsaExplicitUpdate extends SemSsaVariable {
SemSsaExplicitUpdate() { Specific::explicitUpdate(this, sourceExpr) }
final SemExpr getSourceExpr() { result = sourceExpr }
final SemExpr getDefiningExpr() { result = sourceExpr }
}

View File

@@ -14,7 +14,7 @@ private predicate constantIntegerExpr(SemExpr e, int val) {
// Copy of another constant
exists(SemSsaExplicitUpdate v, SemExpr src |
e = v.getAUse() and
src = v.getSourceExpr() and
src = v.getDefiningExpr() and
constantIntegerExpr(src, val)
)
or

View File

@@ -22,30 +22,7 @@ module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
predicate hasConstantBound(SemExpr e, float bound, boolean upper) { none() }
/**
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
* Holds if `e2 >= e1 + delta` (if `upper = false`) or `e2 <= e1 + delta` (if `upper = true`).
*/
predicate hasBound(SemExpr e, SemExpr bound, float delta, boolean upper) { none() }
/**
* Holds if the value of `dest` is known to be `src + delta`.
*/
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, float delta) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified expression,
* if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateType(SemExpr e) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified source
* variable, if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateTypeForSsaVariable(SemSsaVariable var) { none() }
predicate additionalBoundFlowStep(SemExpr e2, SemExpr e1, float delta, boolean upper) { none() }
}

View File

@@ -1,7 +1,6 @@
private import RangeAnalysisConstantSpecific
private import RangeAnalysisRelativeSpecific
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
private import RangeUtils
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExpr
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticCFG
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticGuard
@@ -88,12 +87,18 @@ module Sem implements Semantic {
class AddressType = SemAddressType;
SemType getExprType(SemExpr e) { result = e.getSemType() }
SemType getSsaType(SemSsaVariable var) { result = var.getType() }
class SsaVariable = SemSsaVariable;
class SsaPhiNode = SemSsaPhiNode;
class SsaExplicitUpdate = SemSsaExplicitUpdate;
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, int delta) { none() }
predicate conversionCannotOverflow(Type fromType, Type toType) {
SemanticType::conversionCannotOverflow(fromType, toType)
}
@@ -101,7 +106,7 @@ module Sem implements Semantic {
module SignAnalysis implements SignAnalysisSig<Sem> {
private import SignAnalysisCommon as SA
import SA::SignAnalysis<FloatDelta, Util>
import SA::SignAnalysis<FloatDelta>
}
module ConstantBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
@@ -164,18 +169,16 @@ private module ModulusAnalysisInstantiated implements ModulusAnalysisSig<Sem> {
class ModBound = AllBounds::SemBound;
private import codeql.rangeanalysis.ModulusAnalysis as MA
import MA::ModulusAnalysis<SemLocation, Sem, FloatDelta, AllBounds, Util>
import MA::ModulusAnalysis<SemLocation, Sem, FloatDelta, AllBounds>
}
module Util = RangeUtil<FloatDelta, CppLangImplConstant>;
module ConstantStage =
RangeStage<SemLocation, Sem, FloatDelta, ConstantBounds, FloatOverflow, CppLangImplConstant,
SignAnalysis, ModulusAnalysisInstantiated, Util>;
SignAnalysis, ModulusAnalysisInstantiated>;
module RelativeStage =
RangeStage<SemLocation, Sem, FloatDelta, RelativeBounds, FloatOverflow, CppLangImplRelative,
SignAnalysis, ModulusAnalysisInstantiated, Util>;
SignAnalysis, ModulusAnalysisInstantiated>;
private newtype TSemReason =
TSemNoReason() or

View File

@@ -54,30 +54,7 @@ module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
predicate hasConstantBound(SemExpr e, float bound, boolean upper) { none() }
/**
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
* Holds if `e2 >= e1 + delta` (if `upper = false`) or `e2 <= e1 + delta` (if `upper = true`).
*/
predicate hasBound(SemExpr e, SemExpr bound, float delta, boolean upper) { none() }
/**
* Holds if the value of `dest` is known to be `src + delta`.
*/
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, float delta) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified expression,
* if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateType(SemExpr e) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified source
* variable, if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateTypeForSsaVariable(SemSsaVariable var) { none() }
predicate additionalBoundFlowStep(SemExpr e2, SemExpr e1, float delta, boolean upper) { none() }
}

View File

@@ -1,136 +0,0 @@
/**
* Provides utility predicates for range analysis.
*/
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
private import RangeAnalysisRelativeSpecific
private import codeql.rangeanalysis.RangeAnalysis
private import RangeAnalysisImpl
private import ConstantAnalysis
module RangeUtil<DeltaSig D, LangSig<Sem, D> Lang> implements UtilSig<Sem, D> {
/**
* Gets an expression that equals `v - d`.
*/
private SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
// There are various language-specific extension points that can be removed once we no longer
// expect to match the original Java implementation's results exactly.
result = v.getAUse() and delta = D::fromInt(0)
or
exists(D::Delta d1, SemConstantIntegerExpr c |
result.(SemAddExpr).hasOperands(semSsaRead(v, d1), c) and
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue())
)
or
exists(SemSubExpr sub, D::Delta d1, SemConstantIntegerExpr c |
result = sub and
sub.getLeftOperand() = semSsaRead(v, d1) and
sub.getRightOperand() = c and
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue())
)
or
result = v.(SemSsaExplicitUpdate).getSourceExpr() and
delta = D::fromFloat(0)
or
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta)
or
result.(SemStoreExpr).getOperand() = semSsaRead(v, delta)
}
/**
* Gets a condition that tests whether `v` equals `e + delta`.
*
* If the condition evaluates to `testIsTrue`:
* - `isEq = true` : `v == e + delta`
* - `isEq = false` : `v != e + delta`
*/
pragma[nomagic]
SemGuard semEqFlowCond(
SemSsaVariable v, SemExpr e, D::Delta delta, boolean isEq, boolean testIsTrue
) {
exists(boolean eqpolarity |
result.isEquality(semSsaRead(v, delta), e, eqpolarity) and
(testIsTrue = true or testIsTrue = false) and
eqpolarity.booleanXor(testIsTrue).booleanNot() = isEq
)
or
exists(boolean testIsTrue0 |
semImplies_v2(result, testIsTrue, semEqFlowCond(v, e, delta, isEq, testIsTrue0), testIsTrue0)
)
}
/**
* Holds if `v` is an `SsaExplicitUpdate` that equals `e + delta`.
*/
predicate semSsaUpdateStep(SemSsaExplicitUpdate v, SemExpr e, D::Delta delta) {
exists(SemExpr defExpr | defExpr = v.getSourceExpr() |
defExpr.(SemCopyValueExpr).getOperand() = e and delta = D::fromFloat(0)
or
defExpr.(SemStoreExpr).getOperand() = e and delta = D::fromFloat(0)
or
defExpr.(SemAddOneExpr).getOperand() = e and delta = D::fromFloat(1)
or
defExpr.(SemSubOneExpr).getOperand() = e and delta = D::fromFloat(-1)
or
e = defExpr and
not (
defExpr instanceof SemCopyValueExpr or
defExpr instanceof SemStoreExpr or
defExpr instanceof SemAddOneExpr or
defExpr instanceof SemSubOneExpr
) and
delta = D::fromFloat(0)
)
}
/**
* Holds if `e1 + delta` equals `e2`.
*/
predicate semValueFlowStep(SemExpr e2, SemExpr e1, D::Delta delta) {
e2.(SemCopyValueExpr).getOperand() = e1 and delta = D::fromFloat(0)
or
e2.(SemStoreExpr).getOperand() = e1 and delta = D::fromFloat(0)
or
e2.(SemAddOneExpr).getOperand() = e1 and delta = D::fromFloat(1)
or
e2.(SemSubOneExpr).getOperand() = e1 and delta = D::fromFloat(-1)
or
Lang::additionalValueFlowStep(e2, e1, delta)
or
exists(SemExpr x | e2.(SemAddExpr).hasOperands(e1, x) |
D::fromInt(x.(SemConstantIntegerExpr).getIntValue()) = delta
)
or
exists(SemExpr x, SemSubExpr sub |
e2 = sub and
sub.getLeftOperand() = e1 and
sub.getRightOperand() = x
|
D::fromInt(-x.(SemConstantIntegerExpr).getIntValue()) = delta
)
}
/**
* Gets the type used to track the specified expression's range information.
*
* Usually, this just `e.getSemType()`, but the language can override this to track immutable boxed
* primitive types as the underlying primitive type.
*/
SemType getTrackedType(SemExpr e) {
result = Lang::getAlternateType(e)
or
not exists(Lang::getAlternateType(e)) and result = e.getSemType()
}
/**
* Gets the type used to track the specified source variable's range information.
*
* Usually, this just `e.getType()`, but the language can override this to track immutable boxed
* primitive types as the underlying primitive type.
*/
SemType getTrackedTypeForSsaVariable(SemSsaVariable var) {
result = Lang::getAlternateTypeForSsaVariable(var)
or
not exists(Lang::getAlternateTypeForSsaVariable(var)) and result = var.getType()
}
}

View File

@@ -11,10 +11,9 @@ private import RangeAnalysisImpl
private import SignAnalysisSpecific as Specific
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
private import ConstantAnalysis
private import RangeUtils
private import Sign
module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
module SignAnalysis<DeltaSig D> {
private import codeql.rangeanalysis.internal.RangeUtils::MakeUtils<Sem, D>
/**
@@ -39,7 +38,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
/** An SSA definition whose sign is determined by the sign of that definitions source expression. */
private class ExplicitSignDef extends FlowSignDef instanceof SemSsaExplicitUpdate {
final override Sign getSign() { result = semExprSign(super.getSourceExpr()) }
final override Sign getSign() { result = semExprSign(super.getDefiningExpr()) }
}
/** An SSA Phi definition, whose sign is the union of the signs of its inputs. */
@@ -148,7 +147,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
not this instanceof ConstantSignExpr and
(
// Only track numeric types.
Utils::getTrackedType(this) instanceof SemNumericType
Sem::getExprType(this) instanceof SemNumericType
or
// Unless the language says to track this expression anyway.
Specific::trackUnknownNonNumericExpr(this)
@@ -203,7 +202,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
/** An expression of an unsigned type. */
private class UnsignedExpr extends FlowSignExpr {
UnsignedExpr() { Utils::getTrackedType(this) instanceof SemUnsignedIntegerType }
UnsignedExpr() { Sem::getExprType(this) instanceof SemUnsignedIntegerType }
override Sign getSignRestriction() {
result = TPos() or
@@ -276,7 +275,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
override SemUnboxExpr cast;
UnboxSignExpr() {
exists(SemType fromType | fromType = Utils::getTrackedType(cast.getOperand()) |
exists(SemType fromType | fromType = Sem::getExprType(cast.getOperand()) |
// Only numeric source types are handled here.
fromType instanceof SemNumericType
)
@@ -471,7 +470,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
Sign semExprSign(SemExpr e) {
exists(Sign s | s = e.(SignExpr).getSign() |
if
Utils::getTrackedType(e) instanceof SemUnsignedIntegerType and
Sem::getExprType(e) instanceof SemUnsignedIntegerType and
s = TNeg() and
not Specific::ignoreTypeRestrictions(e)
then result = TPos()

View File

@@ -1,3 +1,9 @@
## 0.8.3
### Minor Analysis Improvements
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.
## 0.8.2
No user-facing changes.

View File

@@ -27,16 +27,26 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" }
override predicate isSource(Instruction source) {
// Holds if `source` is a node that represents the use of a stack variable
exists(VariableAddressInstruction var, Function func |
var = source and
func = source.getEnclosingFunction() and
var.getAstVariable() instanceof StackVariable and
// Pointer-to-member types aren't properly handled in the dbscheme.
not var.getResultType() instanceof PointerToMemberType and
exists(Function func |
// Rule out FPs caused by extraction errors.
not any(ErrorExpr e).getEnclosingFunction() = func and
not intentionallyReturnsStackPointer(func)
not intentionallyReturnsStackPointer(func) and
func = source.getEnclosingFunction()
|
// `source` is an instruction that represents the use of a stack variable
exists(VariableAddressInstruction var |
var = source and
var.getAstVariable() instanceof StackVariable and
// Pointer-to-member types aren't properly handled in the dbscheme.
not var.getResultType() instanceof PointerToMemberType
)
or
// `source` is an instruction that represents the return value of a
// function that is known to return stack-allocated memory.
exists(Call call |
call.getTarget().hasGlobalName(["alloca", "strdupa", "strndupa", "_alloca", "_malloca"]) and
source.getUnconvertedResultExpression() = call
)
)
}
@@ -85,10 +95,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
}
from
MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var,
MustFlowPathNode source, MustFlowPathNode sink, Instruction instr,
ReturnStackAllocatedMemoryConfig conf
where
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
source.getInstruction() = var
source.getInstruction() = instr
select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.",
var.getAst(), var.getAst().toString()
instr.getAst(), instr.getAst().toString()

View File

@@ -14,25 +14,47 @@
import cpp
import semmle.code.cpp.security.Security
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
import TaintedWithPath
import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.ir.IR
import Flow::PathGraph
predicate isProcessOperationExplanation(Expr arg, string processOperation) {
predicate isProcessOperationExplanation(DataFlow::Node arg, string processOperation) {
exists(int processOperationArg, FunctionCall call |
isProcessOperationArgument(processOperation, processOperationArg) and
call.getTarget().getName() = processOperation and
call.getArgument(processOperationArg) = arg
call.getArgument(processOperationArg) = [arg.asExpr(), arg.asIndirectExpr()]
)
}
class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element arg) { isProcessOperationExplanation(arg, _) }
predicate isSource(FlowSource source, string sourceType) {
not source instanceof DataFlow::ExprNode and
sourceType = source.getSourceType()
}
from string processOperation, Expr arg, Expr source, PathNode sourceNode, PathNode sinkNode
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { isSource(node, _) }
predicate isSink(DataFlow::Node node) { isProcessOperationExplanation(node, _) }
predicate isBarrier(DataFlow::Node node) {
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
or
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
}
}
module Flow = TaintTracking::Global<Config>;
from
string processOperation, string sourceType, DataFlow::Node source, DataFlow::Node sink,
Flow::PathNode sourceNode, Flow::PathNode sinkNode
where
isProcessOperationExplanation(arg, processOperation) and
taintedWithPath(source, arg, sourceNode, sinkNode)
select arg, sourceNode, sinkNode,
source = sourceNode.getNode() and
sink = sinkNode.getNode() and
isSource(source, sourceType) and
isProcessOperationExplanation(sink, processOperation) and
Flow::flowPath(sourceNode, sinkNode)
select sink, sourceNode, sinkNode,
"The value of this argument may come from $@ and is being passed to " + processOperation + ".",
source, source.toString()
source, sourceType

View File

@@ -52,16 +52,17 @@ predicate isUnboundedWrite(BufferWrite bw) {
* Holds if `e` is a source buffer going into an unbounded write `bw` or a
* qualifier of (a qualifier of ...) such a source.
*/
predicate unboundedWriteSource(Expr e, BufferWrite bw) {
isUnboundedWrite(bw) and e = bw.getASource()
predicate unboundedWriteSource(Expr e, BufferWrite bw, boolean qualifier) {
isUnboundedWrite(bw) and e = bw.getASource() and qualifier = false
or
exists(FieldAccess fa | unboundedWriteSource(fa, bw) and e = fa.getQualifier())
exists(FieldAccess fa | unboundedWriteSource(fa, bw, _) and e = fa.getQualifier()) and
qualifier = true
}
predicate isSource(FS::FlowSource source, string sourceType) { source.getSourceType() = sourceType }
predicate isSink(DataFlow::Node sink, BufferWrite bw) {
unboundedWriteSource(sink.asIndirectExpr(), bw)
predicate isSink(DataFlow::Node sink, BufferWrite bw, boolean qualifier) {
unboundedWriteSource(sink.asIndirectExpr(), bw, qualifier)
or
// `gets` and `scanf` reads from stdin so there's no real input.
// The `BufferWrite` library models this as the call itself being
@@ -69,7 +70,7 @@ predicate isSink(DataFlow::Node sink, BufferWrite bw) {
// the sink so that we report a path where source = sink (because
// the same output argument is also included in `isSource`).
bw.getASource() = bw and
unboundedWriteSource(sink.asDefiningArgument(), bw)
unboundedWriteSource(sink.asDefiningArgument(), bw, qualifier)
}
predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
@@ -84,9 +85,9 @@ predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSource(source, _) }
predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
predicate isBarrierOut(DataFlow::Node node) { isSink(node) }
predicate isBarrierOut(DataFlow::Node node) { isSink(node, _, false) }
predicate isBarrier(DataFlow::Node node) {
// Block flow if the node is guarded by any <, <= or = operations.
@@ -116,7 +117,7 @@ from BufferWrite bw, Flow::PathNode source, Flow::PathNode sink, string sourceTy
where
Flow::flowPath(source, sink) and
isSource(source.getNode(), sourceType) and
isSink(sink.getNode(), bw)
isSink(sink.getNode(), bw, _)
select bw, source, sink,
"This '" + bw.getBWDesc() + "' with input from $@ may overflow the destination.",
source.getNode(), sourceType

View File

@@ -14,10 +14,13 @@
import cpp
import semmle.code.cpp.security.Overflow
import semmle.code.cpp.security.Security
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
import TaintedWithPath
import semmle.code.cpp.dataflow.new.TaintTracking
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.ir.IR
import semmle.code.cpp.controlflow.IRGuards as IRGuards
import semmle.code.cpp.security.FlowSources as FS
import Bounded
import Flow::PathGraph
bindingset[op]
predicate missingGuard(Operation op, Expr e, string effect) {
@@ -28,28 +31,90 @@ predicate missingGuard(Operation op, Expr e, string effect) {
not e instanceof VariableAccess and effect = "overflow"
}
class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element e) {
exists(Operation op |
missingGuard(op, e, _) and
op.getAnOperand() = e
|
op instanceof UnaryArithmeticOperation or
op instanceof BinaryArithmeticOperation or
op instanceof AssignArithmeticOperation
)
}
predicate isSource(FS::FlowSource source, string sourceType) { sourceType = source.getSourceType() }
override predicate isBarrier(Expr e) {
super.isBarrier(e) or bounded(e) or e.getUnspecifiedType().(IntegralType).getSize() <= 1
predicate isSink(DataFlow::Node sink, Operation op, Expr e) {
e = sink.asExpr() and
missingGuard(op, e, _) and
op.getAnOperand() = e and
(
op instanceof UnaryArithmeticOperation or
op instanceof BinaryArithmeticOperation or
op instanceof AssignArithmeticOperation
)
}
predicate hasUpperBoundsCheck(Variable var) {
exists(RelationalOperation oper, VariableAccess access |
oper.getAnOperand() = access and
access.getTarget() = var and
// Comparing to 0 is not an upper bound check
not oper.getAnOperand().getValue() = "0"
)
}
predicate constantInstruction(Instruction instr) {
instr instanceof ConstantInstruction or
constantInstruction(instr.(UnaryInstruction).getUnary())
}
predicate readsVariable(LoadInstruction load, Variable var) {
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
}
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
exists(Instruction instr | instr = node.asInstruction() |
readsVariable(instr, checkedVar) and
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
)
}
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSource(source, _) }
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
predicate isBarrier(DataFlow::Node node) {
exists(StoreInstruction store | store = node.asInstruction() |
// Block flow to "likely small expressions"
bounded(store.getSourceValue().getUnconvertedResultExpression())
or
// Block flow to "small types"
store.getResultType().getUnspecifiedType().(IntegralType).getSize() <= 1
)
or
// Block flow if there's an upper bound check of the variable anywhere in the program
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
readsVariable(instr, checkedVar) and
hasUpperBoundsCheck(checkedVar)
)
or
// Block flow if the node is guarded by an equality check
exists(Variable checkedVar, Operand access |
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
readsVariable(access.getDef(), checkedVar)
)
or
// Block flow to any binary instruction whose operands are both non-constants.
exists(BinaryInstruction iTo |
iTo = node.asInstruction() and
not constantInstruction(iTo.getLeft()) and
not constantInstruction(iTo.getRight()) and
// propagate taint from either the pointer or the offset, regardless of constantness
not iTo instanceof PointerArithmeticInstruction
)
}
}
from Expr origin, Expr e, string effect, PathNode sourceNode, PathNode sinkNode, Operation op
module Flow = TaintTracking::Global<Config>;
from
Expr e, string effect, Flow::PathNode source, Flow::PathNode sink, Operation op, string sourceType
where
taintedWithPath(origin, e, sourceNode, sinkNode) and
op.getAnOperand() = e and
Flow::flowPath(source, sink) and
isSource(source.getNode(), sourceType) and
isSink(sink.getNode(), op, e) and
missingGuard(op, e, effect)
select e, sourceNode, sinkNode,
select e, source, sink,
"$@ flows to an operand of an arithmetic expression, potentially causing an " + effect + ".",
origin, "User-provided value"
source, sourceType

View File

@@ -4,6 +4,7 @@
* @description The total number of lines of C/C++ code across all files, including system headers, libraries, and auto-generated files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
* @kind metric
* @tags summary
* telemetry
*/
import cpp

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added SQL API models for `ODBC`.

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
## 0.8.3
### Minor Analysis Improvements
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.8.2
lastReleaseVersion: 0.8.3

View File

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

View File

@@ -2,7 +2,6 @@ import cpp
import codeql.rangeanalysis.ModulusAnalysis
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisImpl
@@ -10,9 +9,7 @@ import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
import semmle.code.cpp.ir.IR as IR
import TestUtilities.InlineExpectationsTest
module ModulusAnalysisInstantiated =
ModulusAnalysis<SemLocation, Sem, FloatDelta, ConstantBounds,
RangeUtil<FloatDelta, CppLangImplRelative>>;
module ModulusAnalysisInstantiated = ModulusAnalysis<SemLocation, Sem, FloatDelta, ConstantBounds>;
module ModulusAnalysisTest implements TestSig {
string getARelevantTag() { result = "mod" }

View File

@@ -1,15 +1,13 @@
import cpp
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.SignAnalysisCommon
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
import semmle.code.cpp.ir.IR as IR
import TestUtilities.InlineExpectationsTest
module SignAnalysisInstantiated =
SignAnalysis<FloatDelta, RangeUtil<FloatDelta, CppLangImplRelative>>;
module SignAnalysisInstantiated = SignAnalysis<FloatDelta>;
module SignAnalysisTest implements TestSig {
string getARelevantTag() { result = "sign" }

View File

@@ -43,6 +43,11 @@ edges
| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | (reference to) |
| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | (reference to) |
| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | (reference dereference) |
| test.cpp:237:12:237:17 | call to alloca | test.cpp:237:12:237:17 | call to alloca |
| test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p |
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:249:13:249:20 | call to strndupa |
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | s2 |
| test.cpp:250:9:250:10 | s2 | test.cpp:250:9:250:10 | (void *)... |
nodes
| test.cpp:17:9:17:11 | & ... | semmle.label | & ... |
| test.cpp:17:10:17:11 | mc | semmle.label | mc |
@@ -101,6 +106,14 @@ nodes
| 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 | pRef | semmle.label | pRef |
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
| test.cpp:238:9:238:9 | p | semmle.label | p |
| test.cpp:245:9:245:15 | call to strdupa | semmle.label | call to strdupa |
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
| test.cpp:250:9:250:10 | (void *)... | semmle.label | (void *)... |
| test.cpp:250:9:250:10 | s2 | semmle.label | s2 |
#select
| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
@@ -115,3 +128,6 @@ nodes
| test.cpp:177:10:177:23 | Convert: (void *)... | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | (void *)... | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray |
| test.cpp:183:10:183:19 | CopyValue: (reference to) | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | (reference to) | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal |
| test.cpp:190:10:190:13 | CopyValue: (reference to) | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | (reference to) | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p |
| test.cpp:238:9:238:9 | Load: p | test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p | May return stack-allocated memory from $@. | test.cpp:237:12:237:17 | call to alloca | call to alloca |
| test.cpp:245:9:245:15 | Call: call to strdupa | test.cpp:245:9:245:15 | call to strdupa | test.cpp:245:9:245:15 | call to strdupa | May return stack-allocated memory from $@. | test.cpp:245:9:245:15 | call to strdupa | call to strdupa |
| test.cpp:250:9:250:10 | Convert: (void *)... | test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | (void *)... | May return stack-allocated memory from $@. | test.cpp:249:13:249:20 | call to strndupa | call to strndupa |

View File

@@ -229,4 +229,23 @@ int* id(int* px) {
void f() {
int x;
int* px = id(&x); // GOOD
}
void *alloca(size_t);
void* test_alloca() {
void* p = alloca(10);
return p; // BAD
}
char *strdupa(const char *);
char *strndupa(const char *, size_t);
char* test_strdupa(const char* s) {
return strdupa(s); // BAD
}
void* test_strndupa(const char* s, size_t size) {
char* s2 = strndupa(s, size);
return s2; // BAD
}

View File

@@ -1,23 +1,12 @@
edges
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
| test.cpp:73:24:73:27 | data | test.cpp:37:73:37:76 | data |
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data indirection |
| test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:73:24:73:27 | data indirection |
| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | data indirection |
subpaths
nodes
| test.cpp:37:73:37:76 | data | semmle.label | data |
| test.cpp:37:73:37:76 | data indirection | semmle.label | data indirection |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
| test.cpp:73:24:73:27 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
| test.cpp:64:30:64:35 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:73:24:73:27 | data indirection | semmle.label | data indirection |
subpaths
#select
| test.cpp:43:32:43:35 | data | test.cpp:64:30:64:35 | call to getenv | test.cpp:43:32:43:35 | data | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv | call to getenv |
| test.cpp:43:32:43:35 | data indirection | test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:43:32:43:35 | data indirection | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv indirection | an environment variable |

View File

@@ -1,112 +1,48 @@
edges
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
| test.cpp:42:18:42:23 | call to getenv | test.cpp:24:30:24:36 | command |
| test.cpp:42:18:42:34 | call to getenv | test.cpp:24:30:24:36 | command |
| test.cpp:43:18:43:23 | call to getenv | test.cpp:29:30:29:36 | command |
| test.cpp:43:18:43:34 | call to getenv | test.cpp:29:30:29:36 | command |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
subpaths
| test.cpp:24:30:24:36 | command indirection | test.cpp:26:10:26:16 | command indirection |
| test.cpp:29:30:29:36 | command indirection | test.cpp:31:10:31:16 | command indirection |
| test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:24:30:24:36 | command indirection |
| test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:29:30:29:36 | command indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (reference dereference) indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection |
| test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection |
nodes
| test.cpp:24:30:24:36 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command | semmle.label | command |
| test.cpp:29:30:29:36 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:42:18:42:34 | call to getenv | semmle.label | call to getenv |
| test.cpp:43:18:43:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:43:18:43:34 | call to getenv | semmle.label | call to getenv |
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
| test.cpp:24:30:24:36 | command indirection | semmle.label | command indirection |
| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection |
| test.cpp:29:30:29:36 | command indirection | semmle.label | command indirection |
| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection |
| test.cpp:42:18:42:34 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:43:18:43:34 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:63:10:63:13 | data | semmle.label | data |
| test.cpp:63:10:63:13 | data | semmle.label | data |
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection |
| test.cpp:64:10:64:16 | (reference dereference) indirection | semmle.label | (reference dereference) indirection |
| test.cpp:64:10:64:16 | dataref indirection | semmle.label | dataref indirection |
| test.cpp:65:10:65:14 | data2 indirection | semmle.label | data2 indirection |
| test.cpp:76:12:76:17 | fgets output argument | semmle.label | fgets output argument |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:98:17:98:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:113:8:113:12 | call to fgets | semmle.label | call to fgets |
| test.cpp:113:8:113:12 | call to fgets | semmle.label | call to fgets |
| test.cpp:114:9:114:11 | ptr | semmle.label | ptr |
| test.cpp:114:9:114:11 | ptr | semmle.label | ptr |
| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:113:8:113:12 | call to fgets indirection | semmle.label | call to fgets indirection |
| test.cpp:114:9:114:11 | ptr indirection | semmle.label | ptr indirection |
subpaths
#select
| test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:23 | call to getenv | call to getenv |
| test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:23 | call to getenv | call to getenv |
| test.cpp:62:10:62:15 | buffer | test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:63:10:63:13 | data | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:64:10:64:16 | dataref | test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:65:10:65:14 | data2 | test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:78:10:78:15 | buffer | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | buffer | buffer |
| test.cpp:99:15:99:20 | buffer | test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | buffer | buffer |
| test.cpp:107:15:107:20 | buffer | test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | buffer | buffer |
| test.cpp:114:9:114:11 | ptr | test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr | The value of this argument may come from $@ and is being passed to system. | test.cpp:113:8:113:12 | call to fgets | call to fgets |
| test.cpp:26:10:26:16 | command indirection | test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:26:10:26:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:34 | call to getenv indirection | an environment variable |
| test.cpp:31:10:31:16 | command indirection | test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:31:10:31:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:34 | call to getenv indirection | an environment variable |
| test.cpp:62:10:62:15 | buffer indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:63:10:63:13 | data indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:64:10:64:16 | (reference dereference) indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (reference dereference) indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:64:10:64:16 | dataref indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:65:10:65:14 | data2 indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:78:10:78:15 | buffer indirection | test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | fgets output argument | string read by fgets |
| test.cpp:99:15:99:20 | buffer indirection | test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | recv output argument | buffer read by recv |
| test.cpp:107:15:107:20 | buffer indirection | test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | recv output argument | buffer read by recv |
| test.cpp:114:9:114:11 | ptr indirection | test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:113:8:113:12 | call to fgets indirection | string read by fgets |

View File

@@ -1,4 +1,32 @@
edges
subpaths
| main.cpp:6:27:6:30 | argv indirection | main.cpp:10:20:10:23 | argv indirection |
| main.cpp:10:20:10:23 | argv indirection | tests.cpp:631:32:631:35 | argv indirection |
| tests.cpp:613:19:613:24 | source indirection | tests.cpp:615:17:615:22 | source indirection |
| tests.cpp:622:19:622:24 | source indirection | tests.cpp:625:2:625:16 | ... = ... indirection |
| tests.cpp:625:2:625:16 | ... = ... indirection | tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] |
| tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] | tests.cpp:628:14:628:14 | s indirection [home indirection] |
| tests.cpp:628:14:628:14 | s indirection [home indirection] | tests.cpp:628:14:628:19 | home indirection |
| tests.cpp:628:14:628:14 | s indirection [home indirection] | tests.cpp:628:16:628:19 | home indirection |
| tests.cpp:628:16:628:19 | home indirection | tests.cpp:628:14:628:19 | home indirection |
| tests.cpp:631:32:631:35 | argv indirection | tests.cpp:656:9:656:15 | access to array indirection |
| tests.cpp:631:32:631:35 | argv indirection | tests.cpp:657:9:657:15 | access to array indirection |
| tests.cpp:656:9:656:15 | access to array indirection | tests.cpp:613:19:613:24 | source indirection |
| tests.cpp:657:9:657:15 | access to array indirection | tests.cpp:622:19:622:24 | source indirection |
nodes
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
| main.cpp:10:20:10:23 | argv indirection | semmle.label | argv indirection |
| tests.cpp:613:19:613:24 | source indirection | semmle.label | source indirection |
| tests.cpp:615:17:615:22 | source indirection | semmle.label | source indirection |
| tests.cpp:622:19:622:24 | source indirection | semmle.label | source indirection |
| tests.cpp:625:2:625:16 | ... = ... indirection | semmle.label | ... = ... indirection |
| tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] | semmle.label | s indirection [post update] [home indirection] |
| tests.cpp:628:14:628:14 | s indirection [home indirection] | semmle.label | s indirection [home indirection] |
| tests.cpp:628:14:628:19 | home indirection | semmle.label | home indirection |
| tests.cpp:628:16:628:19 | home indirection | semmle.label | home indirection |
| tests.cpp:631:32:631:35 | argv indirection | semmle.label | argv indirection |
| tests.cpp:656:9:656:15 | access to array indirection | semmle.label | access to array indirection |
| tests.cpp:657:9:657:15 | access to array indirection | semmle.label | access to array indirection |
subpaths
#select
| tests.cpp:615:2:615:7 | call to strcpy | main.cpp:6:27:6:30 | argv indirection | tests.cpp:615:17:615:22 | source indirection | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | argv indirection | a command-line argument |
| tests.cpp:628:2:628:7 | call to strcpy | main.cpp:6:27:6:30 | argv indirection | tests.cpp:628:14:628:19 | home indirection | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | argv indirection | a command-line argument |

View File

@@ -407,7 +407,7 @@ void test15()
{
if (ptr[5] == ' ') // GOOD
{
// ...
break;
}
}
}
@@ -608,6 +608,26 @@ int test23() {
return sizeof(buffer) / sizeof(buffer[101]); // GOOD
}
char* strcpy(char *, const char *);
void test24(char* source) {
char buffer[100];
strcpy(buffer, source); // BAD
}
struct my_struct {
char* home;
};
void test25(char* source) {
my_struct s;
s.home = source;
char buf[100];
strcpy(buf, s.home); // BAD
}
int tests_main(int argc, char *argv[])
{
long long arr17[19];
@@ -633,6 +653,8 @@ int tests_main(int argc, char *argv[])
test21(argc == 0);
test22(argc == 0, argv[0]);
test23();
test24(argv[0]);
test25(argv[0]);
return 0;
}

View File

@@ -1,13 +1,8 @@
edges
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
subpaths
nodes
| examples.cpp:63:26:63:30 | & ... | semmle.label | & ... |
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |
| examples.cpp:66:11:66:14 | data | semmle.label | data |
| examples.cpp:66:11:66:14 | data | semmle.label | data |
subpaths
#select
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | & ... | User-provided value |
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | fscanf output argument | value read by fscanf |

View File

@@ -1,86 +1,59 @@
edges
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:13:27:13 | v |
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:13:27:13 | v |
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
| test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
| test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
| test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:18:6:18:18 | call to getTaintedInt |
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
subpaths
| test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
| test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
| test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
nodes
| test2.cpp:12:21:12:21 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |
| test2.cpp:25:22:25:23 | & ... | semmle.label | & ... |
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
| test2.cpp:27:13:27:13 | v | semmle.label | v |
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
| test2.cpp:36:9:36:14 | fgets output argument | semmle.label | fgets output argument |
| test2.cpp:39:9:39:11 | num | semmle.label | num |
| test2.cpp:39:9:39:11 | num | semmle.label | num |
| test2.cpp:40:3:40:5 | num | semmle.label | num |
| test2.cpp:40:3:40:5 | num | semmle.label | num |
| test3.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | semmle.label | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test.c:11:29:11:32 | argv | semmle.label | argv |
| test.c:11:29:11:32 | argv | semmle.label | argv |
| test.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:41:17:41:20 | argv | semmle.label | argv |
| test.c:41:17:41:20 | argv | semmle.label | argv |
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
| test.c:51:17:51:20 | argv | semmle.label | argv |
| test.c:51:17:51:20 | argv | semmle.label | argv |
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
subpaths
#select
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | buf | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:11:29:11:32 | argv | User-provided value |
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:11:29:11:32 | argv | User-provided value |
| test.c:44:7:44:10 | len2 | test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:41:17:41:20 | argv | User-provided value |
| test.c:54:7:54:10 | len3 | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:51:17:51:20 | argv | User-provided value |
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |

View File

@@ -252,7 +252,7 @@ namespace Semmle.Autobuild.Shared
try
{
var res = thisBuildActions.RunProcess("sysctl", "machdep.cpu.brand_string", workingDirectory: null, env: null, out var stdOut);
thisBuildActions.RunProcess("sysctl", "machdep.cpu.brand_string", workingDirectory: null, env: null, out var stdOut);
return stdOut?.Any(s => s?.ToLowerInvariant().Contains("apple") == true) ?? false;
}
catch (Exception)

View File

@@ -15,14 +15,12 @@ namespace Semmle.Autobuild.Shared
/// <returns></returns>
public static CommandBuilder MsBuildCommand(this CommandBuilder cmdBuilder, IAutobuilder<AutobuildOptionsShared> builder)
{
var IsRunningOnAppleSiliconMac = builder.Actions.IsMacOs() && builder.Actions.IsRunningOnAppleSilicon();
// mono doesn't ship with `msbuild` on Arm-based Macs, but we can fall back to
// msbuild that ships with `dotnet` which can be invoked with `dotnet msbuild`
// perhaps we should do this on all platforms?
return IsRunningOnAppleSiliconMac ?
cmdBuilder.RunCommand("dotnet").Argument("msbuild") :
cmdBuilder.RunCommand("msbuild");
return builder.Actions.IsRunningOnAppleSilicon()
? cmdBuilder.RunCommand("dotnet").Argument("msbuild")
: cmdBuilder.RunCommand("msbuild");
}
}
@@ -84,7 +82,12 @@ namespace Semmle.Autobuild.Shared
Argument("/t:restore").
QuoteArgument(projectOrSolution.FullPath);
if (nugetDownloaded)
if (builder.Actions.IsRunningOnAppleSilicon())
{
// On Apple Silicon, only try package restore with `dotnet msbuild /t:restore`
ret &= BuildScript.Try(msbuildRestoreCommand.Script);
}
else if (nugetDownloaded)
{
ret &= BuildScript.Try(nugetRestore | msbuildRestoreCommand.Script);
}

View File

@@ -89,8 +89,10 @@ namespace Semmle.Extraction.CSharp.Populators
SyntaxKind.ModuleKeyword => Entities.AttributeKind.Module,
_ => throw new InternalError(node, "Unhandled global target")
};
foreach (var attribute in node.Attributes)
var attributes = node.Attributes;
for (var i = 0; i < attributes.Count; i++)
{
var attribute = attributes[i];
if (attributeLookup.Value(attribute) is AttributeData attributeData)
{
var ae = Entities.Attribute.Create(Cx, attributeData, outputAssembly, kind);

View File

@@ -1,3 +1,7 @@
## 1.7.3
No user-facing changes.
## 1.7.2
No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.2
lastReleaseVersion: 1.7.3

View File

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

View File

@@ -1,3 +1,7 @@
## 1.7.3
No user-facing changes.
## 1.7.2
No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.2
lastReleaseVersion: 1.7.3

View File

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

View File

@@ -2,10 +2,10 @@ import os
from create_database_utils import *
from diagnostics_test_utils import *
run_codeql_database_create(['dotnet pack'], db=None, lang="csharp")
run_codeql_database_create(['dotnet pack -o nugetpackage'], db=None, lang="csharp")
## Check that the NuGet package is created.
if not os.path.isfile("bin/Debug/dotnet_pack.1.0.0.nupkg"):
if not os.path.isfile("nugetpackage/dotnet_pack.1.0.0.nupkg"):
raise Exception("The NuGet package was not created.")
check_diagnostics()

View File

@@ -1,24 +1,6 @@
import os
from create_database_utils import *
from diagnostics_test_utils import *
def is_running_on_apple_silicon():
arch = subprocess.Popen(['sysctl', 'machdep.cpu.brand_string'], stdout=subprocess.PIPE)
output, errors = arch.communicate()
if b'apple' in output.lower():
return True
return False
# if on ARM runners, remove Mono from the path, so we're using
# dotnet restore instead of nuget.exe restore - on ARM machines
# we run dotner msbuild (instead of the mono-provided msbuild.exe)
# so we need to match the restore command, too.
platform_name = sys.platform.lower()
if platform_name.startswith("darwin") and is_running_on_apple_silicon():
os.environ["PATH"] = os.environ["PATH"].replace("/Library/Frameworks/Mono.framework/Versions/Current/Commands:", "")
# force CodeQL to use MSBuild by setting `LGTM_INDEX_MSBUILD_TARGET`
run_codeql_database_create([], db=None, lang="csharp", extra_env={ 'LGTM_INDEX_MSBUILD_TARGET': 'Build' })
check_diagnostics()

View File

@@ -7,6 +7,7 @@
<IsPackable>false</IsPackable>
<OutputType>Exe</OutputType>
<SelfContained>false</SelfContained>
</PropertyGroup>
<ItemGroup>

View File

@@ -0,0 +1 @@
Skipping the test on the ARM runners, as we're running into trouble with Mono and nuget.

View File

@@ -1,3 +1,49 @@
## 0.8.3
### Minor Analysis Improvements
* The predicate `UnboundGeneric::getName` now prints the number of type parameters as a `` `N`` suffix, instead of a `<,...,>` suffix. For example, the unbound generic type
`System.Collections.Generic.IList<T>` is printed as ``IList`1`` instead of `IList<>`.
* The predicates `hasQualifiedName`, `getQualifiedName`, and `getQualifiedNameWithTypes` have been deprecated, and are instead replaced by `hasFullyQualifiedName`, `getFullyQualifiedName`, and `getFullyQualifiedNameWithTypes`, respectively. The new predicates use the same format for unbound generic types as mentioned above.
* These changes also affect models-as-data rows that refer to a field or a property belonging to a generic type. For example, instead of writing
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
```
one now writes
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
```
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
```
one now writes
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
```
## 0.8.2
No user-facing changes.

View File

@@ -1,24 +0,0 @@
---
category: minorAnalysis
---
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
```
one now writes
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
```

View File

@@ -1,6 +1,6 @@
---
category: minorAnalysis
---
## 0.8.3
### Minor Analysis Improvements
* The predicate `UnboundGeneric::getName` now prints the number of type parameters as a `` `N`` suffix, instead of a `<,...,>` suffix. For example, the unbound generic type
`System.Collections.Generic.IList<T>` is printed as ``IList`1`` instead of `IList<>`.
@@ -23,3 +23,23 @@ extensions:
data:
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
```
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
```
one now writes
```yml
extensions:
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
```

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.8.2
lastReleaseVersion: 0.8.3

View File

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

View File

@@ -1,3 +1,9 @@
## 0.8.3
### Minor Analysis Improvements
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
## 0.8.2
No user-facing changes.

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
## 0.8.3
### Minor Analysis Improvements
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.8.2
lastReleaseVersion: 0.8.3

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.8.3-dev
version: 0.8.3
groups:
- csharp
- queries

View File

@@ -0,0 +1,2 @@
| standalone.cs:3:12:3:29 | [assembly: Attribute1(...)] |
| standalone.cs:9:2:9:11 | [Attribute1(...)] |

View File

@@ -0,0 +1,5 @@
import csharp
from Attribute a
where a.getType().getName() = "Attribute1Attribute"
select a

View File

@@ -0,0 +1 @@
semmle-extractor-options: --standalone

View File

@@ -0,0 +1,12 @@
using System;
[assembly: global::Attribute1]
class Attribute1Attribute : Attribute
{
}
[Attribute1]
class A
{
}

View File

@@ -42,14 +42,47 @@ Downloading a database from GitHub
.. include:: ../reusables/download-github-database.rst
.. _filtering-databases-and-queries-by-language:
Filtering databases and queries by language
-------------------------------------------
Optionally, to see databases containing a specific language and queries written for that language, you can apply a language filter using the language selector.
#. To see available language filters, in the sidebar, click the **Language** title bar.
#. Hover over the language filter you would like to apply, then click **Select**.
.. image:: ../images/codeql-for-visual-studio-code/choose-language-filter.png
:width: 350
:alt: Screenshot of the language selector. The "Select" button for a language filter is outlined in dark orange.
Creating a custom query
------------------------
You can generate a query template for a specific language from the queries panel, then write your own code to quickly create a custom query.
#. Optionally, to create a custom query in an existing directory, in the sidebar, click the **Queries** title bar to expand the queries panel, then select the desired directory.
#. In the sidebar, hover over the **Queries** title bar, then click the **Create query** icon.
.. image:: ../images/codeql-for-visual-studio-code/create-query-icon.png
:width: 350
:alt: Screenshot of the queries panel. The "Create query" icon is outlined in dark orange.
#. In the Command Palette, select the target language for your query. If you've chosen not to create your custom query in an existing directory, selecting a language will autogenerate a directory labeled ``codeql-custom-queries-<language>``, where ``<language>`` is the name of the selected language. A query template labeled ``example.ql`` will then be added to the existing or autogenerated directory.
#. In the template, write your custom query, then save the file. Once your query is finished, you can run it from the queries panel.
Running a query
------------------------
The `CodeQL repository <https://github.com/github/codeql>`__ on GitHub contains lots of example queries.
If you have that folder (or a different CodeQL pack) available in your workspace, you can access existing queries under ``<language>/ql/src/<category>``, for example ``java/ql/src/Likely Bugs``.
You can access any existing queries in your workspace through the queries panel.
#. Open a query (``.ql``) file. It is displayed in the editor, with IntelliSense features such as syntax highlighting and autocomplete suggestions.
#. Right-click in the query window and select **CodeQL: Run Query on Selected Database**. (Alternatively, run the command from the Command Palette.)
#. In the sidebar, to expand the queries panel, click the **Queries** title bar.
#. To run a query against the selected database, hover over the desired query, then click the **Run local query** icon.
.. image:: ../images/codeql-for-visual-studio-code/run-local-query-icon.png
:width: 350
:alt: Screenshot of the mouse pointer hovering over a query in the queries panel. The "Run local query" icon is outlined in dark orange.
The CodeQL extension runs the query on the current database and reports progress in the bottom right corner of the application.
When the results are ready, they're displayed in the Results view.
@@ -61,6 +94,23 @@ For more information, see ":doc:`Troubleshooting CodeQL for Visual Studio Code <
Running multiple queries
--------------------------
You can quickly run multiple queries against the database you've selected using the queries panel or a single command.
Running all queries in a directory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can easily run every query in a directory using the queries panel.
#. In the sidebar, to expand the queries panel, click the **Queries** title bar.
#. Hover over the desired directory of queries, then click the **Run local queries** icon.
.. image:: ../images/codeql-for-visual-studio-code/run-local-queries-icon.png
:width: 350
:alt: Screenshot of the mouse pointer hovering over a directory of queries in the queries panel. The "Run local queries" icon is outlined in dark orange.
Running a selection of queries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can run multiple queries with a single command.
#. Go to the File Explorer.
@@ -122,6 +172,7 @@ To see the queries that you have run in the current session, open the Query Hist
The Query History contains information including the date and time when the query was run, the name of the query, the database on which it was run, and how long it took to run the query.
To customize the information that is displayed, right-click an entry and select **Rename**.
You can also filter the Query History view by language using the language selector. For more information, see ":ref:`Filtering databases and queries by language <filtering-databases-and-queries-by-language>`."
Click an entry to display the corresponding results in the Query Results view, and double-click
to display the query itself in the editor (or right-click and select **View Query**).

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -49,7 +49,7 @@ The following properties are supported by all query files:
| | | ``warning`` | |
| | | ``recommendation`` | |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@security-severity``| ``<score>`` | Defines the level of severity, between 0.0 and 10.0, for queries with ``@tags security``. For more information about calculating ``@security-severity``, see the `GitHub changelog <https://github.blog/changelog/2021-07-19-codeql-code-scanning-new-severity-levels-for-security-alerts/>`__. |
| ``@security-severity``| ``<score>`` | Defines the level of severity, between 0.0 and 10.0, for queries with ``@tags security``. For more information about calculating ``@security-severity``, see the `GitHub changelog <https://gh.io/2021-07-19-codeql-security-severity>`__. |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Example

View File

@@ -1,3 +1,7 @@
## 0.0.2
No user-facing changes.
## 0.0.1
No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.1
lastReleaseVersion: 0.0.2

View File

@@ -1,5 +1,5 @@
name: codeql-go-consistency-queries
version: 0.0.2-dev
version: 0.0.2
groups:
- go
- queries

View File

@@ -1,3 +1,13 @@
## 0.7.3
### Minor Analysis Improvements
* Added the [gin cors](https://github.com/gin-contrib/cors) library to the CorsMisconfiguration.ql query
### Bug Fixes
* A bug has been fixed that meant that value flow through an array was not tracked correctly in some circumstances. Taint flow was tracked correctly.
## 0.7.2
### Minor Analysis Improvements

View File

@@ -0,0 +1,9 @@
## 0.7.3
### Minor Analysis Improvements
* Added the [gin cors](https://github.com/gin-contrib/cors) library to the CorsMisconfiguration.ql query
### Bug Fixes
* A bug has been fixed that meant that value flow through an array was not tracked correctly in some circumstances. Taint flow was tracked correctly.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.7.2
lastReleaseVersion: 0.7.3

View File

@@ -41,6 +41,7 @@ import semmle.go.frameworks.Email
import semmle.go.frameworks.Encoding
import semmle.go.frameworks.Fiber
import semmle.go.frameworks.Gin
import semmle.go.frameworks.GinCors
import semmle.go.frameworks.Glog
import semmle.go.frameworks.GoKit
import semmle.go.frameworks.GoMicro

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 0.7.3-dev
version: 0.7.3
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -724,16 +724,19 @@ class GenericTypeInstantiationExpr extends Expr {
* ```go
* a[1:3]
* a[1:3:5]
* a[1:]
* a[:3]
* a[:]
* ```
*/
class SliceExpr extends @sliceexpr, Expr {
/** Gets the base of this slice expression. */
Expr getBase() { result = this.getChildExpr(0) }
/** Gets the lower bound of this slice expression. */
/** Gets the lower bound of this slice expression, if any. */
Expr getLow() { result = this.getChildExpr(1) }
/** Gets the upper bound of this slice expression. */
/** Gets the upper bound of this slice expression, if any. */
Expr getHigh() { result = this.getChildExpr(2) }
/** Gets the maximum of this slice expression, if any. */

View File

@@ -21,7 +21,7 @@ predicate containerStoreStep(Node node1, Node node2, Content c) {
node2.getType() instanceof SliceType
) and
(
exists(Write w | w.writesElement(node2, _, node1))
exists(Write w | w.writesElement(node2.(PostUpdateNode).getPreUpdateNode(), _, node1))
or
node1 = node2.(ImplicitVarargsSlice).getCallNode().getAnImplicitVarargsArgument()
)

View File

@@ -0,0 +1,139 @@
/**
* Provides classes for modeling the `github.com/gin-contrib/cors` package.
*/
import go
/**
* Provides classes for modeling the `github.com/gin-contrib/cors` package.
*/
module GinCors {
/** Gets the package name `github.com/gin-gonic/gin`. */
string packagePath() { result = package("github.com/gin-contrib/cors", "") }
/**
* A new function create a new gin Handler that passed to gin as middleware
*/
class New extends Function {
New() { exists(Function f | f.hasQualifiedName(packagePath(), "New") | this = f) }
}
/**
* A write to the value of Access-Control-Allow-Credentials header
*/
class AllowCredentialsWrite extends DataFlow::ExprNode {
DataFlow::Node base;
AllowCredentialsWrite() {
exists(Field f, Write w |
f.hasQualifiedName(packagePath(), "Config", "AllowCredentials") and
w.writesField(base, f, this) and
this.getType() instanceof BoolType
)
}
/**
* Get config struct holding header values
*/
DataFlow::Node getBase() { result = base }
/**
* Get config variable holding header values
*/
GinConfig getConfig() {
exists(GinConfig gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
base.asInstruction() or
gc.getV().getAUse() = base
) and
result = gc
)
}
}
/**
* A write to the value of Access-Control-Allow-Origins header
*/
class AllowOriginsWrite extends DataFlow::ExprNode {
DataFlow::Node base;
AllowOriginsWrite() {
exists(Field f, Write w |
f.hasQualifiedName(packagePath(), "Config", "AllowOrigins") and
w.writesField(base, f, this) and
this.asExpr() instanceof SliceLit
)
}
/**
* Get config struct holding header values
*/
DataFlow::Node getBase() { result = base }
/**
* Get config variable holding header values
*/
GinConfig getConfig() {
exists(GinConfig gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
base.asInstruction() or
gc.getV().getAUse() = base
) and
result = gc
)
}
}
/**
* A write to the value of Access-Control-Allow-Origins of value "*", overriding AllowOrigins
*/
class AllowAllOriginsWrite extends DataFlow::ExprNode {
DataFlow::Node base;
AllowAllOriginsWrite() {
exists(Field f, Write w |
f.hasQualifiedName(packagePath(), "Config", "AllowAllOrigins") and
w.writesField(base, f, this) and
this.getType() instanceof BoolType
)
}
/**
* Get config struct holding header values
*/
DataFlow::Node getBase() { result = base }
/**
* Get config variable holding header values
*/
GinConfig getConfig() {
exists(GinConfig gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
base.asInstruction() or
gc.getV().getAUse() = base
) and
result = gc
)
}
}
/**
* A variable of type Config that holds the headers to be set.
*/
class GinConfig extends Variable {
SsaWithFields v;
GinConfig() {
this = v.getBaseVariable().getSourceVariable() and
exists(Type t | t.hasQualifiedName(packagePath(), "Config") | v.getType() = t)
}
/**
* Get variable declaration of GinConfig
*/
SsaWithFields getV() { result = v }
}
}

View File

@@ -1,3 +1,7 @@
## 0.7.3
No user-facing changes.
## 0.7.2
### Minor Analysis Improvements

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.7.2
lastReleaseVersion: 0.7.3

View File

@@ -0,0 +1,31 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>
If an LDAP connection uses user-supplied data as password, anonymous bind could be caused using an empty password
to result in a successful authentication.
</p>
</overview>
<recommendation>
<p>Don't use user-supplied data as password while establishing an LDAP connection.
</p>
</recommendation>
<example>
<p>In the following examples, the code accepts a bind password via a HTTP request in variable <code>
bindPassword</code>. The code builds a LDAP query whose authentication depends on user supplied data.</p>
<sample src="examples/LdapAuthBad.go" />
<p>In the following examples, the code accepts a bind password via a HTTP request in variable <code>
bindPassword</code>. The function ensures that the password provided is not empty before binding. </p>
<sample src="examples/LdapAuthGood.go" />
</example>
<references>
<li>MITRE: <a href="https://cwe.mitre.org/data/definitions/287.html">CWE-287: Improper Authentication</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,19 @@
/**
* @name Improper LDAP Authentication
* @description A user-controlled query carries no authentication
* @kind path-problem
* @problem.severity warning
* @id go/improper-ldap-auth
* @tags security
* experimental
* external/cwe/cwe-287
*/
import go
import ImproperLdapAuthCustomizations
import ImproperLdapAuth::Flow::PathGraph
from ImproperLdapAuth::Flow::PathNode source, ImproperLdapAuth::Flow::PathNode sink
where ImproperLdapAuth::Flow::flowPath(source, sink)
select sink.getNode(), source, sink, "LDAP binding password depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -0,0 +1,84 @@
import go
import semmle.go.dataflow.barrierguardutil.RegexpCheck
module ImproperLdapAuth {
/**
* A sink that is vulnerable to improper LDAP Authentication vulnerabilities.
*/
abstract class LdapAuthSink extends DataFlow::Node { }
/**
* A sanitizer function that prevents improper LDAP Authentication attacks.
*/
abstract class LdapSanitizer extends DataFlow::Node { }
/**
* A vulnerable argument to `go-ldap` or `ldap`'s `bind` function (Only v2).
*/
private class GoLdapBindSink extends LdapAuthSink {
GoLdapBindSink() {
exists(Method meth |
meth.hasQualifiedName("gopkg.in/ldap.v2", "Conn", "Bind") and
this = meth.getACall().getArgument(1)
)
}
}
/**
* A call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs.
*
* This is overapproximate: we do not attempt to reason about the correctness of the regexp.
*/
class RegexpCheckAsBarrierGuard extends RegexpCheckBarrier, LdapSanitizer { }
/**
* An empty string.
*/
class EmptyString extends DataFlow::Node {
EmptyString() { this.asExpr().getStringValue() = "" }
}
private predicate equalityAsSanitizerGuard(DataFlow::Node g, Expr e, boolean outcome) {
exists(DataFlow::Node nonConstNode, DataFlow::Node constNode, DataFlow::EqualityTestNode eq |
g = eq and
nonConstNode = eq.getAnOperand() and
not nonConstNode.isConst() and
constNode = eq.getAnOperand() and
constNode.isConst() and
e = nonConstNode.asExpr() and
(
// If `constNode` is not an empty string a comparison is considered a sanitizer
not constNode instanceof EmptyString and outcome = eq.getPolarity()
or
// If `constNode` is an empty string a not comparison is considered a sanitizer
constNode instanceof EmptyString and outcome = eq.getPolarity().booleanNot()
)
)
}
/**
* An equality check comparing a data-flow node against a constant string, considered as
* a barrier guard for sanitizing untrusted user input.
*/
class EqualityAsSanitizerGuard extends LdapSanitizer {
EqualityAsSanitizerGuard() {
this = DataFlow::BarrierGuard<equalityAsSanitizerGuard/3>::getABarrierNode()
}
}
private module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof UntrustedFlowSource or source instanceof EmptyString
}
predicate isSink(DataFlow::Node sink) { sink instanceof LdapAuthSink }
predicate isBarrier(DataFlow::Node node) { node instanceof LdapSanitizer }
}
/**
* Tracks taint flow for reasoning about improper ldap auth vulnerabilities
* with sinks which are not sanitized by string comparisons.
*/
module Flow = TaintTracking::Global<Config>;
}

View File

@@ -0,0 +1,22 @@
package main
import (
"fmt"
"log"
)
func bad() interface{} {
bindPassword := req.URL.Query()["password"][0]
// Connect to the LDAP server
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
log.Fatalf("Failed to connect to LDAP server: %v", err)
}
defer l.Close()
err = l.Bind("cn=admin,dc=example,dc=com", bindPassword)
if err != nil {
log.Fatalf("LDAP bind failed: %v", err)
}
}

View File

@@ -0,0 +1,24 @@
package main
import (
"fmt"
"log"
)
func good() interface{} {
bindPassword := req.URL.Query()["password"][0]
// Connect to the LDAP server
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
if err != nil {
log.Fatalf("Failed to connect to LDAP server: %v", err)
}
defer l.Close()
if bindPassword != "" {
err = l.Bind("cn=admin,dc=example,dc=com", bindPassword)
if err != nil {
log.Fatalf("LDAP bind failed: %v", err)
}
}
}

View File

@@ -69,22 +69,53 @@ module UntrustedToAllowOriginHeaderConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSinkHW(sink, _) }
}
module UntrustedToAllowOriginConfigConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
additional predicate isSinkWrite(DataFlow::Node sink, GinCors::AllowOriginsWrite w) { sink = w }
predicate isSink(DataFlow::Node sink) { isSinkWrite(sink, _) }
}
/**
* Tracks taint flowfor reasoning about when an `UntrustedFlowSource` flows to
* a `HeaderWrite` that writes an `Access-Control-Allow-Origin` header's value.
*/
module UntrustedToAllowOriginHeaderFlow = TaintTracking::Global<UntrustedToAllowOriginHeaderConfig>;
/**
* Tracks taint flowfor reasoning about when an `UntrustedFlowSource` flows to
* a `AllowOriginsWrite` that writes an `Access-Control-Allow-Origin` header's value.
*/
module UntrustedToAllowOriginConfigFlow = TaintTracking::Global<UntrustedToAllowOriginConfigConfig>;
/**
* Holds if the provided `allowOriginHW` HeaderWrite's parent ResponseWriter
* also has another HeaderWrite that sets a `Access-Control-Allow-Credentials`
* header to `true`.
*/
predicate allowCredentialsIsSetToTrue(AllowOriginHeaderWrite allowOriginHW) {
predicate allowCredentialsIsSetToTrue(DataFlow::ExprNode allowOriginHW) {
exists(AllowCredentialsHeaderWrite allowCredentialsHW |
allowCredentialsHW.getHeaderValue().toLowerCase() = "true"
|
allowOriginHW.getResponseWriter() = allowCredentialsHW.getResponseWriter()
allowOriginHW.(AllowOriginHeaderWrite).getResponseWriter() =
allowCredentialsHW.getResponseWriter()
)
or
exists(GinCors::AllowCredentialsWrite allowCredentialsGin |
allowCredentialsGin.getExpr().getBoolValue() = true
|
allowCredentialsGin.getConfig() = allowOriginHW.(GinCors::AllowOriginsWrite).getConfig() and
not exists(GinCors::AllowAllOriginsWrite allowAllOrigins |
allowAllOrigins.getExpr().getBoolValue() = true and
allowCredentialsGin.getConfig() = allowAllOrigins.getConfig()
)
or
allowCredentialsGin.getBase() = allowOriginHW.(GinCors::AllowOriginsWrite).getBase() and
not exists(GinCors::AllowAllOriginsWrite allowAllOrigins |
allowAllOrigins.getExpr().getBoolValue() = true and
allowCredentialsGin.getBase() = allowAllOrigins.getBase()
)
)
}
@@ -93,10 +124,13 @@ predicate allowCredentialsIsSetToTrue(AllowOriginHeaderWrite allowOriginHW) {
* UntrustedFlowSource.
* The `message` parameter is populated with the warning message to be returned by the query.
*/
predicate flowsFromUntrustedToAllowOrigin(AllowOriginHeaderWrite allowOriginHW, string message) {
predicate flowsFromUntrustedToAllowOrigin(DataFlow::ExprNode allowOriginHW, string message) {
exists(DataFlow::Node sink |
UntrustedToAllowOriginHeaderFlow::flowTo(sink) and
UntrustedToAllowOriginHeaderConfig::isSinkHW(sink, allowOriginHW)
or
UntrustedToAllowOriginConfigFlow::flowTo(sink) and
UntrustedToAllowOriginConfigConfig::isSinkWrite(sink, allowOriginHW)
|
message =
headerAllowOrigin() + " header is set to a user-defined value, and " +
@@ -108,11 +142,23 @@ predicate flowsFromUntrustedToAllowOrigin(AllowOriginHeaderWrite allowOriginHW,
* Holds if the provided `allowOriginHW` HeaderWrite is for a `Access-Control-Allow-Origin`
* header and the value is set to `null`.
*/
predicate allowOriginIsNull(AllowOriginHeaderWrite allowOriginHW, string message) {
allowOriginHW.getHeaderValue().toLowerCase() = "null" and
predicate allowOriginIsNull(DataFlow::ExprNode allowOriginHW, string message) {
allowOriginHW.(AllowOriginHeaderWrite).getHeaderValue().toLowerCase() = "null" and
message =
headerAllowOrigin() + " header is set to `" + allowOriginHW.getHeaderValue() + "`, and " +
headerAllowCredentials() + " is set to `true`"
headerAllowOrigin() + " header is set to `" +
allowOriginHW.(AllowOriginHeaderWrite).getHeaderValue() + "`, and " + headerAllowCredentials()
+ " is set to `true`"
or
allowOriginHW
.(GinCors::AllowOriginsWrite)
.asExpr()
.(SliceLit)
.getAnElement()
.getStringValue()
.toLowerCase() = "null" and
message =
headerAllowOrigin() + " header is set to `" + "null" + "`, and " + headerAllowCredentials() +
" is set to `true`"
}
/**
@@ -170,7 +216,7 @@ module FromUntrustedFlow = TaintTracking::Global<FromUntrustedConfig>;
/**
* Holds if the provided `allowOriginHW` is also destination of a `UntrustedFlowSource`.
*/
predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW) {
predicate flowsToGuardedByCheckOnUntrusted(DataFlow::ExprNode allowOriginHW) {
exists(DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn |
FromUntrustedFlow::flowTo(sink) and FromUntrustedConfig::isSinkCgn(sink, cgn)
|
@@ -178,7 +224,7 @@ predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW)
)
}
from AllowOriginHeaderWrite allowOriginHW, string message
from DataFlow::ExprNode allowOriginHW, string message
where
allowCredentialsIsSetToTrue(allowOriginHW) and
(

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 0.7.3-dev
version: 0.7.3
groups:
- go
- queries

View File

@@ -0,0 +1,14 @@
edges
| ImproperLdapAuth.go:18:18:18:24 | selection of URL | ImproperLdapAuth.go:18:18:18:32 | call to Query |
| ImproperLdapAuth.go:18:18:18:32 | call to Query | ImproperLdapAuth.go:28:23:28:34 | bindPassword |
| ImproperLdapAuth.go:87:18:87:19 | "" | ImproperLdapAuth.go:97:23:97:34 | bindPassword |
nodes
| ImproperLdapAuth.go:18:18:18:24 | selection of URL | semmle.label | selection of URL |
| ImproperLdapAuth.go:18:18:18:32 | call to Query | semmle.label | call to Query |
| ImproperLdapAuth.go:28:23:28:34 | bindPassword | semmle.label | bindPassword |
| ImproperLdapAuth.go:87:18:87:19 | "" | semmle.label | "" |
| ImproperLdapAuth.go:97:23:97:34 | bindPassword | semmle.label | bindPassword |
subpaths
#select
| ImproperLdapAuth.go:28:23:28:34 | bindPassword | ImproperLdapAuth.go:18:18:18:24 | selection of URL | ImproperLdapAuth.go:28:23:28:34 | bindPassword | LDAP binding password depends on a $@. | ImproperLdapAuth.go:18:18:18:24 | selection of URL | user-provided value |
| ImproperLdapAuth.go:97:23:97:34 | bindPassword | ImproperLdapAuth.go:87:18:87:19 | "" | ImproperLdapAuth.go:97:23:97:34 | bindPassword | LDAP binding password depends on a $@. | ImproperLdapAuth.go:87:18:87:19 | "" | user-provided value |

View File

@@ -0,0 +1,108 @@
package main
//go:generate depstubber -vendor gopkg.in/ldap.v2 Conn Dial
import (
"fmt"
"log"
"net/http"
"regexp"
ldap "gopkg.in/ldap.v2"
)
func bad(w http.ResponseWriter, req *http.Request) (interface{}, error) {
ldapServer := "ldap.example.com"
ldapPort := 389
bindDN := "cn=admin,dc=example,dc=com"
bindPassword := req.URL.Query()["password"][0]
// Connect to the LDAP server
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
if err != nil {
return fmt.Errorf("Failed to connect to LDAP server: %v", err), err
}
defer l.Close()
// BAD: user input is not sanetized
err = l.Bind(bindDN, bindPassword)
if err != nil {
return fmt.Errorf("LDAP bind failed: %v", err), err
}
return nil, nil
}
func good1(w http.ResponseWriter, req *http.Request) (interface{}, error) {
ldapServer := "ldap.example.com"
ldapPort := 389
bindDN := "cn=admin,dc=example,dc=com"
bindPassword := req.URL.Query()["password"][0]
// Connect to the LDAP server
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
if err != nil {
return fmt.Errorf("Failed to connect to LDAP server: %v", err), err
}
defer l.Close()
hasEmptyInput, _ := regexp.MatchString("^\\s*$", bindPassword)
// GOOD : bindPassword is not empty
if !hasEmptyInput {
l.Bind(bindDN, bindPassword)
}
if err != nil {
return fmt.Errorf("LDAP bind failed: %v", err), err
}
return nil, nil
}
func good2(w http.ResponseWriter, req *http.Request) (interface{}, error) {
ldapServer := "ldap.example.com"
ldapPort := 389
bindDN := "cn=admin,dc=example,dc=com"
bindPassword := req.URL.Query()["password"][0]
// Connect to the LDAP server
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
if err != nil {
return fmt.Errorf("Failed to connect to LDAP server: %v", err), err
}
defer l.Close()
// GOOD : bindPassword is not empty
if bindPassword != "" {
l.Bind(bindDN, bindPassword)
return nil, err
}
return nil, nil
}
func bad2(req *http.Request) {
// LDAP server details
ldapServer := "ldap.example.com"
ldapPort := 389
bindDN := "cn=admin,dc=example,dc=com"
// BAD : empty password
bindPassword := ""
// Connect to the LDAP server
l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
if err != nil {
log.Fatalf("Failed to connect to LDAP server: %v", err)
}
defer l.Close()
// BAD : bindPassword is empty
err = l.Bind(bindDN, bindPassword)
if err != nil {
log.Fatalf("LDAP bind failed: %v", err)
}
}
func main() {
bad(nil, nil)
good1(nil, nil)
good2(nil, nil)
bad2(nil)
}

View File

@@ -0,0 +1 @@
experimental/CWE-287/ImproperLdapAuth.ql

View File

@@ -0,0 +1,7 @@
module main
go 1.19
require gopkg.in/ldap.v2 v2.5.1
require gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect

View File

@@ -0,0 +1,185 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for gopkg.in/ldap.v2, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: gopkg.in/ldap.v2 (exports: Conn; functions: Dial)
// Package ldap is a stub of gopkg.in/ldap.v2, generated by depstubber.
package ldap
import (
tls "crypto/tls"
time "time"
)
type AddRequest struct {
DN string
Attributes []Attribute
}
func (_ *AddRequest) Attribute(_ string, _ []string) {}
type Attribute struct {
Type string
Vals []string
}
type Conn struct {
Debug interface{}
}
func (_ *Conn) Add(_ *AddRequest) error {
return nil
}
func (_ *Conn) Bind(_ string, _ string) error {
return nil
}
func (_ *Conn) Close() {}
func (_ *Conn) Compare(_ string, _ string, _ string) (bool, error) {
return false, nil
}
func (_ *Conn) Del(_ *DelRequest) error {
return nil
}
func (_ *Conn) Modify(_ *ModifyRequest) error {
return nil
}
func (_ *Conn) PasswordModify(_ *PasswordModifyRequest) (*PasswordModifyResult, error) {
return nil, nil
}
func (_ *Conn) Search(_ *SearchRequest) (*SearchResult, error) {
return nil, nil
}
func (_ *Conn) SearchWithPaging(_ *SearchRequest, _ uint32) (*SearchResult, error) {
return nil, nil
}
func (_ *Conn) SetTimeout(_ time.Duration) {}
func (_ *Conn) SimpleBind(_ *SimpleBindRequest) (*SimpleBindResult, error) {
return nil, nil
}
func (_ *Conn) Start() {}
func (_ *Conn) StartTLS(_ *tls.Config) error {
return nil
}
type Control interface {
Encode() interface{}
GetControlType() string
String() string
}
type DelRequest struct {
DN string
Controls []Control
}
func Dial(_ string, _ string) (*Conn, error) {
return nil, nil
}
type Entry struct {
DN string
Attributes []*EntryAttribute
}
func (_ *Entry) GetAttributeValue(_ string) string {
return ""
}
func (_ *Entry) GetAttributeValues(_ string) []string {
return nil
}
func (_ *Entry) GetRawAttributeValue(_ string) []byte {
return nil
}
func (_ *Entry) GetRawAttributeValues(_ string) [][]byte {
return nil
}
func (_ *Entry) PrettyPrint(_ int) {}
func (_ *Entry) Print() {}
type EntryAttribute struct {
Name string
Values []string
ByteValues [][]byte
}
func (_ *EntryAttribute) PrettyPrint(_ int) {}
func (_ *EntryAttribute) Print() {}
type ModifyRequest struct {
DN string
AddAttributes []PartialAttribute
DeleteAttributes []PartialAttribute
ReplaceAttributes []PartialAttribute
}
func (_ *ModifyRequest) Add(_ string, _ []string) {}
func (_ *ModifyRequest) Delete(_ string, _ []string) {}
func (_ *ModifyRequest) Replace(_ string, _ []string) {}
type PartialAttribute struct {
Type string
Vals []string
}
type PasswordModifyRequest struct {
UserIdentity string
OldPassword string
NewPassword string
}
type PasswordModifyResult struct {
GeneratedPassword string
}
type SearchRequest struct {
BaseDN string
Scope int
DerefAliases int
SizeLimit int
TimeLimit int
TypesOnly bool
Filter string
Attributes []string
Controls []Control
}
type SearchResult struct {
Entries []*Entry
Referrals []string
Controls []Control
}
func (_ *SearchResult) PrettyPrint(_ int) {}
func (_ *SearchResult) Print() {}
type SimpleBindRequest struct {
Username string
Password string
Controls []Control
}
type SimpleBindResult struct {
Controls []Control
}

View File

@@ -0,0 +1,6 @@
# gopkg.in/ldap.v2 v2.5.1
## explicit
gopkg.in/ldap.v2
# gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d
## explicit
gopkg.in/asn1-ber.v1

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