Compare commits

...

580 Commits

Author SHA1 Message Date
Shati Patel
c53ce00944 Merge pull request #5342 from shati-patel/docs-delete-unused-script
Docs: Remove unused script and workflow
2021-03-05 18:02:50 +00:00
Shati Patel
85205a21de Docs: Remove query help script 2021-03-05 16:02:53 +00:00
Jonas Jensen
767d3141ad Merge pull request #5336 from MathiasVP/fix-join-order-in-memset-may-be-deleted
C++: Fix performance in cpp/memset-may-be-deleted.
2021-03-05 13:08:10 +01:00
Mathias Vorreiter Pedersen
2d7f15cc8a C++: Fix join-order in cpp/memset-may-be-deleted. 2021-03-05 11:38:15 +01:00
Anders Schack-Mulligen
220383b9fb Merge pull request #5313 from joefarebrother/guava-change-note
Java: Add change note for Guava
2021-03-03 13:03:54 +01:00
Anders Schack-Mulligen
663c72ab1d Update java/change-notes/2021-03-23-guava-collections-and-preconditions.md 2021-03-03 12:53:16 +01:00
Joe Farebrother
a77cf12596 Add change note for Guava 2021-03-03 10:56:12 +00:00
Calum Grant
cee96775b8 Merge pull request #5305 from asgerf/js/tuple-type-rest-index-stats
JS: Regenerate stats for tuple_type_rest_index
2021-03-01 17:43:55 +00:00
Asger Feldthaus
26924a3378 JS: Regenerate stats for tuple_type_rest_index 2021-03-01 16:30:09 +00:00
Tamás Vajk
2ac94255b7 Merge pull request #5299 from tamasvajk/feature/limit-codescanning-csharp2
C#: Fix codeql analysis workflow
2021-03-01 16:20:03 +01:00
Tamas Vajk
1ecbbf6af3 C#: Fix codeql analysis workflow 2021-03-01 09:18:05 +01:00
Anders Schack-Mulligen
37baf77b93 Merge pull request #5273 from intrigus-lgtm/java/unify-main-method-check
Java: Remove duplicate code.
2021-03-01 09:05:28 +01:00
Tamás Vajk
3b56e3520c Merge pull request #5277 from tamasvajk/feature/fix-name-resolution
Fix method name resolution issue with nullable suppression
2021-03-01 08:47:21 +01:00
Jonas Jensen
208a374c58 Merge pull request #5256 from MathiasVP/promote-insecure-memset-query
C++: Promote insecure removal of memset query
2021-03-01 08:30:16 +01:00
Mathias Vorreiter Pedersen
d4f7fab7df Update cpp/change-notes/2021-02-24-memset-may-be-deleted.md
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
2021-02-26 19:17:13 +01:00
Mathias Vorreiter Pedersen
0f7256752a Update cpp/ql/src/Security/CWE/CWE-014/MemsetMayBeDeleted.qhelp
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
2021-02-26 19:16:28 +01:00
CodeQL CI
b7c0d18c4a Merge pull request #5278 from erik-krogh/formData
Approved by asgerf
2021-02-26 08:13:41 -08:00
CodeQL CI
0e70b58a41 Merge pull request #5205 from erik-krogh/ts42
Approved by asgerf
2021-02-26 05:06:40 -08:00
Tom Hvitved
ac67c67ad7 Merge pull request #4998 from hvitved/csharp/shared-base-pre-ssa
C#: Use shared SSA implementation for `{Pre,Base}Ssa`
2021-02-26 11:29:07 +01:00
Erik Krogh Kristensen
c59e6fef80 add model for form-data 2021-02-26 10:54:46 +01:00
Erik Krogh Kristensen
00cfc77fc0 Revert "fix file lookup for exclude patterns"
This reverts commit 74630b0fd8.
2021-02-26 10:28:20 +01:00
Erik Krogh Kristensen
4ec3289ecc update relation name in .stats file 2021-02-26 10:26:08 +01:00
Erik Krogh Kristensen
bd19d5a93c remove is_abstract_signature.ql 2021-02-26 10:24:40 +01:00
Erik Krogh Kristensen
1cac692b1d Update javascript/ql/src/semmle/javascript/TypeScript.qll
Co-authored-by: Asger F <asgerf@github.com>
2021-02-26 10:23:01 +01:00
Mathias Vorreiter Pedersen
42d2a673c7 C++: Respond to review comments. 2021-02-26 10:06:05 +01:00
Tamas Vajk
b3d6d0c12b Fix method name resolution issue with nullable suppression 2021-02-26 09:48:37 +01:00
Mathias Vorreiter Pedersen
4e4ffbd790 Update cpp/change-notes/2021-02-24-memset-may-be-deleted.md
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-02-26 09:48:21 +01:00
Mathias Vorreiter Pedersen
72daf2eef9 C++: Make the tests more realistic by actually using the local variable for something. Otherwise it looks like a zero-initialization of a buffer, which the query now tries to exclude. 2021-02-26 09:19:05 +01:00
Tamás Vajk
ce69e3ae66 Merge pull request #5263 from tamasvajk/feature/fix-file-move
C#: Fix potentially concurrent file moves
2021-02-26 08:27:42 +01:00
Tamás Vajk
8241a9c2f1 Merge pull request #5264 from tamasvajk/feature/more-known-enums
C#: Add more well-known enum underlying types
2021-02-26 08:20:14 +01:00
yoff
e3b3825ab0 Merge pull request #5151 from RasmusWL/django-get-redirect-url
Python: Model get_redirect_url in django
2021-02-25 23:07:33 +01:00
intrigus
141f057f7b Java: Remove duplicate code. 2021-02-25 21:29:26 +01:00
Mathias Vorreiter Pedersen
faadcd913e C++: Exclude memsets that clear a variable that has no other uses. 2021-02-25 21:27:12 +01:00
Geoffrey White
0c4a5f5e2a Merge pull request #5266 from geoffw0/isis
JS: Fix 'is, is' and 'is is'.
2021-02-25 18:55:41 +00:00
Mathias Vorreiter Pedersen
2777ca445e Update cpp/ql/src/Security/CWE/CWE-014/MemsetMayBeDeleted.ql
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-02-25 19:49:58 +01:00
Mathias Vorreiter Pedersen
9e7c9d0ea0 C++: Respond to review comments. Relax the escaping requirements on the local variable being used in memset. 2021-02-25 18:22:48 +01:00
CodeQL CI
1bd12e6fdf Merge pull request #5199 from asgerf/js/vue-router
Approved by erik-krogh
2021-02-25 07:32:57 -08:00
Tamás Vajk
505d04b13e Merge pull request #5102 from luchua-bc/java/main-method-in-servlet
Java: CWE-489 Query to detect main() method in servlets
2021-02-25 16:05:06 +01:00
Mathias Vorreiter Pedersen
3f26b2940d Update cpp/ql/src/Security/CWE/CWE-014/MemsetMayBeDeleted.ql
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-02-25 15:48:48 +01:00
Geoffrey White
0e071b7b79 JS: Fix 'is, is' and 'is is'. 2021-02-25 14:16:25 +00:00
Tamas Vajk
3e651f14fd C#: Add more well-known enum underlying types 2021-02-25 14:57:23 +01:00
Rasmus Wriedt Larsen
81b29316e1 Merge pull request #4737 from yoff/python-dataflow-add-cast-nodes
Python: Force read- and store steps to add nodes.
2021-02-25 14:28:54 +01:00
Tamás Vajk
9ae22cbebd Merge pull request #5189 from tamasvajk/feature/refactor-3
C#: Split 'Context' class between CIL and source extraction
2021-02-25 14:28:25 +01:00
Bas van Schaik
5ecd2317b0 Merge pull request #5212 from github/sj-patch-1
Include @xcorail (GHSL) in code reviews for `experimental` queries
2021-02-25 12:58:12 +00:00
Taus
d326d40d71 Merge pull request #5252 from RasmusWL/test-cleanup
Python: Minor cleanup of test setup
2021-02-25 13:33:10 +01:00
Mathias Vorreiter Pedersen
d33209388d C++: Fix test annotations. Also exclude static locals from the query and add a testcase for this. 2021-02-25 13:25:11 +01:00
Taus
01d581ecf3 Merge pull request #5250 from tausbn/python-port-re-security-queries
Python: Port URL sanitisation queries to API graphs
2021-02-25 13:13:55 +01:00
Rasmus Lerchedahl Petersen
64c0eaf305 Python: Update test expectations 2021-02-25 11:49:57 +01:00
yoff
f15084254b Add comment explaining tacky nature of code 2021-02-25 11:49:57 +01:00
Rasmus Lerchedahl Petersen
5b51a3461d Python: Force read- and store steps to add nodes.
This gives muche nicer path explanations on some snapshots.
It is achieved by making stepped-to nodes `CastNode`s.
This seems somewhat reasonable as types then to change, when we move
between content and container.
We could probably refine it, though.
2021-02-25 11:49:57 +01:00
Asger Feldthaus
55a1ab5714 JS: Autoformat 2021-02-25 10:20:13 +00:00
Tamas Vajk
a5543c689e C#: Fix potentially concurrent file moves 2021-02-25 10:35:49 +01:00
Jonas Jensen
2b54c33904 Merge pull request #5257 from MathiasVP/doh-its-2021-mathias
C++: Turns out we're in 2021 and not 2020.
2021-02-25 09:30:08 +01:00
Anders Schack-Mulligen
f0d3841369 Merge pull request #5105 from JLLeitschuh/feat/JLL/depricated_bintray_usage
CWE-1104: Maven POM dependence upon Bintray/JCenter
2021-02-25 09:08:31 +01:00
Bas van Schaik
4ede277c7c Update CODEOWNERS 2021-02-24 18:30:22 +00:00
luchua-bc
e34a203731 Refactor the check of a main method in a test program to improve maintainability 2021-02-24 17:15:08 +00:00
Mathias Vorreiter Pedersen
70a953b633 C++: Add change-note. 2021-02-24 18:02:16 +01:00
Mathias Vorreiter Pedersen
ef8b734863 C++: Move tests out of experimental and merge with old existing tests from the other memset PRs. 2021-02-24 18:02:16 +01:00
Mathias Vorreiter Pedersen
c44fbaaf3c C++: Promote memset query out of experimental. 2021-02-24 18:01:41 +01:00
Jonathan Leitschuh
237fefbcf1 Add release notes 2021-02-24 11:19:20 -05:00
Mathias Vorreiter Pedersen
fc4162ba1a C++: Turns out we're in 2021 and not 2020. 2021-02-24 17:15:51 +01:00
Cornelius Riemenschneider
cea1049745 Merge pull request #5249 from geoffw0/cleanupstr
C++: QLDoc Pure.qll
2021-02-24 16:42:41 +01:00
Tamas Vajk
4711856c2b Remove commented code 2021-02-24 16:21:19 +01:00
Tamas Vajk
841ef9a4ae Make derived 'Context' classes internal and adjust visibility of members in base 'Context' 2021-02-24 16:21:19 +01:00
Tamas Vajk
539fdf952a Extend base context in CIL project 2021-02-24 16:21:19 +01:00
Tamas Vajk
5fca946678 C#: Split 'Context' class between CIL and source extraction 2021-02-24 16:21:19 +01:00
Bas van Schaik
4b884bd5d2 Merge branch 'main' into sj-patch-1 2021-02-24 15:10:26 +00:00
CodeQL CI
bf66bdbb95 Merge pull request #5253 from RasmusWL/no-getAnArg
Approved by tausbn
2021-02-24 06:34:31 -08:00
Rasmus Wriedt Larsen
d05a8b8c46 Python: Remove getAnArg in DataFlow::CallCfgNode
Until we've had further discussion on what is the right approach to
naming (internal discussion in https://github.com/github/codeql-python-team/issues/95)
2021-02-24 14:58:48 +01:00
Felicity Chapman
a05904f812 Merge pull request #5216 from github/felicitymay-update-process
Remove personal assignment to writers
2021-02-24 12:59:08 +00:00
Tamás Vajk
fd4eca6039 Merge pull request #5254 from tamasvajk/feature/fix-merge
C#: Fix merge conflict (with + refactoring)
2021-02-24 12:07:34 +01:00
CodeQL CI
d2816b33e2 Merge pull request #5240 from erik-krogh/vsPerf
Approved by asgerf
2021-02-24 02:26:16 -08:00
Taus Brock-Nannestad
404649d5f1 Python: Get rid of superfluous options file 2021-02-24 11:24:43 +01:00
Rasmus Wriedt Larsen
5c6989cf02 Revert "Python: Accept RequestWithoutValidation expected output change"
Apparently CI is able to produce the ../ path, I have absolutely no clue what is
goign on...
2021-02-24 11:14:18 +01:00
Erik Krogh Kristensen
055275b971 change stats file 2021-02-24 11:12:31 +01:00
Anders Schack-Mulligen
add960bc4d Merge pull request #4880 from luchua-bc/java/sensitive-query-with-get
Java: Sensitive GET Query
2021-02-24 11:08:47 +01:00
Asger Feldthaus
bb858d38c4 JS: Tweak ExprNode 2021-02-24 10:03:45 +00:00
Tamas Vajk
380058a4bd C#: Fix merge conflict (with + refactoring) 2021-02-24 10:50:51 +01:00
yoff
8262f0343b Merge pull request #5208 from RasmusWL/flask-clean-models
Python: Cleanup Flask models now that we have API graphs
2021-02-24 10:36:30 +01:00
Erik Krogh Kristensen
16150a6419 update printAst expected output 2021-02-24 10:29:29 +01:00
Erik Krogh Kristensen
ed47697c09 update expected output 2021-02-24 10:29:12 +01:00
Geoffrey White
358a8fee7d C++: 'side-effect free'. 2021-02-24 09:25:11 +00:00
Taus Brock-Nannestad
af644a0adb Python: Decrease import depth in regex tests
These were increased because of the indirection needed to get to the
regex flags, but as we no longer rely on this, we can make do with a
smaller import depth.
2021-02-24 10:23:01 +01:00
Rasmus Wriedt Larsen
5bb4a1a45a Python: Use explicit argument specification instead of getAnArg
I've seen quite a few places where `getAnArg` leads to wrong behavior, and I
generally just don't like it.
2021-02-24 10:19:34 +01:00
Taus Brock-Nannestad
e77c1059a3 Python: Use source nodes and prevent bad join order 2021-02-24 10:18:54 +01:00
Taus Brock-Nannestad
cac6c4acc9 Python: Add deprecation notice to mode_from_mode_object 2021-02-24 10:18:21 +01:00
Rasmus Wriedt Larsen
0b9a65d234 Python: Accept RequestWithoutValidation expected output change
I have no clue why this changed, but since it's only the `..` part, I guess
we'll live with it
2021-02-24 10:13:25 +01:00
Rasmus Wriedt Larsen
cef37d19ce Python: Split CWE-295 tests
Mostly just because it's nice. But now we can avoid having the same `options`
files for the tests.
2021-02-24 10:12:45 +01:00
Rasmus Wriedt Larsen
0ffc801f9b Python: Remove options for InsecureTemporaryFile tests 2021-02-24 09:57:51 +01:00
Erik Krogh Kristensen
5091bb652f bump extractor version 2021-02-24 09:39:09 +01:00
Erik Krogh Kristensen
971ce83f8e add change note 2021-02-24 09:34:54 +01:00
Erik Krogh Kristensen
bcb3d5aec2 add tests for nested type unions through aliases 2021-02-24 09:34:54 +01:00
Erik Krogh Kristensen
85ed402b1a add test for union types 2021-02-24 09:34:53 +01:00
Erik Krogh Kristensen
5ae3c5952c support abstract signatures 2021-02-24 09:34:53 +01:00
Erik Krogh Kristensen
f385c55f2c add support for rest types elements in the middle of a tuple 2021-02-24 09:34:53 +01:00
Erik Krogh Kristensen
74630b0fd8 fix file lookup for exclude patterns 2021-02-24 09:34:53 +01:00
Erik Krogh Kristensen
8cf28c6186 update TypeScript to 4.2 2021-02-24 09:34:47 +01:00
yoff
c3d2001e85 Merge pull request #5251 from tausbn/python-port-missing-host-key-validation-query
Python: Port missing host key validation query
2021-02-24 08:43:52 +01:00
yo-h
1d654febfd Merge pull request #5195 from aschackmull/java/cwe-548-test
Java: Add empty file to test.
2021-02-23 21:12:40 -05:00
Taus Brock-Nannestad
2942a11a69 Python: Import API graphs privately 2021-02-23 22:45:39 +01:00
Taus Brock-Nannestad
f241dbabab Python: Clean up query a bit 2021-02-23 22:33:18 +01:00
Taus Brock-Nannestad
002d0fe565 Python: Port missing host key query 2021-02-23 22:26:03 +01:00
Taus Brock-Nannestad
e812eb777d Python: Port URL sanitisation queries to API graphs
Really, this boils down to "Port `re` library model to use API graphs
instead of points-to", which is what this PR actually does.

Instead of using points-to to track flags, we use a type tracker. To
handle multiple flags at the same time, we add additional flow from

`x` to `x | y` and `y | x`

and, as an added bonus, the above with `+` instead of `|`, neatly
fixing https://github.com/github/codeql/issues/4707

I had to modify the `Qualified.ql` test slightly, as it now had a
result stemming from the standard library (in `warnings.py`) that
points-to previously ignored.

It might be possible to implement this as a type tracker on
`LocalSourceNode`s, but with the added steps for the above operations,
this was not obvious to me, and so I opted for the simpler
"`smallstep`" variant.
2021-02-23 22:02:35 +01:00
Rasmus Wriedt Larsen
358ade67e5 Merge pull request #5248 from tausbn/python-port-insecure-temporary-file
Python: Port `py/insecure-temporary-file`
2021-02-23 21:37:59 +01:00
Tamás Vajk
91928fa098 Merge pull request #5220 from tamasvajk/feature/limit-codescanning-csharp
Limit C# codeql analysis to the csharp folder
2021-02-23 21:05:38 +01:00
Tamás Vajk
e6532cbd75 Merge pull request #4695 from tamasvajk/feature/csharp9-with-expr
C#: Extract 'with' expressions
2021-02-23 21:04:51 +01:00
Geoffrey White
431a004127 C++: QLDoc. 2021-02-23 19:10:03 +00:00
Taus Brock-Nannestad
b8ce5e969e Python: Port py/insecure-temporary-file 2021-02-23 20:02:22 +01:00
yoff
9eed17f647 Merge pull request #5152 from RasmusWL/improve-pyyaml-support
Python: Improve pyyaml support
2021-02-23 19:58:04 +01:00
CodeQL CI
c5ae8d2c53 Merge pull request #5210 from erik-krogh/barrierPerf
Approved by asgerf
2021-02-23 07:29:27 -08:00
luchua-bc
56e3b301e9 Resolve ambiguous method access 2021-02-23 15:18:07 +00:00
luchua-bc
45f9125bfa Update test program 2021-02-23 14:41:44 +00:00
luchua-bc
9eb8ec7da5 Create a separate file for EJB check 2021-02-23 14:38:15 +00:00
Rasmus Wriedt Larsen
6e2445cce6 Python: Apply suggestions from code review
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-02-23 15:19:29 +01:00
Rasmus Wriedt Larsen
42de872bfa Python: Add INTERNAL annotation to Response::InstanceSource
Since we need to reserve the flexibility to change this setup within the next
few months, we don't want to commit to keeping this extension point around for
the 12 months that the normal API deprecation cycle requires.
2021-02-23 15:10:58 +01:00
Rasmus Wriedt Larsen
8ebedf26d2 Python: Add comment for MethodView being known subclass 2021-02-23 15:08:07 +01:00
Anders Schack-Mulligen
b1bed2731d Merge pull request #5172 from smowton/smowton/feature/commons-strbuilder
Java: Add support for commons-lang's StrBuilder class
2021-02-23 14:39:11 +01:00
Asger Feldthaus
c58947d3e6 JS: Refactor Vue::Instance to lead to better join orders 2021-02-23 13:13:59 +00:00
Tom Hvitved
bed66203c1 C#: Use shared SSA implementation for BaseSsa 2021-02-23 14:06:27 +01:00
Tom Hvitved
b0ee508f10 C#: Use shared SSA implementation for PreSsa 2021-02-23 14:06:27 +01:00
Tom Hvitved
d8792f2f7f C#: Fix bug in BaseSSA::reachesEndOf/3 2021-02-23 14:06:27 +01:00
Taus
53711dc82f Merge pull request #5238 from RasmusWL/no-flow-default-value
Python: Highlight missing flow from default value in functions
2021-02-23 13:27:41 +01:00
CodeQL CI
3f7f963ed5 Merge pull request #5227 from erik-krogh/infTest
Approved by asgerf
2021-02-23 04:03:18 -08:00
Erik Krogh Kristensen
539ef49b11 change join order for SystemCommandExecutors - and use ApiGraphs::getACall 2021-02-23 12:49:25 +01:00
Erik Krogh Kristensen
56405f40b0 change join order for summarizedHigherOrderCall 2021-02-23 12:48:24 +01:00
Erik Krogh Kristensen
b3aa358177 outline callee computation - to avoid many joins on getACall 2021-02-23 12:48:20 +01:00
CodeQL CI
2551aace89 Merge pull request #5236 from asgerf/js/html-invalid-attr-name
Approved by erik-krogh
2021-02-23 02:03:29 -08:00
Erik Krogh Kristensen
aa6cde2fe0 remove magic from inGuard 2021-02-23 10:03:21 +01:00
Erik Krogh Kristensen
69d6df7834 make globalVarRef non recursive 2021-02-23 10:03:17 +01:00
Erik Krogh Kristensen
06091e5312 cache AstNode::getParent 2021-02-23 09:52:58 +01:00
Erik Krogh Kristensen
b4e6f92505 rearange ArrayIndexingStep to avoid #shared predicate 2021-02-23 09:52:50 +01:00
yo-h
6213c20bc3 Merge pull request #5136 from aschackmull/java/csv-models
Java: Add support for framework modelling through csv data.
2021-02-22 19:00:41 -05:00
CodeQL CI
73e7b54bf1 Merge pull request #5214 from tausbn/actions-add-change-note-checker
Approved by adityasharad
2021-02-22 11:24:51 -08:00
Geoffrey White
362c12caea Merge pull request #5217 from MathiasVP/model-bsd-sockets-part-3
C++: Implement models for poll, accept and select
2021-02-22 18:34:59 +00:00
Jonathan Leitschuh
ad99aa2d76 Fix typo in test output 2021-02-22 13:26:51 -05:00
Owen Mansel-Chan
110f4072fd Merge pull request #5222 from owen-mc/update-go-supported-frameworks
Update supported go frameworks
2021-02-22 15:49:54 +00:00
Owen Mansel-Chan
31d6dbb9da Update supported go frameworks 2021-02-22 15:38:56 +00:00
Rasmus Wriedt Larsen
e160c855ad Merge pull request #5233 from yoff/python-for-tuple-iteration
Python: `for`-iteration of tuples
2021-02-22 15:28:13 +01:00
luchua-bc
40df01d2cd Update qldoc and method name 2021-02-22 14:15:41 +00:00
Rasmus Wriedt Larsen
127e778970 Merge pull request #5215 from github/RasmusWL/fix-acronym-style
Style Guide: Fix two-letter acronym
2021-02-22 15:05:26 +01:00
Rasmus Wriedt Larsen
5249b54a9b Python: Highlight missing flow from default value in functions
Although it is becoming non-trivial to get an overview of what tests we have and
don't have, I didn't find any that highlighted this one

I used all 3 variants of parameters, just to be sure :)
2021-02-22 14:52:51 +01:00
CodeQL CI
0a0bdcca4d Merge pull request #5204 from erik-krogh/inGuard
Approved by asgerf
2021-02-22 02:52:11 -08:00
Asger F
b8e1987cad Update javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributes.html
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-02-22 10:08:56 +00:00
Taus Brock-Nannestad
439f9f1d90 Actions: More cleanup
Removes the checkout action, as this is no longer needed, and folds
the `grep` into `jq`.
2021-02-22 11:05:54 +01:00
Asger Feldthaus
e964771e9c JS: Add test 2021-02-22 09:47:21 +00:00
Mathias Vorreiter Pedersen
f908d2f1de C++: Remove hasTaintFlow from poll and select functions. 2021-02-22 08:54:43 +01:00
Taus Brock-Nannestad
4680b25f23 Actions: Remove dependence on external actions 2021-02-21 15:14:33 +01:00
Rasmus Lerchedahl Petersen
d23a8ad016 Python: elide test output 2021-02-21 13:12:54 +01:00
Rasmus Lerchedahl Petersen
46faba69ff Python: Fix for-iteration of tuples 2021-02-21 12:41:16 +01:00
Rasmus Lerchedahl Petersen
0aecf33fe6 Python: test iteration through overflow parameters
These are in a tuple, so the for-step does not fire
2021-02-21 12:33:04 +01:00
luchua-bc
dc799019d0 Add query for Struts and Spring actions 2021-02-20 03:36:21 +00:00
luchua-bc
3d9ac0d094 Add query for enterprise beans 2021-02-20 02:00:42 +00:00
Asger Feldthaus
e9c0f170a1 JS: Restrict names of extracted HTML attributes 2021-02-19 23:28:28 +00:00
Erik Krogh Kristensen
e6009ea8e0 cache getType 2021-02-19 21:25:48 +01:00
Erik Krogh Kristensen
772e78e386 change TypeInference related join-order in module-import predicates 2021-02-19 21:25:44 +01:00
Mathias Vorreiter Pedersen
576a872316 C++: Address review comments. 2021-02-19 20:24:02 +01:00
Mathias Vorreiter Pedersen
f65843a273 Merge pull request #5221 from geoffw0/cwe676
C++: Add CWE-676 tag.
2021-02-19 17:51:54 +01:00
Taus Brock-Nannestad
ca48e57e30 Actions: Peg external actions to specific SHAs 2021-02-19 16:50:08 +01:00
Asger Feldthaus
5264d24f34 JS: Model vue-router 2021-02-19 15:37:24 +00:00
Tamas Vajk
e1b90912de Limit C# codeql analysis to the csharp folder 2021-02-19 16:13:22 +01:00
Geoffrey White
79338052ad C++: Add CWE-676 tag. 2021-02-19 14:55:31 +00:00
Shati Patel
d490bea9a9 Merge pull request #5211 from shati-patel/docs-telemetry
Docs (CodeQL for VS Code): Move info about telemetry into codeql.github.com
2021-02-19 13:59:18 +00:00
Shati Patel
97eb98e9eb Emphasize that telemetry is disabled by default 2021-02-19 13:42:47 +00:00
Mathias Vorreiter Pedersen
fef824c37a C++: Implement models for poll, accept and select. 2021-02-19 14:03:54 +01:00
Taus Brock-Nannestad
6095138acc Actions: Address comments on change note CI check
- Fail the CI check if change note is missing.
- Disregards changes outside of `*/ql/src`.
- Runs the workflow on label changes, and upon moving the PR out of
  draft mode.
- Only fails the CI check if the PR is out of draft.
- Changes label to `no-change-note-required`.
2021-02-19 13:55:35 +01:00
Felicity Chapman
f9ff1f2c9c Remove personal assignment
This is part of the work to revise the process for requesting docs content team reviews on pull requests.
2021-02-19 11:38:15 +00:00
Rasmus Wriedt Larsen
a19da54c9e Python: Exclude flask.request imports as RemoteFlowSource
When I changed the taint modeling in 19b7ea8d85, that obviously also means that
some of the related locations for alerts will change. So that's why all the
examples needs to be updated.

Besides this, I had to fix a minor problem with having too many alerts. If
running a query agaisnt code like in the example below, there would be 3 alerts,
2 of them originating from the import.

```
from flask import Flask, request
app = Flask(__name__)
@app.route("/route")
def route():
    SINK(request.args.get['input'])
```

The 2 import sources where:

- ControlFlowNode for ImportMember
- GSSA Variable request

I removed these from being a RemoteFlowSource, as seen in the diff.

I considered restricting `FlaskRequestSource` so it only extends
`DataFlow::CfgNode` (and make the logic a bit simpler), but I wasn't actually
sure if that was safe to do or not... If you know, please let me know :)
2021-02-19 12:22:05 +01:00
Rasmus Wriedt Larsen
9798e60d0f Merge pull request #5203 from tausbn/python-add-typebacktrackers
Python: Add `TypeBackTracker`
2021-02-19 12:02:53 +01:00
Rasmus Wriedt Larsen
6ad3ce19d7 Style Guide: Fix two-letter acronym
The old text was based on what was in the [Dart guideline](https://dart.dev/guides/language/effective-dart/style#do-capitalize-acronyms-and-abbreviations-longer-than-two-letters-like-words) and was not adjusted in the PR when we changed our inspiration to be the [.NET guideline](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions) -- (it was only changed in the examples in our internal discussion)
2021-02-19 11:51:45 +01:00
Anders Schack-Mulligen
9721182523 Merge pull request #5080 from github/RasmusWL/naming-for-acronyms
Update CodeQL Style guide to mention acronyms
2021-02-19 11:38:25 +01:00
Taus Brock-Nannestad
03d3f2c8e8 Actions: Add change note checker 2021-02-19 10:16:50 +01:00
Anders Schack-Mulligen
dae65f687a Merge pull request #5150 from Marcono1234/marcono1234/conditional-expr-branch
Java: Add ConditionalExpr.getBranchExpr(boolean)
2021-02-19 10:12:43 +01:00
Bas van Schaik
8f8b8be1e9 Include @xcorail in code reviews for experimental queries 2021-02-18 18:07:09 +00:00
Rasmus Wriedt Larsen
779a464dad Update ql-style-guide.md to not mention abbreviation
This rule is only really intended for acronyms, and not abbreviations in general (like `Stmt` instead of `Statement`).
2021-02-18 17:54:59 +01:00
Rasmus Wriedt Larsen
12511440fe Update ql-style-guide.md
Replacing the HTTP example with a SSA variable example. I didn't want to keep both, to not bloat this section.
2021-02-18 17:52:24 +01:00
Geoffrey White
c4cca83019 Merge pull request #5196 from MathiasVP/fix-dataflow-regression-const-member-function
C++: Fix missing dataflow "out of" const member functions
2021-02-18 16:43:38 +00:00
Shati Patel
4dd1be5ba1 Polish headings and formatting 2021-02-18 15:45:17 +00:00
Shati Patel
28848ecf32 Link to new article 2021-02-18 15:44:17 +00:00
Erik Krogh Kristensen
814b5577f5 improve join-order for Configuration::barrierGuardBlocksEdge 2021-02-18 16:43:43 +01:00
Erik Krogh Kristensen
33f310b91e use manual recursion in Refinements::inGuard 2021-02-18 16:42:40 +01:00
CodeQL CI
f81860c402 Merge pull request #5200 from erik-krogh/apiJoin
Approved by max-schaefer
2021-02-18 07:40:38 -08:00
CodeQL CI
3062f4160a Merge pull request #5207 from github/RasmusWL/js-backtrack-grammar
Approved by erik-krogh
2021-02-18 07:11:23 -08:00
Rasmus Wriedt Larsen
cc72fc82f0 Merge branch 'main' into flask-clean-models 2021-02-18 16:08:18 +01:00
Rasmus Wriedt Larsen
9a42f2fb26 Python: Add missing QLdoc for FlaskMethodViewClass 2021-02-18 16:07:47 +01:00
Taus Brock-Nannestad
880451f659 Python: Add change note 2021-02-18 15:59:34 +01:00
Chris Smowton
321df82851 Apply review feedback: comment style, bracketing, and use proper MISSING test annotations 2021-02-18 14:56:52 +00:00
Taus
e9cbdc4ad3 Update python/ql/src/semmle/python/dataflow/new/TypeTracker.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-02-18 15:53:15 +01:00
Rasmus Wriedt Larsen
bb2613b02b Python: Flask model now ready to be publicly exposed
With a single call-out for a member-predicate that is only for internal use.
2021-02-18 15:36:30 +01:00
Rasmus Wriedt Larsen
35876f1939 Python: Re-introduce Response::instance() in flask model
We don't actually need it for anything right now, but I have plans for the
future where would need it.

Although it would be nice to have it as an `API::Node`, and we could re-write
implementations so we could provide it in this instance, I'm not convinced we
can do that in general right now.

For example, if <n'th> parameter of a function has to be modeled as belonging to
a certain type, I don't see any way to specify that as an API::Node.

For me, that's ok. Until we _can_ specify things like this as API::Nodes in the
future, I would like to keep things consistent, and use `DataFlow::Node` as the
result type.
2021-02-18 15:22:16 +01:00
Rasmus Wriedt Larsen
141e2665ea Python: Align ViewClass naming with django
Just as part of tyding up
2021-02-18 15:10:21 +01:00
Shati Patel
48ace064cc Copy telemetry doc
No changes except for rst formatting
2021-02-18 14:09:36 +00:00
Rasmus Wriedt Larsen
19b7ea8d85 Python: Align flask taint modeling with rest of code
This was a good time to do this, so we don't have 2 different ways of doing the
same thing.

I needed to do this to figure out if we should expose
`API::moduleImport("flask").getMember("request")` in a helper predicate or
not. I think I ended up using more refenreces to this in the end. Although it's
not unreasonable to let someone do this themselves, I also think it's reasonable
that we provide a helper predicate for this.
2021-02-18 15:04:07 +01:00
Tamás Vajk
f3814c6468 Merge pull request #5144 from tamasvajk/feature/refactor-2
C# Share entity base classes between CIL and source extraction
2021-02-18 13:52:52 +01:00
Tamás Vajk
8e7a823b9a Merge pull request #5083 from raulgarciamsft/master
Adding queries related to the Solorigate campaign
2021-02-18 13:50:45 +01:00
Anders Schack-Mulligen
954e0b9496 Java: Add empty file to test. 2021-02-18 13:10:29 +01:00
Rasmus Wriedt Larsen
ba61099172 Python: flask.make_response as InstanceSource of flask.Response 2021-02-18 12:52:59 +01:00
Rasmus Wriedt Larsen
e3d530dbbc Python: Flask: Remove more type-tracking helper predicates 2021-02-18 12:13:47 +01:00
Rasmus Wriedt Larsen
e4ea5f25dc Python: Flask: Moderize app and blueprint 2021-02-18 12:09:37 +01:00
Rasmus Wriedt Larsen
7de488b987 Python: Flask: Moderize views 2021-02-18 12:05:56 +01:00
Rasmus Wriedt Larsen
ffd3c6b016 JS: Minor grammar cleanup of type back-tracking 2021-02-18 11:31:30 +01:00
Anders Schack-Mulligen
74d35f4f37 Java: Add support for value-preserving steps. 2021-02-18 11:26:15 +01:00
Anders Schack-Mulligen
04eeeda2c9 Java: Add documentation for the final column. 2021-02-18 11:23:49 +01:00
Anders Schack-Mulligen
6f583baa90 Java: More documentation and support for field writes. 2021-02-18 11:18:31 +01:00
CodeQL CI
d94f20ff2f Merge pull request #5194 from RasmusWL/type-tracking-snippets
Approved by tausbn
2021-02-18 02:13:21 -08:00
Mathias Vorreiter Pedersen
88263cb89e Merge pull request #5114 from geoffw0/codeqltestdoc
Documentation: Make our policy for copied example code clear and visible.
2021-02-18 10:43:17 +01:00
Erik Krogh Kristensen
6f384630f1 Apply suggestions from code review
Co-authored-by: Max Schaefer <54907921+max-schaefer@users.noreply.github.com>
2021-02-18 10:36:49 +01:00
Mathias Vorreiter Pedersen
3082d70345 Merge branch 'main' into fix-dataflow-regression-const-member-function 2021-02-18 09:34:51 +01:00
luchua-bc
e916ce8b9b Exclude test directories of typical build tools 2021-02-18 00:50:38 +00:00
Taus Brock-Nannestad
23e9785efd Python: Add missing QLDoc 2021-02-17 21:38:48 +01:00
Erik Krogh Kristensen
f4e6f49ae7 change join order for API::Impl::trackDefNode 2021-02-17 21:23:11 +01:00
Erik Krogh Kristensen
dcef6cb974 change join order for API::InvokeNode::getParameter 2021-02-17 21:23:11 +01:00
Erik Krogh Kristensen
c80365c48a change join order for API::Impl::useStep 2021-02-17 21:23:11 +01:00
Taus Brock-Nannestad
99f3a61f61 Python: Add TypeBackTracker
This is a fairly straight port of the JS equivalent. Also adds
`Node::getALocalSourceNode` which seems like it might come in handy.
2021-02-17 21:14:20 +01:00
CodeQL CI
8716cbd7ee Merge pull request #5140 from erik-krogh/mark
Approved by asgerf
2021-02-17 11:50:11 -08:00
Raul Garcia (MSFT)
cba9f421ad Changes to the Readme file 2021-02-17 10:05:22 -08:00
luchua-bc
5e36eedcb6 Add check for test packages 2021-02-17 18:04:55 +00:00
Erik Krogh Kristensen
4df85b44de Update javascript/change-notes/2021-02-10-markdown.md
Co-authored-by: Asger F <asgerf@github.com>
2021-02-17 18:30:31 +01:00
Cornelius Riemenschneider
ebcecca9f1 Merge pull request #5157 from geoffw0/modelsbsl2
C++: Improve Iterator models
2021-02-17 18:04:07 +01:00
Jonathan Leitschuh
c43765917f Fix formatting of MavenPom.qll 2021-02-17 11:55:10 -05:00
CodeQL CI
a81592dbd1 Merge pull request #5111 from asgerf/js/angular-framework-note
Approved by erik-krogh
2021-02-17 08:48:00 -08:00
Taus
593a96ffbb Merge pull request #5182 from RasmusWL/update-supported-python-frameworks-docs
Docs: Update list of support frameworks in Python
2021-02-17 17:44:18 +01:00
CodeQL CI
3e1d2c3f81 Merge pull request #5198 from RasmusWL/revert-structure-change
Approved by tausbn
2021-02-17 08:36:04 -08:00
Rasmus Wriedt Larsen
4880350420 Python: Add a single missing QLDoc 2021-02-17 16:33:12 +01:00
Rasmus Wriedt Larsen
7afe3972d8 Revert "Merge pull request #5171 from RasmusWL/restructure-queries"
This reverts commit 8caafb3710, reversing
changes made to ec79094957.
2021-02-17 16:32:53 +01:00
Erik Krogh Kristensen
bc4ff813f3 Merge pull request #5193 from erik-krogh/aceLog
JS: avoid cartesian product in isFilteredPropertyName
2021-02-17 16:27:33 +01:00
Rasmus Wriedt Larsen
63a09fccdd Python: Use this = <...>.getACall() for DataFlow::CallCfgNode
I think this reads a bit cleaner
2021-02-17 14:43:48 +01:00
Mathias Vorreiter Pedersen
908f24d23f C++: Fix missing AST flow. 2021-02-17 14:33:58 +01:00
Anders Schack-Mulligen
862c41632e Java: Add empty file to test. 2021-02-17 13:23:18 +01:00
Taus
ce1d8ded22 Merge pull request #5192 from RasmusWL/framework-for-routed-params
Python: Expose framework identifier for route-setup and request handler
2021-02-17 13:19:43 +01:00
Rasmus Wriedt Larsen
0cdb5c48cf Python: Remove type-tracking snippets for framework modeling
We won't need these anymore, since we can now use API graphs
2021-02-17 13:14:23 +01:00
Rasmus Wriedt Larsen
a4de88d39c Python: Update type-tracking snippet
based on what I learned in https://github.com/github/codeql/pull/5184
2021-02-17 13:13:25 +01:00
Erik Krogh Kristensen
a03507a544 avoid cartesian product in isFilteredPropertyName 2021-02-17 13:12:35 +01:00
Mathias Vorreiter Pedersen
e0dca2be20 Merge pull request #5185 from MathiasVP/block-integral-types-in-cgixss-query
C++: Add isBarrier to cpp/cgi-xss
2021-02-17 12:44:45 +01:00
Rasmus Wriedt Larsen
eee49cde85 Merge pull request #5184 from tausbn/python-move-type-tracker-tests-to-source-nodes
Python: Use `LocalSourceNode` in type tracker tests
2021-02-17 12:13:47 +01:00
Taus
8caafb3710 Merge pull request #5171 from RasmusWL/restructure-queries
Python: Restructure query file layout
2021-02-17 12:09:32 +01:00
Geoffrey White
ec79094957 Merge pull request #5191 from MathiasVP/regression-test-const-member-function
C++: Add test for missing flow due to const specifier
2021-02-17 10:59:20 +00:00
Mathias Vorreiter Pedersen
25beadcb05 Update cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/search.c
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-02-17 11:54:24 +01:00
Geoffrey White
c07a60818c C++: Simplify IteratorAssignArithmeticOperator. 2021-02-17 10:49:28 +00:00
Mathias Vorreiter Pedersen
e1c4406fd4 Merge pull request #5187 from geoffw0/modelsbsl5
C++: Support BSL in Allocation.qll, Deallocation.qll.
2021-02-17 11:48:53 +01:00
Mathias Vorreiter Pedersen
6db75df943 Merge pull request #5186 from geoffw0/modelsbsl4
C++: More models work
2021-02-17 11:46:23 +01:00
Rasmus Wriedt Larsen
cf9ad0cdc5 Python: Move ExternalAPI queries back under Security
This was raised as a question at review, and I don't really have a good enough
argument for moving it under POI. At the end of the day, they are _security_
related enough I guess :)
2021-02-17 11:29:33 +01:00
Rasmus Wriedt Larsen
dec026a820 Python: Fix security qlref to have single empty line 2021-02-17 11:26:02 +01:00
Rasmus Wriedt Larsen
1adb510578 Python: Add a single missing QLDoc 2021-02-17 11:24:11 +01:00
Mathias Vorreiter Pedersen
1b148c4c90 C++: Add reduced testcase demonstrating the problem in codeql-c-analysis-team/issues/231. 2021-02-17 11:20:00 +01:00
Rasmus Wriedt Larsen
2927d888cf Python: Fix location of PathInjection tests 2021-02-17 11:20:00 +01:00
Mathias Vorreiter Pedersen
f5d5460dde C++: Fix testcase. 2021-02-17 10:53:31 +01:00
Chris Smowton
c700d004e0 Commons Lang/Text StrBuilder: propagate taint from constructors 2021-02-17 09:51:28 +00:00
Chris Smowton
c243e03133 Lang3 StrBuilder: fix typo and coding style 2021-02-17 09:50:56 +00:00
Erik Krogh Kristensen
408ac2729d Merge pull request #5066 from CaptainFreak/express-hbs-lfr
JS: add query for Express-HBS LFR
2021-02-17 10:41:38 +01:00
Chris Smowton
10112c50ab Add support for StrBuilder and TextStringBuilder in commons-text
These are identical to the current deprecated StrBuilder in commons-lang3.
2021-02-17 09:36:28 +00:00
Chris Smowton
714611f803 Address review feedback 2021-02-17 09:36:21 +00:00
Chris Smowton
a63f18e49d Add models for Commons-Lang's StrBuilder class. These exclude its fluent methods for the time being, which will be added in a forthcoming PR. 2021-02-17 09:36:20 +00:00
Anders Schack-Mulligen
5188ad1444 Merge pull request #5126 from smowton/smowton/feature/commons-stringutils
Java: Add support for Apache Commons Lang StringUtils
2021-02-17 09:48:22 +01:00
Rasmus Wriedt Larsen
d98aae9fc1 Python: Expose framework identifier for route-setup and req handler
This makes collecting metrics on framework coverage a bit simpler (specifically
giving the RoutedParameter class a more descriptive result for getSourceType).

I guess it can also help a bit when trying to get an overview of a new DB, but
making metrics collection easier is my main motivation for this.
2021-02-16 23:44:03 +01:00
Geoffrey White
3323683ab2 C++: Support BSL in Allocation.qll, Deallocation.qll. 2021-02-16 19:19:06 +00:00
Sauyon Lee
8db234f5f3 Merge pull request #5092 from github/sauyon-patch-1
Add GoKit to Go supported library list
2021-02-16 11:04:43 -08:00
Geoffrey White
d068ede65b Merge pull request #5180 from criemen/bsl-stdcontainer
C++: Refactor StdContainer.qll.
2021-02-16 18:53:08 +00:00
Geoffrey White
58230d6d0a C++: Model BSL in Fread.qll. 2021-02-16 18:00:51 +00:00
Mathias Vorreiter Pedersen
fa44cedd38 C++: Add isBarrier to CgiXss.ql. 2021-02-16 18:58:28 +01:00
Geoffrey White
e17d539883 C++: Model BSL in Getenv.qll. 2021-02-16 17:56:48 +00:00
Taus
36be72972d Merge pull request #2663 from tausbn/python-type-annotation-reuse-fp
Python: Add false positive test example for issue #2652.
2021-02-16 18:46:15 +01:00
Taus Brock-Nannestad
04eb0c774c Python: Use LocalSourceNode in type tracker tests
One minor change to the tests results needed: there is no longer local
flow going into the `ModuleVariableNode` for `attr_ref` in the
`moduleattr.ql` test, but I think this is reasonable.
2021-02-16 18:25:54 +01:00
Geoffrey White
735e014b43 C++: Model BSL in Gets.qll. 2021-02-16 17:22:59 +00:00
Cornelius Riemenschneider
f7f8dd49c6 Merge pull request #5156 from geoffw0/modelsbsl
C++: Improve StdSet and StdPair models
2021-02-16 18:00:23 +01:00
Cornelius Riemenschneider
3fb42194a5 Apply suggestions from code review
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-02-16 17:58:45 +01:00
Geoffrey White
92df1f7a3d Merge pull request #5165 from criemen/bsl-model-identity
C++: Refactor IdentityFunction.qll.
2021-02-16 16:32:57 +00:00
Taus
9499edf761 Merge pull request #5078 from RasmusWL/flask-blueprints
Python: Add modeling of Flask blueprints
2021-02-16 17:22:13 +01:00
Geoffrey White
c32e54e902 Merge pull request #5176 from criemen/bsl-smartptr
BSL support for smart pointers and other std classes.
2021-02-16 16:21:50 +00:00
Jonathan Leitschuh
a8167c6c9c Add docstring for DeclaredRepository.getUrl 2021-02-16 11:21:19 -05:00
Cornelius Riemenschneider
173b16ae21 Merge pull request #5169 from criemen/bsl-pure
C++: Model bsl functions in Pure.qll.
2021-02-16 17:19:11 +01:00
Cornelius Riemenschneider
80eaf0b67a Merge pull request #5174 from criemen/bsl-str
Model bsl functions in Str*.qll
2021-02-16 17:18:40 +01:00
Cornelius Riemenschneider
f087ff3e49 Merge pull request #5167 from criemen/bsl-memset
C++: Refactor Mem*.qll and include bsl model.
2021-02-16 17:18:29 +01:00
Cornelius Riemenschneider
a04883cafc C++: Fix compilation. 2021-02-16 16:17:59 +00:00
Cornelius Riemenschneider
552f0a7c5e C++: Address review. 2021-02-16 15:55:41 +00:00
Chris Smowton
a2eeffa9c0 Add support for Apache Commons Lang StringUtils 2021-02-16 14:48:39 +00:00
Chris Smowton
bf03c0f419 Port InlineExpectationsTest for the Java analysis 2021-02-16 14:48:39 +00:00
Rasmus Wriedt Larsen
bc8e61366b Python: Clarify comment about flask blueprint URL prefixes 2021-02-16 15:29:25 +01:00
Rasmus Wriedt Larsen
1e1cb87436 Python: Model flask blueprints 2021-02-16 15:26:51 +01:00
Rasmus Wriedt Larsen
b7ea469e26 Python: Add tests for flask blueprints 2021-02-16 15:03:00 +01:00
Rasmus Wriedt Larsen
bf401c7498 Merge pull request #5103 from tausbn/python-port-flask-to-api-graphs
Python: Port Flask models to use API graphs
2021-02-16 15:00:46 +01:00
Rasmus Wriedt Larsen
4b9e37f62d Docs: Update list of support frameworks in Python
So it follows what is we actually support with 6eafa9d396/python/ql/src/semmle/python/Frameworks.qll
2021-02-16 14:37:11 +01:00
Rasmus Wriedt Larsen
8494fcf45f Python: Move query tests to reflect new file layout 2021-02-16 13:15:01 +01:00
Anders Schack-Mulligen
6eafa9d396 Merge pull request #5133 from pwntester/fix_SnakeYaml
Remove sanitizing condition which does not prevent vulnerability.
2021-02-16 12:58:47 +01:00
Cornelius Riemenschneider
434a5f04ed Merge branch 'bsl-memcpy' into bsl-memset 2021-02-16 11:56:40 +00:00
Cornelius Riemenschneider
3f17171f13 C++: Address review. 2021-02-16 11:55:03 +00:00
Cornelius Riemenschneider
30659f3ecf C++: Address review. 2021-02-16 11:54:21 +00:00
Cornelius Riemenschneider
a42700f09e C++: Address review. 2021-02-16 11:52:39 +00:00
Cornelius Riemenschneider
5dc57e9cc2 C++: Address review. 2021-02-16 11:49:44 +00:00
Cornelius Riemenschneider
b25f1fd44a C++: Address review. 2021-02-16 11:37:43 +00:00
Geoffrey White
b309b711ab Merge pull request #5173 from criemen/bsl-swap
C++: Model bsl functions in Swap.qll.
2021-02-16 11:20:41 +00:00
Cornelius Riemenschneider
86268d49ed C++: Refactor StdContainer.qll. 2021-02-16 11:10:57 +00:00
Rasmus Wriedt Larsen
1d6f9bee08 Python: Update qlrefs 2021-02-16 11:48:36 +01:00
Rasmus Wriedt Larsen
3a18881660 Python: Restructure query file location
Since I can never remember the CWE numbers
2021-02-16 11:36:10 +01:00
Geoffrey White
04f15ad43a C++: BSL support in StdPairConstructor. 2021-02-16 09:49:09 +00:00
Tamas Vajk
a75b952333 Fix Type.GetQualifiedName() 2021-02-16 09:13:13 +01:00
Tamas Vajk
199e937e9e C#: Rename CachedEntity.symbol to Symbol 2021-02-16 09:13:12 +01:00
Tamas Vajk
67289a498f Share entity base classes between CIL and source extraction 2021-02-16 09:10:24 +01:00
Tamas Vajk
e7853cc3a0 Simplify TypeContainer class 2021-02-16 09:10:24 +01:00
Tamas Vajk
67caf3cad0 Remove redundant IEntity implemented interface declaration and explit interface member implemenration 2021-02-16 09:10:24 +01:00
Tamas Vajk
61e952766c Convert CIL.GenericContext to interface 2021-02-16 09:10:24 +01:00
Tamas Vajk
3e2a6fca21 C#: Simplify CIL.GenericContext contract 2021-02-16 09:10:24 +01:00
Tamás Vajk
1c2b9f9a82 Merge pull request #4669 from tamasvajk/feature/csharp9-global-stmt
C#: Extract global statements
2021-02-16 09:07:48 +01:00
Tamas Vajk
9c2ca93986 Use 'Declaration::hasQualifiedName/2' in 'MainMethod' 2021-02-15 21:38:02 +01:00
Tamas Vajk
9bb501c595 Fix failing tests 2021-02-15 21:30:56 +01:00
Mathias Vorreiter Pedersen
eb8309a17d Merge pull request #5175 from github/igfoo/thethe 2021-02-15 18:09:32 +01:00
luchua-bc
2f17943abc Update qldoc 2021-02-15 16:58:09 +00:00
Tamas Vajk
4967664d09 Rework global statement extraction without DB scheme change 2021-02-15 17:47:33 +01:00
Tamas Vajk
a14db7a04f Fix code review findings 2021-02-15 17:47:33 +01:00
Tamas Vajk
423fee3069 Fix argument location of top level statement entry point 2021-02-15 17:47:32 +01:00
Tamas Vajk
b79d5ab44b Fix labeled stmt factory method parameter types 2021-02-15 17:44:44 +01:00
Tamas Vajk
6a4b54ec89 C#: Extract global statements 2021-02-15 17:44:44 +01:00
Cornelius Riemenschneider
4a07912006 C++: Small code improvement. 2021-02-15 16:36:49 +00:00
Cornelius Riemenschneider
595bb025f9 C++: Model bsl functions in StdMap.qll. 2021-02-15 16:34:07 +00:00
Tamas Vajk
8c4563b7e3 Code quality improvements 2021-02-15 17:27:33 +01:00
Marcono1234
9e2812cbd5 Sync ConditionalExpr changes with csharp 2021-02-15 17:24:56 +01:00
Tamás Vajk
d1fe542280 Merge pull request #5131 from tamasvajk/feature/refactor
C# Cleanup and refactoring
2021-02-15 17:24:25 +01:00
Cornelius Riemenschneider
b6b90b59eb C++: Model bsl functions in SmartPointer.qll. 2021-02-15 16:22:52 +00:00
Cornelius Riemenschneider
d9c6f7bc35 C++: Model bsl functions in Scanf.qll. 2021-02-15 16:12:46 +00:00
Cornelius Riemenschneider
b670e5b04b C++: Model bsl functions in Printf.qll. 2021-02-15 16:12:35 +00:00
Ian Lynagh
ba6e6337f3 C++: Fix TopLevelFunction's qldoc 2021-02-15 16:08:03 +00:00
Cornelius Riemenschneider
fd2e0292c3 C++: Model bsl functions in Strtok.qll. 2021-02-15 16:00:37 +00:00
Tom Hvitved
bb95b8a0cc Merge pull request #5120 from rvermeulen/rvermeulen/redirect-sink
C#: Add Asp.Net Core redirect sinks
2021-02-15 16:52:32 +01:00
Jonathan Leitschuh
d82e8216ed Merge branch 'main' into feat/JLL/depricated_bintray_usage 2021-02-15 10:48:28 -05:00
Cornelius Riemenschneider
fd91a972a5 C++: Model bsl functions in Strcpy.qll. 2021-02-15 15:43:31 +00:00
Cornelius Riemenschneider
9d19752d9a C++: Model bsl functions in Strcat.qll. 2021-02-15 15:42:34 +00:00
Cornelius Riemenschneider
3afe934a05 C++: Model bsl functions in Swap.qll. 2021-02-15 15:40:17 +00:00
Cornelius Riemenschneider
28d5ef919c Merge pull request #5158 from geoffw0/modelsbsl3
C++: StdString BSL support
2021-02-15 16:32:30 +01:00
Jonathan Leitschuh
73fba3a3c0 Apply suggestions from code review
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2021-02-15 10:01:03 -05:00
Tamas Vajk
f878453f14 Fix performance issue with RecordCloneCallable 2021-02-15 15:49:06 +01:00
Anders Schack-Mulligen
8f5fe14e52 Merge pull request #5170 from pwntester/ArrayUtils_changeNote
add change note for new ArrayUtils support
2021-02-15 15:00:15 +01:00
Alvaro Muñoz
3d3f4ba797 add change note 2021-02-15 14:53:16 +01:00
Alvaro Muñoz
923e1c5e9b add change note for new ArrayUtils support 2021-02-15 14:41:18 +01:00
Rasmus Wriedt Larsen
1961ec6e8d Merge pull request #5159 from tausbn/python-unknown-argument-in-format-string-fp
Python: Add FP test for unknown argument in string format
2021-02-15 14:39:10 +01:00
Rasmus Wriedt Larsen
69e081e897 Python: Apply code-review suggestion
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2021-02-15 14:38:20 +01:00
Taus
2ca12aa612 Update python/ql/src/semmle/python/dataflow/new/internal/DataFlowPublic.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-02-15 14:21:12 +01:00
Taus Brock-Nannestad
27c479a8ba Python: Limit RequestInputAccess to immediate uses
This fixes some spurious results that occurred when we considered
_any_ use of `request.something` to be a source, even ones we had
tracked into other functions. To prevent this, using
`getAnImmediateUse` better captures the fact that we want the source
to be just the actual attribute access.
2021-02-15 13:51:29 +01:00
Anders Schack-Mulligen
b9a479dd31 Merge pull request #5134 from pwntester/ArrayUtils
Add support for Apache Commons Lang ArrayUtils
2021-02-15 13:50:01 +01:00
Mathias Vorreiter Pedersen
1c91d3dbe0 Merge pull request #5168 from MathiasVP/model-bsd-sockets-part-2
C++: Model vector versions of BSD-style reads and writes.
2021-02-15 13:39:08 +01:00
Cornelius Riemenschneider
c9af97b742 C++: Model bsl functions in Pure.qll. 2021-02-15 12:31:16 +00:00
CodeQL CI
b5143dbdb4 Merge pull request #5117 from erik-krogh/parseForm
Approved by asgerf
2021-02-15 04:30:59 -08:00
Cornelius Riemenschneider
79e3bf80c3 C++: Simplify code. 2021-02-15 12:13:25 +00:00
Cornelius Riemenschneider
da38377e36 C++: Simplify code. 2021-02-15 12:12:29 +00:00
Cornelius Riemenschneider
2a3d20d9a9 C++: Refactor Memset.qll and include bsl model. 2021-02-15 12:36:18 +01:00
Erik Krogh Kristensen
74ce7369f8 Update javascript/change-notes/2021-02-09-form-parsers.md
Co-authored-by: Asger F <asgerf@github.com>
2021-02-15 12:35:16 +01:00
Cornelius Riemenschneider
a9071a62a0 C++: Refactor Memcpy.qll and include bsl model. 2021-02-15 12:15:17 +01:00
Mathias Vorreiter Pedersen
0f9b044814 C++: Model vector versions of BSD-style reads and writes. 2021-02-15 12:04:51 +01:00
Erik Krogh Kristensen
e5db0ef16b remove the RequestExpr requirement from FormParsers.qll, and use API graphs. 2021-02-15 11:58:26 +01:00
Cornelius Riemenschneider
f79b3144e3 C++: Refactor IdentityFunction.qll. 2021-02-15 11:31:31 +01:00
CodeQL CI
9b8d94d76e Merge pull request #5148 from erik-krogh/apollo
Approved by esbena
2021-02-15 02:23:52 -08:00
Alvaro Muñoz
00a0b12dad update expected results 2021-02-15 11:23:40 +01:00
Alvaro Muñoz
812884341b Merge branch 'ArrayUtils' of github.com:pwntester/codeql-1 into ArrayUtils 2021-02-15 10:59:49 +01:00
Alvaro Muñoz
504d119749 adjust max parameter number 2021-02-15 10:58:17 +01:00
Rasmus Wriedt Larsen
745148474a Python: Model get_redirect_url in django 2021-02-15 10:55:52 +01:00
Rasmus Wriedt Larsen
6934d5e642 Python: Add django test of RedirectView subclass 2021-02-15 10:55:51 +01:00
Rasmus Wriedt Larsen
79855157b3 Python: Move django response test to django v2/v3
That's really the django version I care about :P
2021-02-15 10:55:50 +01:00
Alvaro Muñoz
c7072aef16 update A.java test 2021-02-15 10:34:20 +01:00
Jonas Jensen
f0ce524c0d Merge pull request #5147 from MathiasVP/model-bsd-sockets-part-1
C++: Add models for BSD-style send and recv functions
2021-02-15 10:34:11 +01:00
Tamas Vajk
2de7fbe062 Fix build after rebase 2021-02-15 10:18:12 +01:00
Tamas Vajk
6cc858b9ef Move AstLineCounter to top level class 2021-02-15 10:17:08 +01:00
Tamas Vajk
4f693be33b Move location creation to instance method on context 2021-02-15 10:17:08 +01:00
Tamas Vajk
6f07230725 Relocate 'AstLineCounter' 2021-02-15 10:17:07 +01:00
Tamas Vajk
1cd7fd6cf7 Simplify 'AstLineCounter' 2021-02-15 10:17:07 +01:00
Tamas Vajk
e8fd6e1112 Move classes to seperate files 2021-02-15 10:17:07 +01:00
Tamas Vajk
5ce5a96cb6 Remove 'ContextExtensions' 2021-02-15 10:17:07 +01:00
Tamas Vajk
9ddeff80bf Remove useless 'IExtractor' interface 2021-02-15 10:17:07 +01:00
Tamas Vajk
6cdec2d30e C#: Remove 'extractor.CreateContext' factory method 2021-02-15 10:17:07 +01:00
Tamas Vajk
fc3e6526ce C#: Remove IExtractionScope.FromSource 2021-02-15 10:17:07 +01:00
Tamas Vajk
a75306acbd C#: Remove warnings from MdProvider 2021-02-15 10:17:07 +01:00
Tamas Vajk
1a4f370d15 C#: Fix formatting issues 2021-02-15 10:17:07 +01:00
Anders Schack-Mulligen
7e83a608a2 Merge pull request #4954 from aschackmull/java/member-hasqualifiedname
Java: Add Member.hasQualifiedName.
2021-02-15 10:02:13 +01:00
Erik Krogh Kristensen
91f277681a fix typo in ApolloClientRequest
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-02-15 09:59:04 +01:00
Anders Schack-Mulligen
161e756c4b Merge pull request #5141 from github/yo-h/java-flow-check-fix
Java: prepare to enforce additional compiler checks in test code
2021-02-15 09:41:03 +01:00
yo-h
1d007b6e72 Java: delete two test cases as per code review 2021-02-14 21:42:58 -05:00
Rasmus Wriedt Larsen
2478a9f10e Python: Fix wording of change-note 2021-02-14 23:20:46 +01:00
CodeQL CI
178c54e69b Merge pull request #5139 from RasmusWL/django-improvements
Approved by yoff
2021-02-14 02:16:52 -08:00
Tamas Vajk
4cc9bc9bf0 Add new .stats file 2021-02-13 16:21:45 +01:00
Raul Garcia (MSFT)
782f4bc3e2 Fixing shared .qhelp issue (renaming to .qhelp.inc)& addressing a fix 2021-02-12 13:38:55 -08:00
Marcono1234
7a6db061b5 Address review feedback 2021-02-12 20:15:10 +01:00
Tamas Vajk
cb9116028c Add change note for 'with' expression extraction 2021-02-12 20:04:22 +01:00
Tamas Vajk
10e99203e8 Add DB upgrade folder for 'with' expression 2021-02-12 19:59:14 +01:00
Tamas Vajk
7761774f88 Add record .ctor to property data flow summary 2021-02-12 19:54:52 +01:00
Tom Hvitved
6a6644b5c2 C#: Adjust data-flow for with expressions
In `x with { Foo = bar }`, instead of having a single data-flow step

`x => x with { Foo = bar }`

we now have two steps:

`x => { Foo = bar }`

and

`{ Foo = bar } => x with { Foo = bar }`

Moreover, `clearsContent` now targets the object initializer instead of the
whole `with` expression, which means that it will only apply to values carried
over from the old object and not those explicitly stored into the new object.
2021-02-12 19:54:52 +01:00
Tamas Vajk
dd9b1d52b5 C#: Initial data-flow for with expressions 2021-02-12 19:54:52 +01:00
Tamas Vajk
b2b4c9ecd6 C#: Extract 'with' expressions 2021-02-12 19:54:52 +01:00
Tamás Vajk
77af7edaa4 Merge pull request #4628 from tamasvajk/feature/csharp9-foreach
C#: Extract underlying methods of foreach statements
2021-02-12 19:53:26 +01:00
Taus Brock-Nannestad
2632422783 Python: Add FP test for unknown argument in string format
Reported in https://github.com/github/codeql/issues/2650

I found this during a bit of spring cleaning in my working
directory. As this doesn't have any immediate security implications, I
don't know when we'll get round to fixing it, but it can't hurt to
have the test case checked in.
2021-02-12 19:28:12 +01:00
Erik Krogh Kristensen
4fa33b151f Merge pull request #5146 from github/more-redos-tests
JS: add two non ReDoS regular expressions to the ReDoS test suite
2021-02-12 18:56:52 +01:00
Geoffrey White
6d452521f7 C++: Move StdBasicStringStream to a more logical location. 2021-02-12 17:42:33 +00:00
Geoffrey White
74f05d569b C++: BSL support. 2021-02-12 17:41:32 +00:00
CodeQL CI
179a7a89dd Merge pull request #5098 from erik-krogh/xml2js
Approved by asgerf
2021-02-12 09:22:40 -08:00
Chris Smowton
402f20c5e2 Merge pull request #5154 from smowton/smowton/admin/deprecate-old-maven-predicate-names
Java: Re-introduce deprecated versions of old Maven predicate names
2021-02-12 17:22:05 +00:00
Chris Smowton
80978c7c35 Merge pull request #5153 from smowton/smowton/admin/move-misplaced-experimental-query
Move misplaced experimental query into the conventional directory
2021-02-12 17:21:57 +00:00
Geoffrey White
d362b5aa65 C++: StdSet should be private as well. 2021-02-12 16:29:44 +00:00
Geoffrey White
df91b8182c C++: Deprecate StdPairClass properly. 2021-02-12 16:24:45 +00:00
Geoffrey White
1edfd04598 C++: BSL Support. 2021-02-12 15:56:47 +00:00
Geoffrey White
3cfb0a21fe C++: Fix Iterator.qll taint/data flows for operator+=. 2021-02-12 14:54:47 +00:00
Geoffrey White
61b0d6a0cd C++: Fix Iterator.qll non-member operator+= charpred. 2021-02-12 14:54:46 +00:00
Geoffrey White
da06b2a615 C++: Improve Iterator.qll layout and QLDoc. 2021-02-12 14:54:46 +00:00
Geoffrey White
90dbbbb0c2 C++: Update Iterator.qll. 2021-02-12 14:54:46 +00:00
Geoffrey White
7705fc4f98 C++: Add more test cases for iterator taint flow. 2021-02-12 14:54:45 +00:00
Alvaro Muñoz
7d294361dc Update java/ql/src/semmle/code/java/frameworks/apache/Lang.qll
Co-authored-by: Joe Farebrother <joefarebrother@github.com>
2021-02-12 15:40:44 +01:00
Alvaro Muñoz
6b80a42913 apply LSP formatter and add missing dot 2021-02-12 15:03:11 +01:00
Alvaro Muñoz
8606386c2c add bidirectional import 2021-02-12 14:59:28 +01:00
Alvaro Muñoz
49eda8ced6 apply LSP formatter 2021-02-12 14:56:10 +01:00
Anders Schack-Mulligen
085286ab58 Merge pull request #5135 from pwntester/guava_preconditions
Add support for the Preconditions Class in the Guava framework
2021-02-12 14:15:17 +01:00
Chris Smowton
655cfb3a47 Re-introduce deprecated versions of old Maven predicate names 2021-02-12 12:24:19 +00:00
Chris Smowton
97df60f9d6 Move misplaced experimental query into the conventional directory 2021-02-12 12:12:16 +00:00
Chris Smowton
942ae7ef47 Merge pull request #5142 from Marcono1234/marcono1234/maven-pom-improvements
Java: Improve MavenPom documentation, rename inconsistent predicates
2021-02-12 11:52:19 +00:00
Rasmus Wriedt Larsen
10fdc4bfb9 Python: Add support for more yaml loading functions 2021-02-12 12:30:00 +01:00
Rasmus Wriedt Larsen
2021cdbe33 Python: Add tests for more yaml loading functions 2021-02-12 12:30:00 +01:00
Rasmus Wriedt Larsen
f328e84bd2 Python: Mention yaml.safe_load in the qhelp 2021-02-12 12:29:55 +01:00
Rasmus Wriedt Larsen
1651f81ac8 Python: Refactor to avoid confusing name
After discussion with @yoff
2021-02-12 12:19:37 +01:00
Mathias Vorreiter Pedersen
729c7f2371 C++: Add deprecated alias to RemoteFlowSourceFunction and LocalFlowSourceFunction. 2021-02-12 10:53:34 +01:00
Mathias Vorreiter Pedersen
b1c7cb6396 C++: Address review comments. 2021-02-12 10:37:27 +01:00
Rasmus Wriedt Larsen
ed2dc5f6ad Python: Fix date for change-note 2021-02-12 10:26:31 +01:00
Tamas Vajk
0aded1549e Improve NestedLoopsSameVariable query performance 2021-02-12 09:33:33 +01:00
Marcono1234
905648e452 Add ConditionalExpr.getBranchExpr(boolean) 2021-02-12 04:50:41 +01:00
Marcono1234
e89891fa1f Address review comments 2021-02-12 01:30:47 +01:00
Raul Garcia (MSFT)
710ca21d19 Addressing comments we missed earlier 2021-02-11 11:52:58 -08:00
Geoffrey White
354f21f2c3 C++: BSL support. 2021-02-11 16:57:20 +00:00
Erik Krogh Kristensen
004147a22f add change note 2021-02-11 17:54:53 +01:00
Erik Krogh Kristensen
6f405635ef add ClientRequest model for apollo-client 2021-02-11 17:49:44 +01:00
Mathias Vorreiter Pedersen
91627cbd88 C++: Add models for BSD-style send and recv functions. 2021-02-11 17:21:32 +01:00
Geoffrey White
21b2999722 C++: Update StdSet.qll. 2021-02-11 16:01:55 +00:00
Geoffrey White
33b5802ff6 C++: Update StdPair.qll (just for consistency). 2021-02-11 16:01:44 +00:00
Erik Krogh Kristensen
fd46b7a7bc fix type in change-note
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-02-11 16:17:26 +01:00
Erik Krogh Kristensen
69d8aa143c add taint step for the snarkdown libary 2021-02-11 16:16:46 +01:00
Taus Brock-Nannestad
4c66071f5f Python: Revert "Python: Support moduleImport("dotted.name") in API graphs"
This reverts commit 2c4a477a4e.

It's probably best _not_ to do this, as any `getMember` cycle in the
API graph will lead to nontermination.
2021-02-11 16:08:28 +01:00
Taus Brock-Nannestad
ea30598a08 Python: Split dotted names more efficiently 2021-02-11 16:07:39 +01:00
Jonathan Leitschuh
35e2ceba13 Update java/ql/src/semmle/code/xml/MavenPom.qll
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-02-11 08:59:02 -05:00
Erik Krogh Kristensen
d14586de56 add two non ReDoS regular expressions to the ReDoS test suite
Adds the regular expression from #5145
2021-02-11 14:41:45 +01:00
Erik Krogh Kristensen
f12c38425f add change-note 2021-02-11 13:36:53 +01:00
Erik Krogh Kristensen
3ee0029cd8 Update javascript/change-notes/2021-02-08-xml-parser-taint.md
Co-authored-by: Asger F <asgerf@github.com>
2021-02-11 13:33:42 +01:00
CodeQL CI
02578cfff2 Merge pull request #5112 from erik-krogh/forms
Approved by asgerf
2021-02-11 04:32:14 -08:00
Erik Krogh Kristensen
044f80215e add change note 2021-02-11 09:34:04 +01:00
Erik Krogh Kristensen
010d580f8e add model for multiparty 2021-02-11 09:34:04 +01:00
Erik Krogh Kristensen
61b4ffec3d add remote flow from the Formidable library 2021-02-11 09:34:04 +01:00
Erik Krogh Kristensen
a03f4ed3cd add remote flow source for busboy 2021-02-11 09:34:02 +01:00
Erik Krogh Kristensen
e2fbf8a68c add files uploaded with multer as RemoteFlowSource 2021-02-11 09:33:15 +01:00
Marcono1234
2a1c11b517 Improve MavenPom documentation, rename inconsistent predicates 2021-02-10 23:56:45 +01:00
Raul Garcia (MSFT)
ef0d3720a1 Addressing a few comments 2021-02-10 13:39:24 -08:00
Raul Garcia
190164c182 Update csharp/ql/src/experimental/Security Features/campaign/Solorigate/Solorigate.qhelp
Co-authored-by: Bas van Schaik <5082246+sj@users.noreply.github.com>
2021-02-10 13:30:40 -08:00
Erik Krogh Kristensen
7cff1f441b add model for the unified and remark libraries 2021-02-10 18:13:01 +01:00
Rasmus Wriedt Larsen
c57a4df819 Python: Model taint of self.request on django view class 2021-02-10 17:48:48 +01:00
Rasmus Wriedt Larsen
9ca738d921 Python: Add taint test for self.request on django view class 2021-02-10 17:48:41 +01:00
Jonathan Leitschuh
3b92f97967 Refactor DeclaredRepository to library 2021-02-10 11:41:50 -05:00
Erik Krogh Kristensen
0d497e8b9a add model for the showdown library 2021-02-10 17:22:42 +01:00
Anders Schack-Mulligen
e9bfbb677d Java: Connect the external sources and steps to the defaults. 2021-02-10 17:06:21 +01:00
Anders Schack-Mulligen
5a391ab6c0 Java: Add qldoc. 2021-02-10 16:54:48 +01:00
Jonathan Leitschuh
21b6f35ddc Update java/ql/src/Security/CWE/CWE-1104/MavenPomDependsOnBintray.qhelp 2021-02-10 10:52:27 -05:00
Jonathan Leitschuh
49985a77e3 Apply suggestions from code review
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com>
2021-02-10 10:51:37 -05:00
Rasmus Wriedt Larsen
ca0d345987 Django: Model any class used in django route setup as view class 2021-02-10 16:26:25 +01:00
Rasmus Wriedt Larsen
b428945bc2 Django: Fix DjangoRouteHandler char-pred
Before it the class would contain _all_ functions xD
2021-02-10 16:21:51 +01:00
Rasmus Wriedt Larsen
78a3206fce Python: Add test with unkown view class in django 2021-02-10 15:56:33 +01:00
Anders Schack-Mulligen
b74911204a Merge pull request #4945 from intrigus-lgtm/java/insecure-jxbrowser
Java: Insecure JXBrowser
2021-02-10 15:48:17 +01:00
Rasmus Wriedt Larsen
42eceb80bd Python: Handle view functions with decorators 2021-02-10 15:47:55 +01:00
Erik Krogh Kristensen
f76018c039 add taint step for the markdown-table library 2021-02-10 15:11:41 +01:00
Erik Krogh Kristensen
b4704f7016 add taint-step for the marked library 2021-02-10 14:51:08 +01:00
Erik Krogh Kristensen
91f7d33044 add change note 2021-02-10 14:17:49 +01:00
Erik Krogh Kristensen
101d4358a9 detect DOM nodes from event callbacks 2021-02-10 14:17:49 +01:00
Erik Krogh Kristensen
be9636491b add source for react-hook-form in xss-through-dom 2021-02-10 14:17:49 +01:00
Erik Krogh Kristensen
65d93c9061 detect for DOM elements from DOM events in React 2021-02-10 14:17:49 +01:00
Erik Krogh Kristensen
458dda9d25 add xss-through-dom source from react-final-form 2021-02-10 14:17:49 +01:00
Erik Krogh Kristensen
ff3950ce98 add model for formik 2021-02-10 14:17:49 +01:00
Erik Krogh Kristensen
d1087d4e41 move sources from XssThroughDom into a customizations file 2021-02-10 14:17:49 +01:00
Erik Krogh Kristensen
4969a1ef4f add change note 2021-02-10 14:16:31 +01:00
Erik Krogh Kristensen
0ca2310594 add model for htmlparser2 2021-02-10 14:16:31 +01:00
Erik Krogh Kristensen
e2a66bf3ed add model for xml-js 2021-02-10 14:16:31 +01:00
Erik Krogh Kristensen
73f7cd149f add model for sax 2021-02-10 14:16:31 +01:00
Erik Krogh Kristensen
c43025d7b3 add model for xml2js 2021-02-10 14:16:30 +01:00
Erik Krogh Kristensen
44ca2e26a6 add taint-step to XML parsers 2021-02-10 14:16:08 +01:00
intrigus
5c82ff83de Java: Fix qhelp, fix CWE reference 2021-02-10 13:57:51 +01:00
Anders Schack-Mulligen
3a6fa9d99b Java: Add support for framework modelling through csv data. 2021-02-10 13:25:03 +01:00
Alvaro Muñoz
645b021845 Add support for the Preconditions Class in the Guava framework 2021-02-10 13:20:29 +01:00
Alvaro Muñoz
0cf3a29429 Add support for Apache Commons Lang ArrayUtils 2021-02-10 13:09:57 +01:00
Shati Patel
18225fa254 Merge pull request #4997 from github/shati-patel/cwe-coverage-docs
Docs: Add outline for CWE coverage page
2021-02-10 11:45:09 +00:00
Alvaro Muñoz
3b4357792b Remove sanitizing condition which does not prevent
vulnerability.
2021-02-10 12:21:48 +01:00
Anders Schack-Mulligen
66d0bf6b5e Merge pull request #5128 from hvitved/dataflow/exploration-clears-content
Data flow: Take `clearsContent()` into account in flow exploration
2021-02-10 11:52:24 +01:00
yoff
9930d59aca Merge pull request #5124 from RasmusWL/typetracking-with-decorator
Python: Add test for type-tracking through decorators
2021-02-10 09:34:54 +01:00
Tom Hvitved
1f9b42f9ab Data flow: Sync files 2021-02-09 20:10:23 +01:00
Tom Hvitved
e5970f4c65 Data flow: Take clearsContent() into account in flow exploration 2021-02-09 20:09:24 +01:00
Geoffrey White
d475e55ec0 Update cpp/ql/test/README.md
Co-authored-by: hubwriter <hubwriter@github.com>
2021-02-09 15:20:03 +00:00
Geoffrey White
cc031118dd Update CONTRIBUTING.md
Co-authored-by: hubwriter <hubwriter@github.com>
2021-02-09 15:19:30 +00:00
yo-h
e5331a4735 Java: accept changes in expected output 2021-02-09 09:17:35 -05:00
yo-h
e194411cfa Java: fix javac errors in test code 2021-02-09 09:16:57 -05:00
luchua-bc
cb01613aa6 Exclude FP token patterns 2021-02-09 13:53:23 +00:00
Tamas Vajk
9854b95c30 Fix query performance 2021-02-09 14:45:22 +01:00
Alexander Eyers-Taylor
1c43505d30 Merge pull request #5121 from alexet/fix-js-jdoc
Javascript Extractor: Update <tt> tages to <code>
2021-02-09 13:07:19 +00:00
CodeQL CI
475d216f8e Merge pull request #5087 from erik-krogh/immutable
Approved by asgerf
2021-02-09 12:43:19 +00:00
Rasmus Wriedt Larsen
1d25184b32 Python: Add test for type-tracking through decorators
In general, if there is _some_ decorator on a function, it might not be safe to
track content out of it (since the decorator could do anything), but in this
case, we can see what the decorator does, so we should be able to handle it (but
we don't right now).

By my understanding of how type-tracking works, if we track content through
`my_decorator`, then we would also track content to the result of
`unrelated_func()`, which I wanted to make sure our tests would catch.

I found out the core of the problem seems to come from our lack of being able to
track to the inner scope, and added an explicit test for that.
2021-02-09 13:43:10 +01:00
Rasmus Wriedt Larsen
eb7e30d472 Python: Add test of django view handler with decorator
Which we currently don't handle :(

Also added a bit more explanatory comments
2021-02-09 13:25:12 +01:00
Geoffrey White
d1910a3f5c Update CONTRIBUTING.md
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-02-09 12:12:24 +00:00
alexet
8dd5a7e7c7 Javascript Extractor: Update <tt> tages to <code> 2021-02-09 12:10:09 +00:00
Remco Vermeulen
3818971b79 Add redirect sinks
Both the familiy of `Accepted` and `Created` method set the location
header based on provided input. If this is untrusted input this can
result in an URL redirect attack.
2021-02-09 13:09:02 +01:00
Alexander Eyers-Taylor
bed10ad562 Merge pull request #5113 from github/alexet/fix-var-decls-spec
Update the language specification to allow empty var_decls
2021-02-09 11:08:23 +00:00
CaptainFreak
503b339a1f remove hbs specific checks 2021-02-09 07:35:35 +05:30
Raul Garcia (MSFT)
f114ef1f06 Adding unit tests 2021-02-08 16:57:49 -08:00
Geoffrey White
8bf9fc6111 Consistent capitalisation. 2021-02-08 20:29:46 +00:00
Geoffrey White
07b263bb2f Typo. 2021-02-08 20:27:28 +00:00
Geoffrey White
bd255617d8 Three copies of a link is too much. 2021-02-08 20:25:35 +00:00
Geoffrey White
e1ca762bbc Fix layout. 2021-02-08 20:24:15 +00:00
Geoffrey White
65ea1a4631 Add hints / links about tests and documentation to CONTRIBUTING.md. 2021-02-08 20:04:10 +00:00
Geoffrey White
690b525192 Add a link to the C/C++ CodeQL Tests README.md from the Supported CodeQL queries and libraries doc. 2021-02-08 20:04:10 +00:00
Geoffrey White
74178a5e86 Call out the copied code issue for qhelp files again (more generally) in the Supported CodeQL queries and libraries doc. 2021-02-08 20:04:09 +00:00
Geoffrey White
cb16c64540 Call out the issue of copied code for C/C++ example code in the C/C++ CodeQL Tests README.md (where we talk about it for tests). 2021-02-08 19:58:36 +00:00
Alexander Eyers-Taylor
7583904046 Update the language specification to allow empty var_decls
This is a degenerate form that is accepted in the compiler even if they don't make much sense. 

Fixes #5060
2021-02-08 18:54:13 +00:00
Taus Brock-Nannestad
c59b5c98cb Python: Replace use of AttrNode with getMember 2021-02-08 19:14:11 +01:00
Taus Brock-Nannestad
72a699e099 Python: Add CallCfgNode class and rewrite using that class
I prefer this name to `CfgCallNode` as the latter will make
autocomplete more difficult.
2021-02-08 16:55:18 +01:00
Asger Feldthaus
b278233a94 JS: Mention all versions of Angular are supported 2021-02-08 15:45:46 +00:00
Taus Brock-Nannestad
46eb3fd10a Python: Even more API::Node pushing. 2021-02-08 14:22:42 +01:00
Taus
c0c2aa69b3 Merge branch 'main' into python-port-flask-to-api-graphs 2021-02-08 14:17:25 +01:00
Taus Brock-Nannestad
2c4a477a4e Python: Support moduleImport("dotted.name") in API graphs 2021-02-08 14:08:34 +01:00
Taus
738d1bc3d4 Python: More use of API::Node
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-02-08 14:08:16 +01:00
Tamas Vajk
bd50ed975f Fix doc comment 2021-02-08 11:18:37 +01:00
Erik Krogh Kristensen
504db8739d fix typo in execa change-note file name 2021-02-08 10:00:26 +01:00
Erik Krogh Kristensen
8ca75e41d2 add change note 2021-02-08 09:59:45 +01:00
intrigus
2e30f2d9ce Java: Fix QHelp & accept test output
Accept test output for changed alert message.
2021-02-08 00:05:02 +01:00
Tamas Vajk
ef55ca179b Improve file read exception logging 2021-02-07 09:06:11 +01:00
Tamas Vajk
6d908876e0 Add new .stats file 2021-02-07 09:06:11 +01:00
Tamas Vajk
96248f8845 Add DB upgrade folder 2021-02-07 09:06:11 +01:00
Tamas Vajk
63b0fe10e4 Rework foreach_stmt_info extraction 2021-02-07 09:06:11 +01:00
Tamas Vajk
7c506f445c C#: Extract underlying methods of foreach statements 2021-02-07 09:06:11 +01:00
Raul Garcia (MSFT)
d775528069 Fixes on multiple files. 2021-02-05 14:09:26 -08:00
Taus
d3a79ecff1 Update python/ql/src/semmle/python/frameworks/Flask.qll
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-02-05 22:54:27 +01:00
Jonathan Leitschuh
f00b0baaea Update java/ql/src/Security/CWE/CWE-1104/MavenPomDependsOnBintray.qhelp
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-02-05 16:31:37 -05:00
Taus Brock-Nannestad
3d2548ed28 Python: Get rid of remaining type trackers in Flask model
At this point, we may want to reconsider whether we really want the
deeply-nested module structure we had before (and which made the type
trackers somewhat bearable).

There's also a question of how we can make this a bit more
smooth. I think we need to consider exactly how we would like the
interface to this to work.
2021-02-05 21:58:08 +01:00
Taus Brock-Nannestad
5bfde2c0f2 Python: Fix overly broad class attribute node class
This is not strictly necessary, but it was bothering me that this
simply covered _all_ nodes that were both definitions and names at the
same time. Now it actually encompasses what the documentation claims
it does.
2021-02-05 21:56:57 +01:00
Taus Brock-Nannestad
7f3c6acd08 Python: Handle class attribute references in API graph
This is slightly dubious, and should really be in the currently
unimplemented "def" counterpart to the "use" bits we already have.

However, it seems to work correctly, and in the spirit of moving
things along, this seemed like the easier solution. We can always
replace the implementation with the "proper" approach at a later point.
2021-02-05 21:54:35 +01:00
Jonathan Leitschuh
bfa9324266 CWE-1104: Maven POM dependence upon Bintray/JCenter 2021-02-05 13:05:51 -05:00
Raul Garcia (MSFT)
d48a713f30 Fixing cutom edges predicate 2021-02-05 09:27:08 -08:00
Raul Garcia (MSFT)
681e6a9303 Adding Solorigate context for the generic backdoor queries. 2021-02-05 09:02:59 -08:00
Taus Brock-Nannestad
ef600575ca Python: Add API graph support for subclasses 2021-02-05 16:52:58 +01:00
Taus Brock-Nannestad
b39cbf82c6 Python: Port Flask models to use API graphs
Most of the type trackers in this model were easily replaceable with
uses of the API graph, but the ones for tracking subclasses are
problematic, as these take us out of the API graph.
2021-02-05 14:41:42 +01:00
Shati Patel
6a46be2379 Install sphinx extension for building markdown tables 2021-02-05 12:07:06 +00:00
Shati Patel
5f17fa8366 Docs: Add outline for CWE coverage page 2021-02-05 12:06:57 +00:00
luchua-bc
a183b00166 Query to detect main method in servlets 2021-02-05 03:53:01 +00:00
Raul Garcia (MSFT)
3dc1b81d65 Changing ProcessNameToHash query to path-problem. Any additional feedback will be welcomed 2021-02-04 17:54:35 -08:00
Raul Garcia (MSFT)
9ef4aef28e Changing location for NonCryptographicHash qll
Changing the TimeBomb query to path-problem (any suggestions to improve it would be welcomed, no previous experience iwth path-problem queries)
2021-02-04 16:59:38 -08:00
Raul Garcia (MSFT)
d5c9db42de Fixing format 2021-02-04 14:26:03 -08:00
Raul Garcia (MSFT)
1d8f8286a5 Fixes to address some of the comments during PR 2021-02-04 13:25:43 -08:00
Raul Garcia (MSFT)
8e85145df4 Updated Readme file 2021-02-04 12:51:31 -08:00
Raul Garcia (MSFT)
979fdd2c6a Addressing multiple comments 2021-02-04 10:23:01 -08:00
Sauyon Lee
5927ce5d69 Add GoKit to Go supported library list 2021-02-04 14:43:34 +00:00
Rasmus Wriedt Larsen
1de3524bc5 Update docs/ql-style-guide.md
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-02-04 12:27:38 +01:00
Erik Krogh Kristensen
6cbf7b3267 add of Set, Stack and similar to the Immutable model 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
b74df66463 implement Immutable merge 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
c0de6a3af2 add support for Immutable Record 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
609b16b1f7 implement Immutable OrderedMap 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
2e7bf9b53c implement Immutable lists 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
a5c9492c87 add support for fromJS in the Immutable model 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
6cbe4caecc support toJS() by using plain property names instead of pseudoproperties. 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
b1f092f052 add support for map.set in Immutable model 2021-02-04 12:05:44 +01:00
Erik Krogh Kristensen
b77dd54618 implement basic map get/set for immutable.js 2021-02-04 12:05:44 +01:00
Raul Garcia (MSFT)
53ab787efc Fixed format 2021-02-03 15:54:47 -08:00
Raul Garcia (MSFT)
86a2aa97ec Fixing incorrect file extension & adding suite 2021-02-03 15:48:16 -08:00
Raul Garcia (MSFT)
5e1e27c2b6 Adding queries related to the Solorigate campaign 2021-02-03 15:12:31 -08:00
Rasmus Wriedt Larsen
2453a25833 Update docs/ql-style-guide.md
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-02-03 13:42:08 +01:00
Rasmus Wriedt Larsen
0ea7aa54f9 Update CodeQL Style guide to mention acronyms
Adding this after asking how to do this internally. Is based on https://dart.dev/guides/language/effective-dart/style#do-capitalize-acronyms-and-abbreviations-longer-than-two-letters-like-words
2021-02-03 13:31:26 +01:00
Erik Krogh Kristensen
d016ba2252 rename name dataflow configuration in js/template-object-injection 2021-02-03 12:29:23 +01:00
Erik Krogh Kristensen
a5bde53bfe use the TaintedObject library in js/template-object-injection 2021-02-03 12:26:37 +01:00
Erik Krogh Kristensen
c6a22844e2 add test for js/template-object-injection 2021-02-03 12:16:57 +01:00
CaptainFreak
12ee497485 move query to src, rename and refactor 2021-02-03 15:48:02 +05:30
CaptainFreak
3363f5e6db JS: add query for Express-HBS LFR 2021-02-01 18:01:34 +05:30
intrigus
d3e6e594b2 Java: Improve QLDoc 2021-01-27 11:57:32 +01:00
intrigus
bdba7e14fe Java: Switch to data flow 2021-01-27 11:54:40 +01:00
luchua-bc
fee0b94cd4 Use isRequestGetParamMethod as the source 2021-01-26 04:41:44 +00:00
intrigus
a4cbd7037b Java: Add tests for different versions.
Adds a test for version 6.24, because that version is not vulnerable.
The other test is for versions < 6.24, because these versions are
vulnerable.
2021-01-15 17:20:57 +01:00
intrigus-lgtm
b8076481bf Java: Suggestions from Review 2021-01-13 20:32:23 +01:00
Anders Schack-Mulligen
f3b8fe2e2e Java: Add Member.hasQualifiedName. 2021-01-13 13:42:35 +01:00
intrigus
5b3086a93a Java: Fix capitalization of JxBrowser 2021-01-12 22:43:41 +01:00
intrigus
1ebc9f4d93 Java: Only detect JxBrowser < 6.24 2021-01-12 22:39:08 +01:00
intrigus
b30872806d Java: Add tests and test stubs. 2021-01-12 14:49:12 +01:00
intrigus
9b3070ab7c Java: Add JXBrowser disabled certificate query. 2021-01-12 14:48:22 +01:00
luchua-bc
3d26e5b8a4 Update qldoc 2021-01-06 12:41:00 +00:00
luchua-bc
f1763ae354 Use the sensitive info sink 2021-01-06 01:48:19 +00:00
luchua-bc
367ff99909 Change the source to be the request variable 2021-01-05 17:30:19 +00:00
luchua-bc
195755d687 Revamp the query to be more selective 2021-01-05 00:04:08 +00:00
luchua-bc
496db4b42f Factor isGetServletMethod into the servlet library 2021-01-04 16:14:13 +00:00
luchua-bc
ffe9d4a310 Sensitive GET Query 2020-12-26 16:51:30 +00:00
Taus Brock-Nannestad
ead687da06 Python: Add false positive test example for issue #2652. 2020-01-21 15:28:01 +01:00
819 changed files with 41869 additions and 13624 deletions

21
.github/workflows/check-change-note.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
on:
pull_request_target:
types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review]
paths:
- "*/ql/src/**/*.ql"
- "*/ql/src/**/*.qll"
- "!**/experimental/**"
jobs:
check-change-note:
runs-on: ubuntu-latest
steps:
- name: Fail if no change note found. To fix, either add one, or add the `no-change-note-required` label.
if: |
github.event.pull_request.draft == false &&
!contains(github.event.pull_request.labels.*.name, 'no-change-note-required')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate |
jq 'any(.[].filename ; test("/change-notes/.*[.]md$"))' --exit-status

View File

@@ -9,6 +9,8 @@ on:
branches:
- main
- 'rc/*'
paths:
- 'csharp/**'
schedule:
- cron: '0 9 * * 1'

View File

@@ -1,60 +0,0 @@
name: Generate CodeQL query help documentation using Sphinx
on:
workflow_dispatch:
inputs:
description:
description: A description of the purpose of this job. For human consumption.
required: false
push:
branches:
- 'lgtm.com'
pull_request:
paths:
- '.github/workflows/generate-query-help-docs.yml'
- 'docs/codeql/query-help/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone github/codeql
uses: actions/checkout@v2
with:
path: codeql
- name: Clone github/codeql-go
uses: actions/checkout@v2
with:
repository: 'github/codeql-go'
path: codeql-go
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
uses: dsaltares/fetch-gh-release-asset@aa37ae5c44d3c9820bc12fe675e8670ecd93bd1c
with:
repo: "github/codeql-cli-binaries"
version: "latest"
file: "codeql-linux64.zip"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Set up query help docs folder
run: |
cp -r codeql/docs/codeql/** .
- name: Query help to markdown
run: |
PATH="$PATH:codeql-cli/codeql" python codeql/docs/codeql/query-help-markdown.py
- name: Run Sphinx for query help
uses: ammaraskar/sphinx-action@8b4f60114d7fd1faeba1a712269168508d4750d2 # v0.4
with:
docs-folder: "query-help/"
pre-build-command: "python -m pip install --upgrade recommonmark"
build-command: "sphinx-build -b dirhtml . _build"
- name: Upload HTML artifacts
uses: actions/upload-artifact@v2
with:
name: query-help-html
path: query-help/_build

View File

@@ -4,17 +4,9 @@
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
# Assign query help for docs review
/cpp/**/*.qhelp @hubwriter
/csharp/**/*.qhelp @jf205
/java/**/*.qhelp @felicitymay
/javascript/**/*.qhelp @mchammer01
/python/**/*.qhelp @felicitymay
/docs/language/ @shati-patel @jf205
# Exclude help for experimental queries from docs review
/cpp/**/experimental/**/*.qhelp @github/codeql-c-analysis
/csharp/**/experimental/**/*.qhelp @github/codeql-csharp
/java/**/experimental/**/*.qhelp @github/codeql-java
/javascript/**/experimental/**/*.qhelp @github/codeql-javascript
/python/**/experimental/**/*.qhelp @github/codeql-python
# Make @xcorail (GitHub Security Lab) a code owner for experimental queries so he gets pinged when we promote a query out of experimental
/cpp/**/experimental/**/* @github/codeql-c-analysis @xcorail
/csharp/**/experimental/**/* @github/codeql-csharp @xcorail
/java/**/experimental/**/* @github/codeql-java @xcorail
/javascript/**/experimental/**/* @github/codeql-javascript @xcorail
/python/**/experimental/**/* @github/codeql-python @xcorail

View File

@@ -49,7 +49,11 @@ If you have an idea for a query that you would like to share with other CodeQL u
- The query must have at least one true positive result on some revision of a real project.
Experimental queries and libraries may not be actively maintained as the [supported](docs/supported-queries.md) libraries evolve. They may also be changed in backwards-incompatible ways or may be removed entirely in the future without deprecation warnings.
6. **Query help files and unit tests**
- Query help (`.qhelp`) files and unit tests are optional (but strongly encouraged!) for queries in the `experimental` directories. For more information about contributing query help files and unit tests, see [Supported CodeQL queries and libraries](docs/supported-queries.md).
Experimental queries and libraries may not be actively maintained as the supported libraries evolve. They may also be changed in backwards-incompatible ways or may be removed entirely in the future without deprecation warnings.
After the experimental query is merged, we welcome pull requests to improve it. Before a query can be moved out of the `experimental` subdirectory, it must satisfy [the requirements for being a supported query](docs/supported-queries.md).

View File

@@ -356,6 +356,7 @@
],
"Inline Test Expectations": [
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"java/ql/test/TestUtilities/InlineExpectationsTest.qll",
"python/ql/test/TestUtilities/InlineExpectationsTest.qll"
],
"C++ ExternalAPIs": [
@@ -424,5 +425,10 @@
"java/ql/src/IDEContextual.qll",
"javascript/ql/src/IDEContextual.qll",
"python/ql/src/analysis/IDEContextual.qll"
],
"SSA C#": [
"csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll"
]
}
}

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* A new query (`cpp/memset-may-be-deleted`) is added to the default query suite. The query finds calls to `memset` that may be removed by the compiler. This behavior can make information-leak vulnerabilities easier to exploit. This query was originally [submitted as an experimental query by @ihsinme](https://github.com/github/codeql/pull/4953).

View File

@@ -0,0 +1,3 @@
char password[MAX_PASSWORD_LENGTH];
// read and verify password
memset(password, 0, MAX_PASSWORD_LENGTH);

View File

@@ -0,0 +1,3 @@
char password[MAX_PASSWORD_LENGTH];
// read and verify password
memset_s(password, MAX_PASSWORD_LENGTH, 0, MAX_PASSWORD_LENGTH);

View File

@@ -0,0 +1,45 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Calling <code>memset</code> or <code>bzero</code> on a buffer to clear its contents may get optimized
away by the compiler if the buffer is not subsequently used. This is not desirable behavior if the buffer
contains sensitive data that could somehow be retrieved by an attacker.</p>
</overview>
<recommendation>
<p>Use alternative platform-supplied functions that will not get optimized away. Examples of such
functions include <code>memset_s</code>, <code>SecureZeroMemory</code>, and <code>bzero_explicit</code>.
Alternatively, passing the <code>-fno-builtin-memset</code> option to the GCC/Clang compiler usually
also prevents the optimization. Finally, you can use the public-domain <code>secure_memzero</code> function
(see references below). This function, however, is not guaranteed to work on all platforms and compilers.</p>
</recommendation>
<example>
<p>The following program fragment uses <code>memset</code> to erase sensitive information after it is no
longer needed:</p>
<sample src="MemsetMayBeDeleted-bad.c" />
<p>Because of dead store elimination, the call to <code>memset</code> may be removed by the compiler
(since the buffer is not subsequently used), resulting in potentially sensitive data remaining in memory.
</p>
<p>The best solution to this problem is to use the <code>memset_s</code> function instead of
<code>memset</code>:</p>
<sample src="MemsetMayBeDeleted-good.c" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations">MSC06-C. Beware of compiler optimizations</a>.
</li>
<li>
USENIX: The Advanced Computing Systems Association:
<a href="https://www.usenix.org/system/files/conference/usenixsecurity17/sec17-yang.pdf">Dead Store Elimination (Still) Considered Harmfuls</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,81 @@
/**
* @name Call to `memset` may be deleted
* @description Using the `memset` function to clear private data in a variable that has no subsequent use
* can make information-leak vulnerabilities easier to exploit because the compiler can remove the call.
* @kind problem
* @id cpp/memset-may-be-deleted
* @problem.severity warning
* @precision high
* @tags security
* external/cwe/cwe-14
*/
import cpp
import semmle.code.cpp.dataflow.EscapesTree
import semmle.code.cpp.commons.Exclusions
import semmle.code.cpp.models.interfaces.Alias
class MemsetFunction extends Function {
MemsetFunction() {
this.hasGlobalOrStdOrBslName("memset")
or
this.hasGlobalOrStdName("wmemset")
or
this.hasGlobalName(["bzero", "__builtin_memset"])
}
}
predicate isNonEscapingArgument(Expr escaped) {
exists(Call call, AliasFunction aliasFunction, int i |
aliasFunction = call.getTarget() and
call.getArgument(i) = escaped.getUnconverted() and
(
aliasFunction.parameterNeverEscapes(i)
or
aliasFunction.parameterEscapesOnlyViaReturn(i) and
(call instanceof ExprInVoidContext or call.getConversion*() instanceof BoolConversion)
)
)
}
pragma[noinline]
predicate callToMemsetWithRelevantVariable(
LocalVariable v, VariableAccess acc, FunctionCall call, MemsetFunction memset
) {
not v.isStatic() and
// Reference-typed variables get special treatment in `variableAddressEscapesTree` so we leave them
// out of this query.
not v.getUnspecifiedType() instanceof ReferenceType and
call.getTarget() = memset and
acc = v.getAnAccess() and
// `v` escapes as the argument to `memset`
variableAddressEscapesTree(acc, call.getArgument(0).getFullyConverted())
}
pragma[noinline]
predicate relevantVariable(LocalVariable v, FunctionCall call, MemsetFunction memset) {
exists(VariableAccess acc, VariableAccess anotherAcc |
callToMemsetWithRelevantVariable(v, acc, call, memset) and
// `v` is not only just used in the call to `memset`.
anotherAcc = v.getAnAccess() and
acc != anotherAcc and
not anotherAcc.isUnevaluated()
)
}
from FunctionCall call, LocalVariable v, MemsetFunction memset
where
relevantVariable(v, call, memset) and
not isFromMacroDefinition(call) and
// `v` doesn't escape anywhere else.
forall(Expr escape | variableAddressEscapesTree(v.getAnAccess(), escape) |
isNonEscapingArgument(escape)
) and
// There is no later use of `v`.
not v.getAnAccess() = call.getASuccessor*() and
// Not using the `-fno-builtin-memset` flag
exists(Compilation c |
c.getAFileCompiled() = call.getFile() and
not c.getAnArgument() = "-fno-builtin-memset"
)
select call, "Call to " + memset.getName() + " may be deleted by the compiler."

View File

@@ -46,7 +46,7 @@ class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration {
UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" }
override predicate isSource(DataFlow::Node source) {
exists(RemoteFlowFunction remoteFlow |
exists(RemoteFlowSourceFunction remoteFlow |
remoteFlow = source.asExpr().(Call).getTarget() and
remoteFlow.hasRemoteFlowSource(_, _)
)

View File

@@ -34,6 +34,10 @@ class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element tainted) {
exists(PrintStdoutCall call | call.getAnArgument() = tainted)
}
override predicate isBarrier(Expr e) {
super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType
}
}
from QueryString query, Element printedArg, PathNode sourceNode, PathNode sinkNode

View File

@@ -8,6 +8,7 @@
* @tags reliability
* security
* external/cwe/cwe-242
* external/cwe/cwe-676
*/
import cpp

View File

@@ -1,35 +0,0 @@
// BAD: the memset call will probably be removed.
void getPassword(void) {
char pwd[64];
if (GetPassword(pwd, sizeof(pwd))) {
/* Checking of password, secure operations, etc. */
}
memset(pwd, 0, sizeof(pwd));
}
// GOOD: in this case the memset will not be removed.
void getPassword(void) {
char pwd[64];
if (retrievePassword(pwd, sizeof(pwd))) {
/* Checking of password, secure operations, etc. */
}
memset_s(pwd, 0, sizeof(pwd));
}
// GOOD: in this case the memset will not be removed.
void getPassword(void) {
char pwd[64];
if (retrievePassword(pwd, sizeof(pwd))) {
/* Checking of password, secure operations, etc. */
}
SecureZeroMemory(pwd, sizeof(pwd));
}
// GOOD: in this case the memset will not be removed.
void getPassword(void) {
char pwd[64];
if (retrievePassword(pwd, sizeof(pwd))) {
/* Checking of password, secure operations, etc. */
}
#pragma optimize("", off)
memset(pwd, 0, sizeof(pwd));
#pragma optimize("", on)
}

View File

@@ -1,31 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Compiler optimization will exclude the cleaning of private information.
Using the <code>memset</code> function to clear private data in a variable that has no subsequent use is potentially dangerous, since the compiler can remove the call.
For some compilers, optimization is also possible when using calls to free memory after the <code>memset</code> function.</p>
<p>It is possible to miss detection of vulnerabilities if used to clear fields of structures or parts of a buffer.</p>
</overview>
<recommendation>
<p>We recommend to use the <code>RtlSecureZeroMemory</code> or <code>memset_s</code> functions, or compilation flags that exclude optimization of <code>memset</code> calls (e.g. -fno-builtin-memset).</p>
</recommendation>
<example>
<p>The following example demonstrates an erroneous and corrected use of the <code>memset</code> function.</p>
<sample src="CompilerRemovalOfCodeToClearBuffers.c" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations">MSC06-C. Beware of compiler optimizations</a>.
</li>
</references>
</qhelp>

View File

@@ -1,127 +0,0 @@
/**
* @name Compiler Removal Of Code To Clear Buffers
* @description Using <code>memset</code> the function to clear private data in a variable that has no subsequent use
* is potentially dangerous because the compiler can remove the call.
* @kind problem
* @id cpp/compiler-removal-of-code-to-clear-buffers
* @problem.severity warning
* @precision medium
* @tags security
* external/cwe/cwe-14
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.dataflow.StackAddress
/**
* A call to `memset` of the form `memset(ptr, value, num)`, for some local variable `ptr`.
*/
class CompilerRemovaMemset extends FunctionCall {
CompilerRemovaMemset() {
this.getTarget().hasGlobalOrStdName("memset") and
exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Expr exp |
DataFlow::localFlow(source, sink) and
this.getArgument(0) = isv.getAnAccess() and
(
source.asExpr() = exp
or
// handle the case where exp is defined by an address being passed into some function.
source.asDefiningArgument() = exp
) and
exp.getLocation().getEndLine() < this.getArgument(0).getLocation().getStartLine() and
sink.asExpr() = this.getArgument(0)
)
}
predicate isExistsAllocForThisVariable() {
exists(AllocationExpr alloc, Variable v |
alloc = v.getAnAssignedValue() and
this.getArgument(0) = v.getAnAccess() and
alloc.getASuccessor+() = this
)
or
not stackPointerFlowsToUse(this.getArgument(0), _, _, _)
}
predicate isExistsFreeForThisVariable() {
exists(DeallocationExpr free, Variable v |
this.getArgument(0) = v.getAnAccess() and
free.getFreedExpr() = v.getAnAccess() and
this.getASuccessor+() = free
)
}
predicate isExistsCallWithThisVariableExcludingDeallocationCalls() {
exists(FunctionCall fc, Variable v |
not fc instanceof DeallocationExpr and
this.getArgument(0) = v.getAnAccess() and
fc.getAnArgument() = v.getAnAccess() and
this.getASuccessor+() = fc
)
}
predicate isVariableUseAfterMemsetExcludingCalls() {
exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Expr exp |
DataFlow::localFlow(source, sink) and
this.getArgument(0) = isv.getAnAccess() and
source.asExpr() = isv.getAnAccess() and
exp.getLocation().getStartLine() > this.getArgument(2).getLocation().getEndLine() and
not exp.getParent() instanceof FunctionCall and
sink.asExpr() = exp
)
}
predicate isVariableUseBoundWithArgumentFunction() {
exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Parameter p, Expr exp |
DataFlow::localFlow(source, sink) and
this.getArgument(0) = isv.getAnAccess() and
this.getEnclosingFunction().getAParameter() = p and
exp.getAChild*() = p.getAnAccess() and
source.asExpr() = exp and
sink.asExpr() = isv.getAnAccess()
)
}
predicate isVariableUseBoundWithGlobalVariable() {
exists(
DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, GlobalVariable gv, Expr exp
|
DataFlow::localFlow(source, sink) and
this.getArgument(0) = isv.getAnAccess() and
exp.getAChild*() = gv.getAnAccess() and
source.asExpr() = exp and
sink.asExpr() = isv.getAnAccess()
)
}
predicate isExistsCompilationFlagsBlockingRemoval() {
exists(Compilation c |
c.getAFileCompiled() = this.getFile() and
c.getAnArgument() = "-fno-builtin-memset"
)
}
predicate isUseVCCompilation() {
exists(Compilation c |
c.getAFileCompiled() = this.getFile() and
(
c.getArgument(2).matches("%gcc%") or
c.getArgument(2).matches("%g++%") or
c.getArgument(2).matches("%clang%") or
c.getArgument(2) = "--force-recompute"
)
)
}
}
from CompilerRemovaMemset fc
where
not (fc.isExistsAllocForThisVariable() and not fc.isExistsFreeForThisVariable()) and
not (fc.isExistsFreeForThisVariable() and not fc.isUseVCCompilation()) and
not fc.isVariableUseAfterMemsetExcludingCalls() and
not fc.isExistsCallWithThisVariableExcludingDeallocationCalls() and
not fc.isVariableUseBoundWithArgumentFunction() and
not fc.isVariableUseBoundWithGlobalVariable() and
not fc.isExistsCompilationFlagsBlockingRemoval()
select fc.getArgument(0), "This variable will not be cleared."

View File

@@ -139,6 +139,19 @@ class Declaration extends Locatable, @declaration {
this.hasQualifiedName("std", "", name)
}
/**
* Holds if this declaration has the given name in the global namespace,
* the `std` namespace or the `bsl` namespace.
* We treat `std` and `bsl` as the same in some of our models.
*/
predicate hasGlobalOrStdOrBslName(string name) {
this.hasGlobalName(name)
or
this.hasQualifiedName("std", "", name)
or
this.hasQualifiedName("bsl", "", name)
}
/** Gets a specifier of this declaration. */
Specifier getASpecifier() { none() } // overridden in subclasses

View File

@@ -467,7 +467,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
// ... and likewise for destructors.
this.(Destructor).getADestruction().mayBeGloballyImpure()
else
// Unless it's a function that we know is side-effect-free, it may
// Unless it's a function that we know is side-effect free, it may
// have side-effects.
not this.hasGlobalOrStdName([
"strcmp", "wcscmp", "_mbscmp", "strlen", "wcslen", "_mbslen", "_mbslen_l", "_mbstrlen",
@@ -680,7 +680,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/**
* A C/C++ non-member function (a function that is not a member of any
* class). For example the in the following code, `MyFunction` is a
* class). For example, in the following code, `MyFunction` is a
* `TopLevelFunction` but `MyMemberFunction` is not:
* ```
* void MyFunction() {

View File

@@ -34,10 +34,10 @@ class Scanf extends ScanfFunction {
Scanf() {
this instanceof TopLevelFunction and
(
hasName("scanf") or // scanf(format, args...)
hasName("wscanf") or // wscanf(format, args...)
hasName("_scanf_l") or // _scanf_l(format, locale, args...)
hasName("_wscanf_l") // _wscanf_l(format, locale, args...)
hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...)
hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...)
hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...)
hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...)
)
}
@@ -53,10 +53,10 @@ class Fscanf extends ScanfFunction {
Fscanf() {
this instanceof TopLevelFunction and
(
hasName("fscanf") or // fscanf(src_stream, format, args...)
hasName("fwscanf") or // fwscanf(src_stream, format, args...)
hasName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...)
hasName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...)
hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...)
hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...)
hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...)
hasGlobalName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...)
)
}
@@ -72,10 +72,10 @@ class Sscanf extends ScanfFunction {
Sscanf() {
this instanceof TopLevelFunction and
(
hasName("sscanf") or // sscanf(src_stream, format, args...)
hasName("swscanf") or // swscanf(src, format, args...)
hasName("_sscanf_l") or // _sscanf_l(src, format, locale, args...)
hasName("_swscanf_l") // _swscanf_l(src, format, locale, args...)
hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...)
hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...)
hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...)
hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...)
)
}
@@ -91,10 +91,10 @@ class Snscanf extends ScanfFunction {
Snscanf() {
this instanceof TopLevelFunction and
(
hasName("_snscanf") or // _snscanf(src, max_amount, format, args...)
hasName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
hasName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
hasName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...)
hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
hasGlobalName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
// note that the max_amount is not a limit on the output length, it's an input length
// limit used with non null-terminated strings.
)

View File

@@ -131,7 +131,22 @@ private predicate lvalueToUpdate(Expr lvalue, Expr outer, ControlFlowNode node)
exists(Call call | node = call |
outer = call.getQualifier().getFullyConverted() and
outer.getUnspecifiedType() instanceof Class and
not call.getTarget().hasSpecifier("const")
not (
call.getTarget().hasSpecifier("const") and
// Given the following program:
// ```
// struct C {
// void* data_;
// void* data() const { return data; }
// };
// C c;
// memcpy(c.data(), source, 16)
// ```
// the data pointed to by `c.data_` is potentially modified by the call to `memcpy` even though
// `C::data` has a const specifier. So we further place the restriction that the type returned
// by `call` should not be of the form `const T*` (for some deeply const type `T`).
call.getType().isDeeplyConstBelow()
)
)
or
assignmentTo(outer, node)
@@ -170,7 +185,11 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
or
outer = call.getQualifier().getFullyConverted() and
outer.getUnspecifiedType() instanceof PointerType and
not call.getTarget().hasSpecifier("const")
not (
call.getTarget().hasSpecifier("const") and
// See the `lvalueToUpdate` case for an explanation of this conjunct.
call.getType().isDeeplyConstBelow()
)
)
or
exists(PointerFieldAccess fa |

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -3598,6 +3598,7 @@ private module FlowExploration {
or
exists(PartialPathNodeRev mid |
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
not clearsContent(node, ap.getHead()) and
not fullBarrier(node, config) and
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
)
@@ -3611,6 +3612,7 @@ private module FlowExploration {
exists(PartialPathNodeFwd mid |
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
not fullBarrier(node, config) and
not clearsContent(node, ap.getHead().getContent()) and
if node instanceof CastingNode
then compatibleTypes(getNodeType(node), ap.getType())
else any()

View File

@@ -28,3 +28,8 @@ private import implementations.Swap
private import implementations.GetDelim
private import implementations.SmartPointer
private import implementations.Sscanf
private import implementations.Send
private import implementations.Recv
private import implementations.Accept
private import implementations.Poll
private import implementations.Select

View File

@@ -0,0 +1,56 @@
/**
* Provides implementation classes modeling `accept` and various similar
* functions. See `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.Function
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
/**
* The function `accept` and its assorted variants
*/
private class Accept extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction {
Accept() { this.hasGlobalName(["accept", "accept4", "WSAAccept"]) }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
bufParam = 1 and countParam = 2
}
override predicate hasArrayInput(int bufParam) { bufParam = 1 }
override predicate hasArrayOutput(int bufParam) { bufParam = 1 }
override predicate parameterNeverEscapes(int index) { exists(this.getParameter(index)) }
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
(input.isParameter(0) or input.isParameterDeref(1)) and
(output.isReturnValue() or output.isParameterDeref(1))
}
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = 1 and buffer = true and mustWrite = false
or
i = 2 and buffer = false and mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = 0 and buffer = true
or
i = 1 and buffer = false
}
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
// NOTE: We implement thse two predicates as none because we can't model the low-level changes made to
// the structure pointed to by the file-descriptor argument.
override predicate hasOnlySpecificReadSideEffects() { none() }
override predicate hasOnlySpecificWriteSideEffects() { none() }
}

View File

@@ -15,7 +15,7 @@ private class MallocAllocationFunction extends AllocationFunction {
MallocAllocationFunction() {
// --- C library allocation
hasGlobalOrStdName("malloc") and // malloc(size)
hasGlobalOrStdOrBslName("malloc") and // malloc(size)
sizeArg = 0
or
hasGlobalName([
@@ -104,7 +104,7 @@ private class CallocAllocationFunction extends AllocationFunction {
CallocAllocationFunction() {
// --- C library allocation
hasGlobalOrStdName("calloc") and // calloc(num, size)
hasGlobalOrStdOrBslName("calloc") and // calloc(num, size)
sizeArg = 1 and
multArg = 0
}
@@ -124,7 +124,7 @@ private class ReallocAllocationFunction extends AllocationFunction {
ReallocAllocationFunction() {
// --- C library allocation
hasGlobalOrStdName("realloc") and // realloc(ptr, size)
hasGlobalOrStdOrBslName("realloc") and // realloc(ptr, size)
sizeArg = 1 and
reallocArg = 0
or

View File

@@ -13,9 +13,13 @@ private class StandardDeallocationFunction extends DeallocationFunction {
int freedArg;
StandardDeallocationFunction() {
hasGlobalName([
hasGlobalOrStdOrBslName([
// --- C library allocation
"free", "realloc",
"free", "realloc"
]) and
freedArg = 0
or
hasGlobalName([
// --- OpenSSL memory allocation
"CRYPTO_free", "CRYPTO_secure_free"
]) and

View File

@@ -1,8 +1,8 @@
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.FlowSource
private class Fread extends AliasFunction, RemoteFlowFunction {
Fread() { this.hasGlobalName("fread") }
private class Fread extends AliasFunction, RemoteFlowSourceFunction {
Fread() { this.hasGlobalOrStdOrBslName("fread") }
override predicate parameterNeverEscapes(int n) {
n = 0 or

View File

@@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.FlowSource
* The standard functions `getdelim`, `getwdelim` and the glibc variant `__getdelim`.
*/
private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction,
RemoteFlowFunction {
RemoteFlowSourceFunction {
GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {

View File

@@ -8,8 +8,8 @@ import semmle.code.cpp.models.interfaces.FlowSource
/**
* The POSIX function `getenv`.
*/
class Getenv extends LocalFlowFunction {
Getenv() { this.hasGlobalName("getenv") }
class Getenv extends LocalFlowSourceFunction {
Getenv() { this.hasGlobalOrStdOrBslName("getenv") }
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
(

View File

@@ -14,12 +14,12 @@ import semmle.code.cpp.models.interfaces.FlowSource
* The standard functions `gets` and `fgets`.
*/
private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
SideEffectFunction, RemoteFlowFunction {
SideEffectFunction, RemoteFlowSourceFunction {
GetsFunction() {
// gets(str)
// fgets(str, num, stream)
// fgetws(wstr, num, stream)
hasGlobalOrStdName(["gets", "fgets", "fgetws"])
hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
@@ -54,13 +54,13 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
}
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
not hasGlobalOrStdName("gets") and
not hasName("gets") and
bufParam = 0 and
countParam = 1
}
override predicate hasArrayWithUnknownSize(int bufParam) {
hasGlobalOrStdName("gets") and
hasName("gets") and
bufParam = 0
}

View File

@@ -6,12 +6,9 @@ import semmle.code.cpp.models.interfaces.SideEffect
/**
* The standard function templates `std::move` and `std::forward`.
*/
private class IdentityFunction extends DataFlowFunction, SideEffectFunction, AliasFunction {
IdentityFunction() {
this.getNamespace().getParentNamespace() instanceof GlobalNamespace and
this.getNamespace().getName() = "std" and
this.getName() = ["move", "forward"]
}
private class IdentityFunction extends DataFlowFunction, SideEffectFunction, AliasFunction,
FunctionTemplateInstantiation {
IdentityFunction() { this.hasQualifiedName("std", ["move", "forward"]) }
override predicate hasOnlySpecificReadSideEffects() { any() }

View File

@@ -15,7 +15,7 @@ import semmle.code.cpp.models.interfaces.Iterator
*/
private class IteratorTraits extends Class {
IteratorTraits() {
this.hasQualifiedName("std", "iterator_traits") and
this.hasQualifiedName(["std", "bsl"], "iterator_traits") and
not this instanceof TemplateClass and
exists(TypedefType t |
this.getAMember() = t and
@@ -26,6 +26,14 @@ private class IteratorTraits extends Class {
Type getIteratorType() { result = this.getTemplateArgument(0) }
}
/**
* A type that is deduced to be an iterator because there is a corresponding
* `std::iterator_traits` instantiation for it.
*/
private class IteratorByTraits extends Iterator {
IteratorByTraits() { exists(IteratorTraits it | it.getIteratorType() = this) }
}
/**
* A type which has the typedefs expected for an iterator.
*/
@@ -36,7 +44,7 @@ private class IteratorByTypedefs extends Iterator, Class {
this.getAMember().(TypedefType).hasName("pointer") and
this.getAMember().(TypedefType).hasName("reference") and
this.getAMember().(TypedefType).hasName("iterator_category") and
not this.hasQualifiedName("std", "iterator_traits")
not this.hasQualifiedName(["std", "bsl"], "iterator_traits")
}
}
@@ -44,17 +52,13 @@ private class IteratorByTypedefs extends Iterator, Class {
* The `std::iterator` class.
*/
private class StdIterator extends Iterator, Class {
StdIterator() { this.hasQualifiedName("std", "iterator") }
StdIterator() { this.hasQualifiedName(["std", "bsl"], "iterator") }
}
/**
* A type that is deduced to be an iterator because there is a corresponding
* `std::iterator_traits` instantiation for it.
* Gets the `FunctionInput` corresponding to an iterator parameter to
* user-defined operator `op`, at `index`.
*/
private class IteratorByTraits extends Iterator {
IteratorByTraits() { exists(IteratorTraits it | it.getIteratorType() = this) }
}
private FunctionInput getIteratorArgumentInput(Operator op, int index) {
exists(Type t |
t =
@@ -155,17 +159,21 @@ private class IteratorSubOperator extends Operator, TaintFunction {
private class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, TaintFunction {
IteratorAssignArithmeticOperator() {
this.hasName(["operator+=", "operator-="]) and
this.getDeclaringType() instanceof Iterator
exists(getIteratorArgumentInput(this, 0))
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and
output.isReturnValue()
or
input.isParameterDeref(0) and output.isReturnValueDeref()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and output.isReturnValueDeref()
or
// reverse flow from returned reference to the object referenced by the first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
or
input.isParameterDeref(1) and
output.isParameterDeref(0)
}
@@ -177,8 +185,7 @@ private class IteratorAssignArithmeticOperator extends Operator, DataFlowFunctio
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorPointerDereferenceMemberOperator() {
this.hasName("operator*") and
this.getDeclaringType() instanceof Iterator
this.getClassAndName("operator*") instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -195,8 +202,7 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
*/
private class IteratorCrementMemberOperator extends MemberFunction, DataFlowFunction, TaintFunction {
IteratorCrementMemberOperator() {
this.hasName(["operator++", "operator--"]) and
this.getDeclaringType() instanceof Iterator
this.getClassAndName(["operator++", "operator--"]) instanceof Iterator
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
@@ -220,10 +226,7 @@ private class IteratorCrementMemberOperator extends MemberFunction, DataFlowFunc
* A member `operator->` function for an iterator type.
*/
private class IteratorFieldMemberOperator extends Operator, TaintFunction {
IteratorFieldMemberOperator() {
this.hasName("operator->") and
this.getDeclaringType() instanceof Iterator
}
IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
@@ -236,8 +239,7 @@ private class IteratorFieldMemberOperator extends Operator, TaintFunction {
*/
private class IteratorBinaryArithmeticMemberOperator extends MemberFunction, TaintFunction {
IteratorBinaryArithmeticMemberOperator() {
this.hasName(["operator+", "operator-"]) and
this.getDeclaringType() instanceof Iterator
this.getClassAndName(["operator+", "operator-"]) instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -252,21 +254,24 @@ private class IteratorBinaryArithmeticMemberOperator extends MemberFunction, Tai
private class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFunction,
TaintFunction {
IteratorAssignArithmeticMemberOperator() {
this.hasName(["operator+=", "operator-="]) and
this.getDeclaringType() instanceof Iterator
this.getClassAndName(["operator+=", "operator-="]) instanceof Iterator
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierAddress() and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isQualifierObject()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
or
input.isParameterDeref(0) and
output.isQualifierObject()
}
}
@@ -275,10 +280,7 @@ private class IteratorAssignArithmeticMemberOperator extends MemberFunction, Dat
*/
private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorArrayMemberOperator() {
this.hasName("operator[]") and
this.getDeclaringType() instanceof Iterator
}
IteratorArrayMemberOperator() { this.getClassAndName("operator[]") instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
@@ -295,8 +297,7 @@ private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
*/
private class IteratorAssignmentMemberOperator extends MemberFunction, TaintFunction {
IteratorAssignmentMemberOperator() {
this.hasName("operator=") and
this.getDeclaringType() instanceof Iterator and
this.getClassAndName("operator=") instanceof Iterator and
not this instanceof CopyAssignmentOperator and
not this instanceof MoveAssignmentOperator
}
@@ -337,7 +338,7 @@ private class BeginOrEndFunction extends MemberFunction, TaintFunction, GetItera
*/
private class InserterIteratorFunction extends GetIteratorFunction {
InserterIteratorFunction() {
this.hasQualifiedName("std", ["front_inserter", "inserter", "back_inserter"])
this.hasQualifiedName(["std", "bsl"], ["front_inserter", "inserter", "back_inserter"])
}
override predicate getsIterator(FunctionInput input, FunctionOutput output) {

View File

@@ -20,7 +20,7 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
// memcpy(dest, src, num)
// memmove(dest, src, num)
// memmove(dest, src, num, remaining)
this.hasGlobalOrStdName(["memcpy", "memmove"])
this.hasGlobalOrStdOrBslName(["memcpy", "memmove"])
or
// bcopy(src, dest, num)
// mempcpy(dest, src, num)

View File

@@ -15,7 +15,9 @@ import semmle.code.cpp.models.interfaces.SideEffect
private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction {
MemsetFunction() {
this.hasGlobalOrStdName(["memset", "wmemset"])
this.hasGlobalOrStdOrBslName("memset")
or
this.hasGlobalOrStdName("wmemset")
or
this.hasGlobalName([bzero(), "__builtin_memset", "__builtin_memset_chk"])
}

View File

@@ -0,0 +1,44 @@
/**
* Provides implementation classes modeling `poll` and various similar
* functions. See `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.Function
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
/**
* The function `poll` and its assorted variants
*/
private class Poll extends ArrayFunction, AliasFunction, SideEffectFunction {
Poll() { this.hasGlobalName(["poll", "ppoll", "WSAPoll"]) }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
bufParam = 0 and countParam = 1
}
override predicate hasArrayInput(int bufParam) { bufParam = 0 }
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
override predicate parameterNeverEscapes(int index) { exists(this.getParameter(index)) }
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
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 and buffer = true
or
this.hasGlobalName("ppoll") and i = [2, 3] and buffer = false
}
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
}

View File

@@ -15,7 +15,7 @@ private class Printf extends FormattingFunction, AliasFunction {
Printf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdName(["printf", "wprintf"]) or
hasGlobalOrStdOrBslName(["printf", "wprintf"]) or
hasGlobalName(["printf_s", "wprintf_s", "g_printf"])
) and
not exists(getDefinition().getFile().getRelativePath())
@@ -23,10 +23,7 @@ private class Printf extends FormattingFunction, AliasFunction {
override int getFormatParameterIndex() { result = 0 }
deprecated override predicate isWideCharDefault() {
hasGlobalOrStdName("wprintf") or
hasGlobalName("wprintf_s")
}
deprecated override predicate isWideCharDefault() { hasName(["wprintf", "wprintf_s"]) }
override predicate isOutputGlobal() { any() }
@@ -44,7 +41,7 @@ private class Fprintf extends FormattingFunction {
Fprintf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdName(["fprintf", "fwprintf"]) or
hasGlobalOrStdOrBslName(["fprintf", "fwprintf"]) or
hasGlobalName("g_fprintf")
) and
not exists(getDefinition().getFile().getRelativePath())
@@ -52,7 +49,7 @@ private class Fprintf extends FormattingFunction {
override int getFormatParameterIndex() { result = 1 }
deprecated override predicate isWideCharDefault() { hasGlobalOrStdName("fwprintf") }
deprecated override predicate isWideCharDefault() { hasName("fwprintf") }
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true }
}
@@ -64,7 +61,7 @@ private class Sprintf extends FormattingFunction {
Sprintf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdName([
hasGlobalOrStdOrBslName([
"sprintf", // sprintf(dst, format, args...)
"wsprintf" // wsprintf(dst, format, args...)
])
@@ -90,22 +87,20 @@ private class Sprintf extends FormattingFunction {
}
override int getFormatParameterIndex() {
hasGlobalName("g_strdup_printf") and result = 0
hasName("g_strdup_printf") and result = 0
or
hasGlobalName("__builtin___sprintf_chk") and result = 3
hasName("__builtin___sprintf_chk") and result = 3
or
not getName() = ["g_strdup_printf", "__builtin___sprintf_chk"] and
result = 1
}
override int getOutputParameterIndex(boolean isStream) {
not hasGlobalName("g_strdup_printf") and result = 0 and isStream = false
not hasName("g_strdup_printf") and result = 0 and isStream = false
}
override int getFirstFormatArgumentIndex() {
if hasGlobalName("__builtin___sprintf_chk")
then result = 4
else result = getNumberOfParameters()
if hasName("__builtin___sprintf_chk") then result = 4 else result = getNumberOfParameters()
}
}
@@ -116,7 +111,7 @@ private class SnprintfImpl extends Snprintf {
SnprintfImpl() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdName([
hasGlobalOrStdOrBslName([
"snprintf", // C99 defines snprintf
"swprintf" // The s version of wide-char printf is also always the n version
])
@@ -163,10 +158,7 @@ private class SnprintfImpl extends Snprintf {
}
override predicate returnsFullFormatLength() {
(
hasGlobalOrStdName("snprintf") or
hasGlobalName(["g_snprintf", "__builtin___snprintf_chk", "snprintf_s"])
) and
hasName(["snprintf", "g_snprintf", "__builtin___snprintf_chk", "snprintf_s"]) and
not exists(getDefinition().getFile().getRelativePath())
}

View File

@@ -3,11 +3,14 @@ import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
/** Pure string functions. */
/**
* A function that operates on strings and is pure. That is, its evaluation is
* guaranteed to be side-effect free.
*/
private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction {
PureStrFunction() {
hasGlobalOrStdName([
hasGlobalOrStdOrBslName([
atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr",
"strspn", strtol(), strrev(), strcmp(), strlwr(), strupr()
])
@@ -89,10 +92,12 @@ private string strcmp() {
]
}
/** String standard `strlen` function, and related functions for computing string lengths. */
/**
* A function such as `strlen` that returns the length of the given string.
*/
private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction {
StrLenFunction() {
hasGlobalOrStdName(["strlen", "strnlen", "wcslen"])
hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"])
or
hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"])
}
@@ -123,9 +128,12 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun
}
}
/** Pure functions. */
/**
* A function that is pure, that is, its evaluation is guaranteed to be
* side-effect free. Excludes functions modeled by `PureStrFunction` and `PureMemFunction`.
*/
private class PureFunction extends TaintFunction, SideEffectFunction {
PureFunction() { hasGlobalOrStdName(["abs", "labs"]) }
PureFunction() { hasGlobalOrStdOrBslName(["abs", "labs"]) }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i |
@@ -140,11 +148,14 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
override predicate hasOnlySpecificWriteSideEffects() { any() }
}
/** Pure raw-memory functions. */
/**
* A function that operates on memory buffers and is pure. That is, its
* evaluation is guaranteed to be side-effect free.
*/
private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction {
PureMemFunction() {
hasGlobalOrStdName([
hasGlobalOrStdOrBslName([
"memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem"
]) or
this.hasGlobalName("memfrob")

View File

@@ -0,0 +1,88 @@
/**
* Provides implementation classes modeling `recv` and various similar
* functions. See `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.models.interfaces.SideEffect
/** The function `recv` and its assorted variants */
private class Recv extends AliasFunction, ArrayFunction, SideEffectFunction,
RemoteFlowSourceFunction {
Recv() {
this.hasGlobalName([
"recv", // recv(socket, dest, len, flags)
"recvfrom", // recvfrom(socket, dest, len, flags, from, fromlen)
"recvmsg", // recvmsg(socket, msg, flags)
"read", // read(socket, dest, len)
"pread", // pread(socket, dest, len, offset)
"readv", // readv(socket, dest, len)
"preadv", // readv(socket, dest, len, offset)
"preadv2" // readv2(socket, dest, len, offset, flags)
])
}
override predicate parameterNeverEscapes(int index) {
this.getParameter(index).getUnspecifiedType() instanceof PointerType
}
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
not this.hasGlobalName("recvmsg") and
bufParam = 1 and
countParam = 2
}
override predicate hasArrayInput(int bufParam) { this.hasGlobalName("recvfrom") and bufParam = 4 }
override predicate hasArrayOutput(int bufParam) {
bufParam = 1
or
this.hasGlobalName("recvfrom") and bufParam = 4
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
this.hasGlobalName("recvfrom") and
(
i = 4 and buffer = true
or
i = 5 and buffer = false
)
or
this.hasGlobalName("recvmsg") and
i = 1 and
buffer = true
}
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = 1 and buffer = true and mustWrite = false
or
this.hasGlobalName("recvfrom") and
(
i = 4 and buffer = true and mustWrite = false
or
i = 5 and buffer = false and mustWrite = false
)
}
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
(
output.isParameterDeref(1)
or
this.hasGlobalName("recvfrom") and output.isParameterDeref([4, 5])
) and
description = "Buffer read by " + this.getName()
}
}

View File

@@ -0,0 +1,40 @@
/**
* Provides implementation classes modeling `select` and various similar
* functions. See `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.Function
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
/**
* The function `select` and its assorted variants
*/
private class Select extends ArrayFunction, AliasFunction, SideEffectFunction {
Select() { this.hasGlobalName(["select", "pselect"]) }
override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = [1 .. 3] }
override predicate hasArrayInput(int bufParam) { bufParam = [1 .. 3] }
override predicate hasArrayOutput(int bufParam) { bufParam = [1 .. 3] }
override predicate parameterNeverEscapes(int index) { exists(this.getParameter(index)) }
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = [1 .. 3] and buffer = true and mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = [1 .. 5] and buffer = true
}
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
}

View File

@@ -0,0 +1,63 @@
/**
* Provides implementation classes modeling `send` and various similar
* functions. See `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.models.interfaces.SideEffect
/** The function `send` and its assorted variants */
private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, RemoteFlowSinkFunction {
Send() {
this.hasGlobalName([
"send", // send(socket, buf, len, flags)
"sendto", // sendto(socket, buf, len, flags, to, tolen)
"sendmsg", // sendmsg(socket, msg, flags)
"write", // write(socket, buf, len)
"writev", // writev(socket, buf, len)
"pwritev", // pwritev(socket, buf, len, offset)
"pwritev2" // pwritev2(socket, buf, len, offset, flags)
])
}
override predicate parameterNeverEscapes(int index) {
this.getParameter(index).getUnspecifiedType() instanceof PointerType
}
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
not this.hasGlobalName("sendmsg") and
bufParam = 1 and
countParam = 2
}
override predicate hasArrayInput(int bufParam) { bufParam = 1 }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
none()
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = 1 and buffer = true
or
this.hasGlobalName("sendto") and i = 4 and buffer = false
or
this.hasGlobalName("sendmsg") and i = 1 and buffer = true
}
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
override predicate hasRemoteFlowSink(FunctionInput input, string description) {
input.isParameterDeref(1) and description = "Buffer sent by " + this.getName()
}
}

View File

@@ -4,14 +4,14 @@ import semmle.code.cpp.models.interfaces.Taint
* The `std::shared_ptr` and `std::unique_ptr` template classes.
*/
private class UniqueOrSharedPtr extends Class {
UniqueOrSharedPtr() { this.hasQualifiedName("std", ["shared_ptr", "unique_ptr"]) }
UniqueOrSharedPtr() { this.hasQualifiedName(["std", "bsl"], ["shared_ptr", "unique_ptr"]) }
}
/**
* The `std::make_shared` and `std::make_unique` template functions.
*/
private class MakeUniqueOrShared extends TaintFunction {
MakeUniqueOrShared() { this.hasQualifiedName("std", ["make_shared", "make_unique"]) }
MakeUniqueOrShared() { this.hasQualifiedName(["bsl", "std"], ["make_shared", "make_unique"]) }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// Exclude the specializations of `std::make_shared` and `std::make_unique` that allocate arrays

View File

@@ -5,6 +5,41 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Iterator
/**
* The `std::array` template class.
*/
private class Array extends Class {
Array() { this.hasQualifiedName(["std", "bsl"], "array") }
}
/**
* The `std::deque` template class.
*/
private class Deque extends Class {
Deque() { this.hasQualifiedName(["std", "bsl"], "deque") }
}
/**
* The `std::forward_list` template class.
*/
private class ForwardList extends Class {
ForwardList() { this.hasQualifiedName(["std", "bsl"], "forward_list") }
}
/**
* The `std::list` template class.
*/
private class List extends Class {
List() { this.hasQualifiedName(["std", "bsl"], "list") }
}
/**
* The `std::vector` template class.
*/
private class Vector extends Class {
Vector() { this.hasQualifiedName(["std", "bsl"], "vector") }
}
/**
* Additional model for standard container constructors that reference the
* value type of the container (that is, the `T` in `std::vector<T>`). For
@@ -15,7 +50,10 @@ import semmle.code.cpp.models.interfaces.Iterator
*/
private class StdSequenceContainerConstructor extends Constructor, TaintFunction {
StdSequenceContainerConstructor() {
this.getDeclaringType().hasQualifiedName("std", ["vector", "deque", "list", "forward_list"])
this.getDeclaringType() instanceof Vector or
this.getDeclaringType() instanceof Deque or
this.getDeclaringType() instanceof List or
this.getDeclaringType() instanceof ForwardList
}
/**
@@ -50,7 +88,10 @@ private class StdSequenceContainerConstructor extends Constructor, TaintFunction
* The standard container function `data`.
*/
private class StdSequenceContainerData extends TaintFunction {
StdSequenceContainerData() { this.hasQualifiedName("std", ["array", "vector"], "data") }
StdSequenceContainerData() {
this.getClassAndName("data") instanceof Array or
this.getClassAndName("data") instanceof Vector
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from container itself (qualifier) to return value
@@ -69,8 +110,10 @@ private class StdSequenceContainerData extends TaintFunction {
*/
private class StdSequenceContainerPush extends TaintFunction {
StdSequenceContainerPush() {
this.hasQualifiedName("std", ["vector", "deque", "list"], "push_back") or
this.hasQualifiedName("std", ["deque", "list", "forward_list"], "push_front")
this.getClassAndName("push_back") instanceof Vector or
this.getClassAndName(["push_back", "push_front"]) instanceof Deque or
this.getClassAndName("push_front") instanceof ForwardList or
this.getClassAndName(["push_back", "push_front"]) instanceof List
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -85,8 +128,11 @@ private class StdSequenceContainerPush extends TaintFunction {
*/
private class StdSequenceContainerFrontBack extends TaintFunction {
StdSequenceContainerFrontBack() {
this.hasQualifiedName("std", ["array", "vector", "deque", "list", "forward_list"], "front") or
this.hasQualifiedName("std", ["array", "vector", "deque", "list"], "back")
this.getClassAndName(["front", "back"]) instanceof Array or
this.getClassAndName(["front", "back"]) instanceof Deque or
this.getClassAndName("front") instanceof ForwardList or
this.getClassAndName(["front", "back"]) instanceof List or
this.getClassAndName(["front", "back"]) instanceof Vector
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -101,8 +147,10 @@ private class StdSequenceContainerFrontBack extends TaintFunction {
*/
private class StdSequenceContainerInsert extends TaintFunction {
StdSequenceContainerInsert() {
this.hasQualifiedName("std", ["vector", "deque", "list"], "insert") or
this.hasQualifiedName("std", "forward_list", "insert_after")
this.getClassAndName("insert") instanceof Deque or
this.getClassAndName("insert") instanceof List or
this.getClassAndName("insert") instanceof Vector or
this.getClassAndName("insert_after") instanceof ForwardList
}
/**
@@ -138,7 +186,10 @@ private class StdSequenceContainerInsert extends TaintFunction {
*/
private class StdSequenceContainerAssign extends TaintFunction {
StdSequenceContainerAssign() {
this.hasQualifiedName("std", ["vector", "deque", "list", "forward_list"], "assign")
this.getClassAndName("assign") instanceof Deque or
this.getClassAndName("assign") instanceof ForwardList or
this.getClassAndName("assign") instanceof List or
this.getClassAndName("assign") instanceof Vector
}
/**
@@ -170,7 +221,9 @@ private class StdSequenceContainerAssign extends TaintFunction {
*/
private class StdSequenceContainerAt extends TaintFunction {
StdSequenceContainerAt() {
this.hasQualifiedName("std", ["vector", "array", "deque"], ["at", "operator[]"])
this.getClassAndName(["at", "operator[]"]) instanceof Array or
this.getClassAndName(["at", "operator[]"]) instanceof Deque or
this.getClassAndName(["at", "operator[]"]) instanceof Vector
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -188,7 +241,7 @@ private class StdSequenceContainerAt extends TaintFunction {
* The standard vector `emplace` function.
*/
class StdVectorEmplace extends TaintFunction {
StdVectorEmplace() { this.hasQualifiedName("std", "vector", "emplace") }
StdVectorEmplace() { this.getClassAndName("emplace") instanceof Vector }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter except the position iterator to qualifier and return value
@@ -205,7 +258,7 @@ class StdVectorEmplace extends TaintFunction {
* The standard vector `emplace_back` function.
*/
class StdVectorEmplaceBack extends TaintFunction {
StdVectorEmplaceBack() { this.hasQualifiedName("std", "vector", "emplace_back") }
StdVectorEmplaceBack() { this.getClassAndName("emplace_back") instanceof Vector }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter to qualifier

View File

@@ -5,14 +5,18 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Iterator
/**
* The `std::map` and `std::unordered_map` template classes.
*/
private class MapOrUnorderedMap extends Class {
MapOrUnorderedMap() { this.hasQualifiedName(["std", "bsl"], ["map", "unordered_map"]) }
}
/**
* Additional model for map constructors using iterator inputs.
*/
private class StdMapConstructor extends Constructor, TaintFunction {
StdMapConstructor() {
this.hasQualifiedName("std", "map", "map") or
this.hasQualifiedName("std", "unordered_map", "unordered_map")
}
StdMapConstructor() { this.getDeclaringType() instanceof MapOrUnorderedMap }
/**
* Gets the index of a parameter to this function that is an iterator.
@@ -37,7 +41,7 @@ private class StdMapConstructor extends Constructor, TaintFunction {
*/
private class StdMapInsert extends TaintFunction {
StdMapInsert() {
this.hasQualifiedName("std", ["map", "unordered_map"], ["insert", "insert_or_assign"])
this.getClassAndName(["insert", "insert_or_assign"]) instanceof MapOrUnorderedMap
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -55,9 +59,7 @@ private class StdMapInsert extends TaintFunction {
* The standard map `emplace` and `emplace_hint` functions.
*/
private class StdMapEmplace extends TaintFunction {
StdMapEmplace() {
this.hasQualifiedName("std", ["map", "unordered_map"], ["emplace", "emplace_hint"])
}
StdMapEmplace() { this.getClassAndName(["emplace", "emplace_hint"]) instanceof MapOrUnorderedMap }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from the last parameter (which may be the value part used to
@@ -79,7 +81,7 @@ private class StdMapEmplace extends TaintFunction {
* The standard map `try_emplace` function.
*/
private class StdMapTryEmplace extends TaintFunction {
StdMapTryEmplace() { this.hasQualifiedName("std", ["map", "unordered_map"], "try_emplace") }
StdMapTryEmplace() { this.getClassAndName("try_emplace") instanceof MapOrUnorderedMap }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter apart from the key to qualifier and return value
@@ -106,7 +108,7 @@ private class StdMapTryEmplace extends TaintFunction {
* The standard map `merge` function.
*/
private class StdMapMerge extends TaintFunction {
StdMapMerge() { this.hasQualifiedName("std", ["map", "unordered_map"], "merge") }
StdMapMerge() { this.getClassAndName("merge") instanceof MapOrUnorderedMap }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// container1.merge(container2)
@@ -119,7 +121,7 @@ private class StdMapMerge extends TaintFunction {
* The standard map functions `at` and `operator[]`.
*/
private class StdMapAt extends TaintFunction {
StdMapAt() { this.hasQualifiedName("std", ["map", "unordered_map"], ["at", "operator[]"]) }
StdMapAt() { this.getClassAndName(["at", "operator[]"]) instanceof MapOrUnorderedMap }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to referenced return value
@@ -136,7 +138,7 @@ private class StdMapAt extends TaintFunction {
* The standard map `find` function.
*/
private class StdMapFind extends TaintFunction {
StdMapFind() { this.hasQualifiedName("std", ["map", "unordered_map"], "find") }
StdMapFind() { this.getClassAndName("find") instanceof MapOrUnorderedMap }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
@@ -148,7 +150,7 @@ private class StdMapFind extends TaintFunction {
* The standard map `erase` function.
*/
private class StdMapErase extends TaintFunction {
StdMapErase() { this.hasQualifiedName("std", ["map", "unordered_map"], "erase") }
StdMapErase() { this.getClassAndName("erase") instanceof MapOrUnorderedMap }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to iterator return value
@@ -163,8 +165,7 @@ private class StdMapErase extends TaintFunction {
*/
private class StdMapEqualRange extends TaintFunction {
StdMapEqualRange() {
this.hasQualifiedName("std", ["map", "unordered_map"],
["lower_bound", "upper_bound", "equal_range"])
this.getClassAndName(["lower_bound", "upper_bound", "equal_range"]) instanceof MapOrUnorderedMap
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -7,10 +7,16 @@ import semmle.code.cpp.models.interfaces.Taint
/**
* An instantiation of `std::pair<T1, T2>`.
*/
class StdPairClass extends ClassTemplateInstantiation {
StdPairClass() { getTemplate().hasQualifiedName("std", "pair") }
private class StdPair extends ClassTemplateInstantiation {
StdPair() { this.hasQualifiedName(["std", "bsl"], "pair") }
}
/**
* DEPRECATED: This is now called `StdPair` and is a private part of the
* library implementation.
*/
deprecated class StdPairClass = StdPair;
/**
* Any of the single-parameter constructors of `std::pair` that takes a reference to an
* instantiation of `std::pair`. These constructors allow conversion between pair types when the
@@ -18,9 +24,9 @@ class StdPairClass extends ClassTemplateInstantiation {
*/
class StdPairCopyishConstructor extends Constructor, TaintFunction {
StdPairCopyishConstructor() {
this.getDeclaringType() instanceof StdPairClass and
this.getDeclaringType() instanceof StdPair and
this.getNumberOfParameters() = 1 and
this.getParameter(0).getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdPairClass
this.getParameter(0).getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdPair
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -38,7 +44,7 @@ class StdPairCopyishConstructor extends Constructor, TaintFunction {
* Additional model for `std::pair` constructors.
*/
private class StdPairConstructor extends Constructor, TaintFunction {
StdPairConstructor() { this.hasQualifiedName("std", "pair", "pair") }
StdPairConstructor() { this.getDeclaringType() instanceof StdPair }
/**
* Gets the index of a parameter to this function that is a reference to

View File

@@ -5,14 +5,18 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Iterator
/**
* An instantiation of `std::set` or `std::unordered_set`.
*/
private class StdSet extends ClassTemplateInstantiation {
StdSet() { this.hasQualifiedName(["std", "bsl"], ["set", "unordered_set"]) }
}
/**
* Additional model for set constructors using iterator inputs.
*/
private class StdSetConstructor extends Constructor, TaintFunction {
StdSetConstructor() {
this.hasQualifiedName("std", "set", "set") or
this.hasQualifiedName("std", "unordered_set", "unordered_set")
}
StdSetConstructor() { this.getDeclaringType() instanceof StdSet }
/**
* Gets the index of a parameter to this function that is an iterator.
@@ -36,7 +40,7 @@ private class StdSetConstructor extends Constructor, TaintFunction {
* The standard set `insert` and `insert_or_assign` functions.
*/
private class StdSetInsert extends TaintFunction {
StdSetInsert() { this.hasQualifiedName("std", ["set", "unordered_set"], "insert") }
StdSetInsert() { this.getClassAndName("insert") instanceof StdSet }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from last parameter to qualifier and return value
@@ -53,9 +57,7 @@ private class StdSetInsert extends TaintFunction {
* The standard set `emplace` and `emplace_hint` functions.
*/
private class StdSetEmplace extends TaintFunction {
StdSetEmplace() {
this.hasQualifiedName("std", ["set", "unordered_set"], ["emplace", "emplace_hint"])
}
StdSetEmplace() { this.getClassAndName(["emplace", "emplace_hint"]) instanceof StdSet }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter to qualifier and return value
@@ -76,7 +78,7 @@ private class StdSetEmplace extends TaintFunction {
* The standard set `merge` function.
*/
private class StdSetMerge extends TaintFunction {
StdSetMerge() { this.hasQualifiedName("std", ["set", "unordered_set"], "merge") }
StdSetMerge() { this.getClassAndName("merge") instanceof StdSet }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// container1.merge(container2)
@@ -89,7 +91,7 @@ private class StdSetMerge extends TaintFunction {
* The standard set `find` function.
*/
private class StdSetFind extends TaintFunction {
StdSetFind() { this.hasQualifiedName("std", ["set", "unordered_set"], "find") }
StdSetFind() { this.getClassAndName("find") instanceof StdSet }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
@@ -101,7 +103,7 @@ private class StdSetFind extends TaintFunction {
* The standard set `erase` function.
*/
private class StdSetErase extends TaintFunction {
StdSetErase() { this.hasQualifiedName("std", ["set", "unordered_set"], "erase") }
StdSetErase() { this.getClassAndName("erase") instanceof StdSet }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to iterator return value
@@ -116,8 +118,7 @@ private class StdSetErase extends TaintFunction {
*/
private class StdSetEqualRange extends TaintFunction {
StdSetEqualRange() {
this.hasQualifiedName("std", ["set", "unordered_set"],
["lower_bound", "upper_bound", "equal_range"])
this.getClassAndName(["lower_bound", "upper_bound", "equal_range"]) instanceof StdSet
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -12,7 +12,7 @@ import semmle.code.cpp.models.interfaces.DataFlow
* The `std::basic_string` template class instantiations.
*/
private class StdBasicString extends ClassTemplateInstantiation {
StdBasicString() { this.hasQualifiedName("std", "basic_string") }
StdBasicString() { this.hasQualifiedName(["std", "bsl"], "basic_string") }
}
/**
@@ -127,7 +127,7 @@ private class StdStringFrontBack extends TaintFunction {
*/
private class StdStringPlus extends TaintFunction {
StdStringPlus() {
this.hasQualifiedName("std", "operator+") and
this.hasQualifiedName(["std", "bsl"], "operator+") and
this.getUnspecifiedType() instanceof StdBasicString
}
@@ -252,13 +252,6 @@ private class StdStringSubstr extends TaintFunction {
}
}
/**
* The `std::basic_stringstream` template class instantiations.
*/
private class StdBasicStringStream extends ClassTemplateInstantiation {
StdBasicStringStream() { this.hasQualifiedName("std", "basic_stringstream") }
}
/**
* The `std::string` functions `at` and `operator[]`.
*/
@@ -280,7 +273,7 @@ private class StdStringAt extends TaintFunction {
* The `std::basic_istream` template class instantiations.
*/
private class StdBasicIStream extends ClassTemplateInstantiation {
StdBasicIStream() { this.hasQualifiedName("std", "basic_istream") }
StdBasicIStream() { this.hasQualifiedName(["std", "bsl"], "basic_istream") }
}
/**
@@ -314,7 +307,7 @@ private class StdIStreamIn extends DataFlowFunction, TaintFunction {
*/
private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
StdIStreamInNonMember() {
this.hasQualifiedName("std", "operator>>") and
this.hasQualifiedName(["std", "bsl"], "operator>>") and
this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicIStream
}
@@ -462,7 +455,7 @@ private class StdIStreamGetLine extends DataFlowFunction, TaintFunction {
* The (non-member) function `std::getline`.
*/
private class StdGetLine extends DataFlowFunction, TaintFunction {
StdGetLine() { this.hasQualifiedName("std", "getline") }
StdGetLine() { this.hasQualifiedName(["std", "bsl"], "getline") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to return value
@@ -488,7 +481,7 @@ private class StdGetLine extends DataFlowFunction, TaintFunction {
* The `std::basic_ostream` template class instantiations.
*/
private class StdBasicOStream extends ClassTemplateInstantiation {
StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") }
StdBasicOStream() { this.hasQualifiedName(["std", "bsl"], "basic_ostream") }
}
/**
@@ -535,7 +528,7 @@ private class StdOStreamOut extends DataFlowFunction, TaintFunction {
*/
private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
StdOStreamOutNonMember() {
this.hasQualifiedName("std", "operator<<") and
this.hasQualifiedName(["std", "bsl"], "operator<<") and
this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicOStream
}
@@ -563,6 +556,13 @@ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
}
}
/**
* The `std::basic_stringstream` template class instantiations.
*/
private class StdBasicStringStream extends ClassTemplateInstantiation {
StdBasicStringStream() { this.hasQualifiedName(["std", "bsl"], "basic_stringstream") }
}
/**
* Additional model for `std::stringstream` constructors that take a string
* input parameter.
@@ -609,7 +609,7 @@ private class StdStringStreamStr extends TaintFunction {
* The `std::basic_ios` template class instantiations.
*/
private class StdBasicIOS extends ClassTemplateInstantiation {
StdBasicIOS() { this.hasQualifiedName("std", "basic_ios") }
StdBasicIOS() { this.hasQualifiedName(["std", "bsl"], "basic_ios") }
}
/**

View File

@@ -13,7 +13,7 @@ import semmle.code.cpp.models.interfaces.SideEffect
*/
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
StrcatFunction() {
this.hasGlobalOrStdName([
this.hasGlobalOrStdOrBslName([
"strcat", // strcat(dst, src)
"strncat", // strncat(dst, src, max_amount)
"wcscat", // wcscat(dst, src)

View File

@@ -13,7 +13,7 @@ import semmle.code.cpp.models.interfaces.SideEffect
*/
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction {
StrcpyFunction() {
this.hasGlobalOrStdName([
this.hasGlobalOrStdOrBslName([
"strcpy", // strcpy(dst, src)
"wcscpy", // wcscpy(dst, src)
"strncpy", // strncpy(dst, src, max_amount)

View File

@@ -15,7 +15,7 @@ import semmle.code.cpp.models.interfaces.Taint
*/
private class Strtok extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction {
Strtok() {
this.hasGlobalOrStdName("strtok") or
this.hasGlobalOrStdOrBslName("strtok") or
this.hasGlobalName(["strtok_r", "_strtok_l", "wcstok", "_wcstok_l", "_mbstok", "_mbstok_l"])
}

View File

@@ -9,7 +9,7 @@ import semmle.code.cpp.models.interfaces.Alias
* ```
*/
private class Swap extends DataFlowFunction {
Swap() { this.hasQualifiedName("std", "swap") }
Swap() { this.hasQualifiedName(["std", "bsl"], "swap") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and

View File

@@ -1,9 +1,9 @@
/**
* Provides a class for modeling functions that return data from potentially untrusted sources. To use
* this QL library, create a QL class extending `DataFlowFunction` with a
* Provides classes for modeling functions that return data from (or send data to) potentially untrusted
* sources. To use this QL library, create a QL class extending `DataFlowFunction` with a
* characteristic predicate that selects the function or set of functions you
* are modeling. Within that class, override the predicates provided by
* `RemoteFlowFunction` to match the flow within that function.
* `RemoteFlowSourceFunction` or `RemoteFlowSinkFunction` to match the flow within that function.
*/
import cpp
@@ -13,19 +13,42 @@ import semmle.code.cpp.models.Models
/**
* A library function that returns data that may be read from a network connection.
*/
abstract class RemoteFlowFunction extends Function {
abstract class RemoteFlowSourceFunction extends Function {
/**
* Holds if remote data described by `description` flows from `output` of a call to this function.
*/
abstract predicate hasRemoteFlowSource(FunctionOutput output, string description);
}
/**
* DEPRECATED: Use `RemoteFlowSourceFunction` instead.
*
* A library function that returns data that may be read from a network connection.
*/
deprecated class RemoteFlowFunction = RemoteFlowSourceFunction;
/**
* A library function that returns data that is directly controlled by a user.
*/
abstract class LocalFlowFunction extends Function {
abstract class LocalFlowSourceFunction extends Function {
/**
* Holds if data described by `description` flows from `output` of a call to this function.
*/
abstract predicate hasLocalFlowSource(FunctionOutput output, string description);
}
/**
* DEPRECATED: Use `LocalFlowSourceFunction` instead.
*
* A library function that returns data that is directly controlled by a user.
*/
deprecated class LocalFlowFunction = LocalFlowSourceFunction;
/** A library function that sends data over a network connection. */
abstract class RemoteFlowSinkFunction extends Function {
/**
* Holds if data described by `description` flows into `input` to a call to this function, and is then
* send over a network connection.
*/
abstract predicate hasRemoteFlowSink(FunctionInput input, string description);
}

View File

@@ -23,7 +23,7 @@ private class RemoteReturnSource extends RemoteFlowSource {
string sourceType;
RemoteReturnSource() {
exists(RemoteFlowFunction func, CallInstruction instr, FunctionOutput output |
exists(RemoteFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and
@@ -42,7 +42,7 @@ private class RemoteParameterSource extends RemoteFlowSource {
string sourceType;
RemoteParameterSource() {
exists(RemoteFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
exists(RemoteFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and
@@ -57,7 +57,7 @@ private class LocalReturnSource extends LocalFlowSource {
string sourceType;
LocalReturnSource() {
exists(LocalFlowFunction func, CallInstruction instr, FunctionOutput output |
exists(LocalFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
@@ -76,7 +76,7 @@ private class LocalParameterSource extends LocalFlowSource {
string sourceType;
LocalParameterSource() {
exists(LocalFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
exists(LocalFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
@@ -98,3 +98,31 @@ private class ArgvSource extends LocalFlowSource {
override string getSourceType() { result = "a command-line argument" }
}
/** A remote data flow sink. */
abstract class RemoteFlowSink extends DataFlow::Node {
/** Gets a string that describes the type of this flow sink. */
abstract string getSinkType();
}
private class RemoteParameterSink extends RemoteFlowSink {
string sourceType;
RemoteParameterSink() {
exists(RemoteFlowSinkFunction func, FunctionInput input, CallInstruction call, int index |
func.hasRemoteFlowSink(input, sourceType) and call.getStaticCallTarget() = func
|
exists(ReadSideEffectInstruction read |
call = read.getPrimaryInstruction() and
read.getIndex() = index and
this.asOperand() = read.getSideEffectOperand() and
input.isParameterDerefOrQualifierObject(index)
)
or
input.isParameterOrQualifierAddress(index) and
this.asOperand() = call.getArgumentOperand(index)
)
}
override string getSinkType() { result = sourceType }
}

View File

@@ -6,6 +6,7 @@
import semmle.code.cpp.exprs.Expr
import semmle.code.cpp.commons.Environment
import semmle.code.cpp.security.SecurityOptions
import semmle.code.cpp.models.interfaces.FlowSource
/**
* Extend this class to customize the security queries for
@@ -59,14 +60,14 @@ class SecurityOptions extends string {
or
functionCall.getTarget().hasGlobalName(fname) and
exists(functionCall.getArgument(arg)) and
(
fname = ["read", "recv", "recvmsg"] and arg = 1
or
fname = "getaddrinfo" and arg = 3
or
fname = "recvfrom" and
(arg = 1 or arg = 4 or arg = 5)
)
fname = "getaddrinfo" and
arg = 3
)
or
exists(RemoteFlowSourceFunction remote, FunctionOutput output |
functionCall.getTarget() = remote and
output.isParameterDerefOrQualifierObject(arg) and
remote.hasRemoteFlowSource(output, _)
)
}
@@ -81,6 +82,12 @@ class SecurityOptions extends string {
userInputReturn(fname)
)
)
or
exists(RemoteFlowSourceFunction remote, FunctionOutput output |
functionCall.getTarget() = remote and
(output.isReturnValue() or output.isReturnValueDeref()) and
remote.hasRemoteFlowSource(output, _)
)
}
/**

View File

@@ -1,6 +1,6 @@
# C/C++ CodeQL tests
This document provides additional information about the C/C++ CodeQL Tests located in `cpp/ql/test`. See [Contributing to CodeQL](/CONTRIBUTING.md) for general information about contributing to this repository.
This document provides additional information about the C/C++ CodeQL tests located in `cpp/ql/test`. The principles under "Copying code", below, also apply to any other C/C++ code in this repository, such as examples linked from query `.qhelp` files in `cpp/ql/src`. For more general information about contributing to this repository, see [Contributing to CodeQL](/CONTRIBUTING.md).
The tests can be run through Visual Studio Code. Advanced users may also use the `codeql test run` command.

View File

@@ -1,3 +0,0 @@
| test.c:13:9:13:13 | buff1 | This variable will not be cleared. |
| test.c:35:9:35:13 | buff1 | This variable will not be cleared. |
| test.c:43:9:43:13 | buff1 | This variable will not be cleared. |

View File

@@ -1 +0,0 @@
experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.ql

View File

@@ -1,201 +0,0 @@
struct buffers
{
unsigned char buff1[50];
unsigned char *buff2;
} globalBuff1,*globalBuff2;
unsigned char * globalBuff;
void badFunc0_0(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
}
void nobadFunc0_0(){
unsigned char buff1[12];
memset(buff1,12,12);
}
void nobadFunc0_1(){
unsigned char buff1[12];
int i;
memset(buff1,12,12);
for(i=0;i<12;i++)
buff1[i]=13;
free(buff1);
}
void nobadFunc1_0(){
unsigned char * buff1;
buff1 = (unsigned char *) malloc(12);
memset(buff1,12,12);
}
void badFunc1_0(){
unsigned char * buff1;
buff1 = (unsigned char *) malloc(12);
memset(buff1,12,12);
free(buff1);
}
void badFunc1_1(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
free(buff1);
}
void nobadFunc2_0_0(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
printf(buff1);
}
void nobadFunc2_0_1(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
printf(buff1+3);
}
void nobadFunc2_0_2(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
printf(*buff1);
}
void nobadFunc2_0_3(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
printf(*(buff1+3));
}
unsigned char * nobadFunc2_0_4(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
return buff1;
}
unsigned char * nobadFunc2_0_5(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
return buff1+3;
}
unsigned char nobadFunc2_0_6(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
return *buff1;
}
unsigned char nobadFunc2_0_7(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
return *(buff1+3);
}
void nobadFunc2_1_0(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
if(*buff1==0)
printf("123123");
}
void nobadFunc2_1_1(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
if(*(buff1+3)==0)
printf("123123");
}
void nobadFunc2_1_2(){
unsigned char buff1[12];
int i;
for(i=0;i<12;i++)
buff1[i]=13;
memset(buff1,12,12);
buff1[2]=5;
}
void nobadFunc3_0(unsigned char * buffAll){
unsigned char * buff1 = buffAll;
memset(buff1,12,12);
}
void nobadFunc3_1(unsigned char * buffAll){
unsigned char * buff1 = buffAll+3;
memset(buff1,12,12);
}
void nobadFunc3_2(struct buffers buffAll){
unsigned char * buff1 = buffAll.buff1;
memset(buff1,12,12);
}
void nobadFunc3_3(struct buffers buffAll){
unsigned char * buff1 = buffAll.buff2;
memset(buff1,12,12);
}
void nobadFunc3_4(struct buffers buffAll){
unsigned char * buff1 = buffAll.buff2+3;
memset(buff1,12,12);
}
void nobadFunc3_5(struct buffers * buffAll){
unsigned char * buff1 = buffAll->buff1;
memset(buff1,12,12);
}
void nobadFunc3_6(struct buffers *buffAll){
unsigned char * buff1 = buffAll->buff2;
memset(buff1,12,12);
}
void nobadFunc4(){
unsigned char * buff1 = globalBuff;
memset(buff1,12,12);
}
void nobadFunc4_0(){
unsigned char * buff1 = globalBuff;
memset(buff1,12,12);
}
void nobadFunc4_1(){
unsigned char * buff1 = globalBuff+3;
memset(buff1,12,12);
}
void nobadFunc4_2(){
unsigned char * buff1 = globalBuff1.buff1;
memset(buff1,12,12);
}
void nobadFunc4_3(){
unsigned char * buff1 = globalBuff1.buff2;
memset(buff1,12,12);
}
void nobadFunc4_4(){
unsigned char * buff1 = globalBuff1.buff2+3;
memset(buff1,12,12);
}
void nobadFunc4_5(){
unsigned char * buff1 = globalBuff2->buff1;
memset(buff1,12,12);
}
void nobadFunc4_6(){
unsigned char * buff1 = globalBuff2->buff2;
memset(buff1,12,12);
}

View File

@@ -216,3 +216,46 @@ void test_pointers2()
sink(ptr4); // clean
sink(*ptr4); // $ MISSING: ast,ir
}
// --- recv ---
int recv(int s, char* buf, int len, int flags);
void test_recv() {
char buffer[1024];
recv(0, buffer, sizeof(buffer), 0);
sink(buffer); // $ ast,ir
sink(*buffer); // $ ast,ir
}
// --- send and related functions ---
int send(int, const void*, int, int);
void test_send(char* buffer, int length) {
send(0, buffer, length, 0); // $ remote
}
struct iovec {
void *iov_base;
unsigned iov_len;
};
int readv(int, const struct iovec*, int);
int writev(int, const struct iovec*, int);
void sink(const iovec* iovs);
void sink(iovec);
int test_readv_and_writev(iovec* iovs) {
readv(0, iovs, 16);
sink(iovs); // $ast,ir
sink(iovs[0]); // $ast MISSING: ir
sink(*iovs); // $ast MISSING: ir
char* p = (char*)iovs[1].iov_base;
sink(p); // $ MISSING: ast,ir
sink(*p); // $ MISSING: ast,ir
writev(0, iovs, 16); // $ remote
}

View File

@@ -0,0 +1,20 @@
/** This tests that we are able to detect remote flow sinks. */
import cpp
import TestUtilities.InlineExpectationsTest
import semmle.code.cpp.security.FlowSources
class RemoteFlowSinkTest extends InlineExpectationsTest {
RemoteFlowSinkTest() { this = "RemoteFlowSinkTest" }
override string getARelevantTag() { result = "remote" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "remote" and
value = "" and
exists(RemoteFlowSink node |
location = node.getLocation() and
element = node.toString()
)
}
}

View File

@@ -36,9 +36,6 @@ argHasPostUpdate
| arrays.cpp:10:8:10:15 | * ... | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:16:8:16:13 | access to array | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:17:8:17:13 | access to array | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:51:8:51:8 | s | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:57:8:57:8 | s | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:63:8:63:8 | s | ArgumentNode is missing PostUpdateNode. |
postWithInFlow
| A.cpp:25:13:25:13 | c [post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:27:28:27:28 | c [post update] | PostUpdateNode should not be the target of local flow. |

View File

@@ -227,14 +227,18 @@
| by_reference.cpp:20:23:20:27 | value | AST only |
| by_reference.cpp:24:19:24:22 | this | AST only |
| by_reference.cpp:24:25:24:29 | value | AST only |
| by_reference.cpp:40:12:40:15 | this | AST only |
| by_reference.cpp:50:3:50:3 | s | AST only |
| by_reference.cpp:50:17:50:26 | call to user_input | AST only |
| by_reference.cpp:51:8:51:8 | s | AST only |
| by_reference.cpp:51:10:51:20 | call to getDirectly | AST only |
| by_reference.cpp:56:3:56:3 | s | AST only |
| by_reference.cpp:56:19:56:28 | call to user_input | AST only |
| by_reference.cpp:57:8:57:8 | s | AST only |
| by_reference.cpp:57:10:57:22 | call to getIndirectly | AST only |
| by_reference.cpp:62:3:62:3 | s | AST only |
| by_reference.cpp:62:25:62:34 | call to user_input | AST only |
| by_reference.cpp:63:8:63:8 | s | AST only |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | AST only |
| by_reference.cpp:68:17:68:18 | & ... | AST only |
| by_reference.cpp:68:21:68:30 | call to user_input | AST only |

View File

@@ -266,14 +266,18 @@
| by_reference.cpp:20:23:20:27 | value |
| by_reference.cpp:24:19:24:22 | this |
| by_reference.cpp:24:25:24:29 | value |
| by_reference.cpp:40:12:40:15 | this |
| by_reference.cpp:50:3:50:3 | s |
| by_reference.cpp:50:17:50:26 | call to user_input |
| by_reference.cpp:51:8:51:8 | s |
| by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:3:56:3 | s |
| by_reference.cpp:56:19:56:28 | call to user_input |
| by_reference.cpp:57:8:57:8 | s |
| by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:62:3:62:3 | s |
| by_reference.cpp:62:25:62:34 | call to user_input |
| by_reference.cpp:63:8:63:8 | s |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:68:17:68:18 | & ... |
| by_reference.cpp:68:21:68:30 | call to user_input |

View File

@@ -0,0 +1,24 @@
void sink(...);
int source();
// --- accept ---
struct sockaddr {
unsigned char length;
int sa_family;
char* sa_data;
};
int accept(int, const sockaddr*, int*);
void sink(sockaddr);
void test_accept() {
int s = source();
sockaddr addr;
int size = sizeof(sockaddr);
int a = accept(s, &addr, &size);
sink(a); // $ ast=17:11 SPURIOUS: ast=18:12 MISSING: ir
sink(addr); // $ ast MISSING: ir
}

View File

@@ -135,6 +135,17 @@
| arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT |
| arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | |
| arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT |
| bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | |
| bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | |
| bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | |
| bsd.cpp:19:14:19:29 | sizeof(sockaddr) | bsd.cpp:20:29:20:32 | size | |
| bsd.cpp:20:11:20:16 | call to accept | bsd.cpp:22:8:22:8 | a | |
| bsd.cpp:20:18:20:18 | s | bsd.cpp:20:11:20:16 | call to accept | TAINT |
| bsd.cpp:20:21:20:25 | & ... | bsd.cpp:20:11:20:16 | call to accept | TAINT |
| bsd.cpp:20:22:20:25 | addr | bsd.cpp:20:11:20:16 | call to accept | TAINT |
| bsd.cpp:20:22:20:25 | addr | bsd.cpp:20:21:20:25 | & ... | |
| bsd.cpp:20:28:20:32 | ref arg & ... | bsd.cpp:20:29:20:32 | size [inner post update] | |
| bsd.cpp:20:29:20:32 | size | bsd.cpp:20:28:20:32 | & ... | |
| constructor_delegation.cpp:8:2:8:8 | this | constructor_delegation.cpp:8:20:8:24 | constructor init of field x [pre-this] | |
| constructor_delegation.cpp:8:14:8:15 | _x | constructor_delegation.cpp:8:22:8:23 | _x | |
| constructor_delegation.cpp:8:22:8:23 | _x | constructor_delegation.cpp:8:20:8:24 | constructor init of field x | TAINT |
@@ -796,8 +807,23 @@
| map.cpp:146:40:146:41 | ref arg i1 | map.cpp:150:8:150:9 | i1 | |
| map.cpp:148:8:148:8 | call to operator* | map.cpp:148:8:148:10 | call to pair | TAINT |
| map.cpp:148:9:148:10 | i1 | map.cpp:148:8:148:8 | call to operator* | TAINT |
| map.cpp:148:9:148:10 | ref arg i1 | map.cpp:146:24:146:25 | i1 | |
| map.cpp:148:9:148:10 | ref arg i1 | map.cpp:146:40:146:41 | i1 | |
| map.cpp:148:9:148:10 | ref arg i1 | map.cpp:148:9:148:10 | i1 | |
| map.cpp:148:9:148:10 | ref arg i1 | map.cpp:149:8:149:9 | i1 | |
| map.cpp:148:9:148:10 | ref arg i1 | map.cpp:150:8:150:9 | i1 | |
| map.cpp:149:8:149:9 | i1 | map.cpp:149:10:149:10 | call to operator-> | TAINT |
| map.cpp:149:8:149:9 | ref arg i1 | map.cpp:146:24:146:25 | i1 | |
| map.cpp:149:8:149:9 | ref arg i1 | map.cpp:146:40:146:41 | i1 | |
| map.cpp:149:8:149:9 | ref arg i1 | map.cpp:148:9:148:10 | i1 | |
| map.cpp:149:8:149:9 | ref arg i1 | map.cpp:149:8:149:9 | i1 | |
| map.cpp:149:8:149:9 | ref arg i1 | map.cpp:150:8:150:9 | i1 | |
| map.cpp:150:8:150:9 | i1 | map.cpp:150:10:150:10 | call to operator-> | TAINT |
| map.cpp:150:8:150:9 | ref arg i1 | map.cpp:146:24:146:25 | i1 | |
| map.cpp:150:8:150:9 | ref arg i1 | map.cpp:146:40:146:41 | i1 | |
| map.cpp:150:8:150:9 | ref arg i1 | map.cpp:148:9:148:10 | i1 | |
| map.cpp:150:8:150:9 | ref arg i1 | map.cpp:149:8:149:9 | i1 | |
| map.cpp:150:8:150:9 | ref arg i1 | map.cpp:150:8:150:9 | i1 | |
| map.cpp:152:12:152:13 | m2 | map.cpp:152:15:152:19 | call to begin | TAINT |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:152:30:152:31 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
@@ -830,8 +856,23 @@
| map.cpp:152:40:152:41 | ref arg i2 | map.cpp:156:8:156:9 | i2 | |
| map.cpp:154:8:154:8 | call to operator* | map.cpp:154:8:154:10 | call to pair | TAINT |
| map.cpp:154:9:154:10 | i2 | map.cpp:154:8:154:8 | call to operator* | TAINT |
| map.cpp:154:9:154:10 | ref arg i2 | map.cpp:152:24:152:25 | i2 | |
| map.cpp:154:9:154:10 | ref arg i2 | map.cpp:152:40:152:41 | i2 | |
| map.cpp:154:9:154:10 | ref arg i2 | map.cpp:154:9:154:10 | i2 | |
| map.cpp:154:9:154:10 | ref arg i2 | map.cpp:155:8:155:9 | i2 | |
| map.cpp:154:9:154:10 | ref arg i2 | map.cpp:156:8:156:9 | i2 | |
| map.cpp:155:8:155:9 | i2 | map.cpp:155:10:155:10 | call to operator-> | TAINT |
| map.cpp:155:8:155:9 | ref arg i2 | map.cpp:152:24:152:25 | i2 | |
| map.cpp:155:8:155:9 | ref arg i2 | map.cpp:152:40:152:41 | i2 | |
| map.cpp:155:8:155:9 | ref arg i2 | map.cpp:154:9:154:10 | i2 | |
| map.cpp:155:8:155:9 | ref arg i2 | map.cpp:155:8:155:9 | i2 | |
| map.cpp:155:8:155:9 | ref arg i2 | map.cpp:156:8:156:9 | i2 | |
| map.cpp:156:8:156:9 | i2 | map.cpp:156:10:156:10 | call to operator-> | TAINT |
| map.cpp:156:8:156:9 | ref arg i2 | map.cpp:152:24:152:25 | i2 | |
| map.cpp:156:8:156:9 | ref arg i2 | map.cpp:152:40:152:41 | i2 | |
| map.cpp:156:8:156:9 | ref arg i2 | map.cpp:154:9:154:10 | i2 | |
| map.cpp:156:8:156:9 | ref arg i2 | map.cpp:155:8:155:9 | i2 | |
| map.cpp:156:8:156:9 | ref arg i2 | map.cpp:156:8:156:9 | i2 | |
| map.cpp:158:12:158:13 | m3 | map.cpp:158:15:158:19 | call to begin | TAINT |
| map.cpp:158:12:158:13 | ref arg m3 | map.cpp:158:30:158:31 | m3 | |
| map.cpp:158:12:158:13 | ref arg m3 | map.cpp:252:1:252:1 | m3 | |
@@ -852,8 +893,23 @@
| map.cpp:158:40:158:41 | ref arg i3 | map.cpp:162:8:162:9 | i3 | |
| map.cpp:160:8:160:8 | call to operator* | map.cpp:160:8:160:10 | call to pair | TAINT |
| map.cpp:160:9:160:10 | i3 | map.cpp:160:8:160:8 | call to operator* | TAINT |
| map.cpp:160:9:160:10 | ref arg i3 | map.cpp:158:24:158:25 | i3 | |
| map.cpp:160:9:160:10 | ref arg i3 | map.cpp:158:40:158:41 | i3 | |
| map.cpp:160:9:160:10 | ref arg i3 | map.cpp:160:9:160:10 | i3 | |
| map.cpp:160:9:160:10 | ref arg i3 | map.cpp:161:8:161:9 | i3 | |
| map.cpp:160:9:160:10 | ref arg i3 | map.cpp:162:8:162:9 | i3 | |
| map.cpp:161:8:161:9 | i3 | map.cpp:161:10:161:10 | call to operator-> | TAINT |
| map.cpp:161:8:161:9 | ref arg i3 | map.cpp:158:24:158:25 | i3 | |
| map.cpp:161:8:161:9 | ref arg i3 | map.cpp:158:40:158:41 | i3 | |
| map.cpp:161:8:161:9 | ref arg i3 | map.cpp:160:9:160:10 | i3 | |
| map.cpp:161:8:161:9 | ref arg i3 | map.cpp:161:8:161:9 | i3 | |
| map.cpp:161:8:161:9 | ref arg i3 | map.cpp:162:8:162:9 | i3 | |
| map.cpp:162:8:162:9 | i3 | map.cpp:162:10:162:10 | call to operator-> | TAINT |
| map.cpp:162:8:162:9 | ref arg i3 | map.cpp:158:24:158:25 | i3 | |
| map.cpp:162:8:162:9 | ref arg i3 | map.cpp:158:40:158:41 | i3 | |
| map.cpp:162:8:162:9 | ref arg i3 | map.cpp:160:9:160:10 | i3 | |
| map.cpp:162:8:162:9 | ref arg i3 | map.cpp:161:8:161:9 | i3 | |
| map.cpp:162:8:162:9 | ref arg i3 | map.cpp:162:8:162:9 | i3 | |
| map.cpp:166:27:166:29 | call to map | map.cpp:167:7:167:9 | m10 | |
| map.cpp:166:27:166:29 | call to map | map.cpp:171:7:171:9 | m10 | |
| map.cpp:166:27:166:29 | call to map | map.cpp:252:1:252:1 | m10 | |
@@ -1460,8 +1516,23 @@
| map.cpp:298:40:298:41 | ref arg i1 | map.cpp:302:8:302:9 | i1 | |
| map.cpp:300:8:300:8 | call to operator* | map.cpp:300:8:300:10 | call to pair | TAINT |
| map.cpp:300:9:300:10 | i1 | map.cpp:300:8:300:8 | call to operator* | TAINT |
| map.cpp:300:9:300:10 | ref arg i1 | map.cpp:298:24:298:25 | i1 | |
| map.cpp:300:9:300:10 | ref arg i1 | map.cpp:298:40:298:41 | i1 | |
| map.cpp:300:9:300:10 | ref arg i1 | map.cpp:300:9:300:10 | i1 | |
| map.cpp:300:9:300:10 | ref arg i1 | map.cpp:301:8:301:9 | i1 | |
| map.cpp:300:9:300:10 | ref arg i1 | map.cpp:302:8:302:9 | i1 | |
| map.cpp:301:8:301:9 | i1 | map.cpp:301:10:301:10 | call to operator-> | TAINT |
| map.cpp:301:8:301:9 | ref arg i1 | map.cpp:298:24:298:25 | i1 | |
| map.cpp:301:8:301:9 | ref arg i1 | map.cpp:298:40:298:41 | i1 | |
| map.cpp:301:8:301:9 | ref arg i1 | map.cpp:300:9:300:10 | i1 | |
| map.cpp:301:8:301:9 | ref arg i1 | map.cpp:301:8:301:9 | i1 | |
| map.cpp:301:8:301:9 | ref arg i1 | map.cpp:302:8:302:9 | i1 | |
| map.cpp:302:8:302:9 | i1 | map.cpp:302:10:302:10 | call to operator-> | TAINT |
| map.cpp:302:8:302:9 | ref arg i1 | map.cpp:298:24:298:25 | i1 | |
| map.cpp:302:8:302:9 | ref arg i1 | map.cpp:298:40:298:41 | i1 | |
| map.cpp:302:8:302:9 | ref arg i1 | map.cpp:300:9:300:10 | i1 | |
| map.cpp:302:8:302:9 | ref arg i1 | map.cpp:301:8:301:9 | i1 | |
| map.cpp:302:8:302:9 | ref arg i1 | map.cpp:302:8:302:9 | i1 | |
| map.cpp:304:12:304:13 | m2 | map.cpp:304:15:304:19 | call to begin | TAINT |
| map.cpp:304:12:304:13 | ref arg m2 | map.cpp:304:30:304:31 | m2 | |
| map.cpp:304:12:304:13 | ref arg m2 | map.cpp:334:7:334:8 | m2 | |
@@ -1488,8 +1559,23 @@
| map.cpp:304:40:304:41 | ref arg i2 | map.cpp:308:8:308:9 | i2 | |
| map.cpp:306:8:306:8 | call to operator* | map.cpp:306:8:306:10 | call to pair | TAINT |
| map.cpp:306:9:306:10 | i2 | map.cpp:306:8:306:8 | call to operator* | TAINT |
| map.cpp:306:9:306:10 | ref arg i2 | map.cpp:304:24:304:25 | i2 | |
| map.cpp:306:9:306:10 | ref arg i2 | map.cpp:304:40:304:41 | i2 | |
| map.cpp:306:9:306:10 | ref arg i2 | map.cpp:306:9:306:10 | i2 | |
| map.cpp:306:9:306:10 | ref arg i2 | map.cpp:307:8:307:9 | i2 | |
| map.cpp:306:9:306:10 | ref arg i2 | map.cpp:308:8:308:9 | i2 | |
| map.cpp:307:8:307:9 | i2 | map.cpp:307:10:307:10 | call to operator-> | TAINT |
| map.cpp:307:8:307:9 | ref arg i2 | map.cpp:304:24:304:25 | i2 | |
| map.cpp:307:8:307:9 | ref arg i2 | map.cpp:304:40:304:41 | i2 | |
| map.cpp:307:8:307:9 | ref arg i2 | map.cpp:306:9:306:10 | i2 | |
| map.cpp:307:8:307:9 | ref arg i2 | map.cpp:307:8:307:9 | i2 | |
| map.cpp:307:8:307:9 | ref arg i2 | map.cpp:308:8:308:9 | i2 | |
| map.cpp:308:8:308:9 | i2 | map.cpp:308:10:308:10 | call to operator-> | TAINT |
| map.cpp:308:8:308:9 | ref arg i2 | map.cpp:304:24:304:25 | i2 | |
| map.cpp:308:8:308:9 | ref arg i2 | map.cpp:304:40:304:41 | i2 | |
| map.cpp:308:8:308:9 | ref arg i2 | map.cpp:306:9:306:10 | i2 | |
| map.cpp:308:8:308:9 | ref arg i2 | map.cpp:307:8:307:9 | i2 | |
| map.cpp:308:8:308:9 | ref arg i2 | map.cpp:308:8:308:9 | i2 | |
| map.cpp:310:12:310:13 | m3 | map.cpp:310:15:310:19 | call to begin | TAINT |
| map.cpp:310:12:310:13 | ref arg m3 | map.cpp:310:30:310:31 | m3 | |
| map.cpp:310:12:310:13 | ref arg m3 | map.cpp:438:1:438:1 | m3 | |
@@ -1510,8 +1596,23 @@
| map.cpp:310:40:310:41 | ref arg i3 | map.cpp:314:8:314:9 | i3 | |
| map.cpp:312:8:312:8 | call to operator* | map.cpp:312:8:312:10 | call to pair | TAINT |
| map.cpp:312:9:312:10 | i3 | map.cpp:312:8:312:8 | call to operator* | TAINT |
| map.cpp:312:9:312:10 | ref arg i3 | map.cpp:310:24:310:25 | i3 | |
| map.cpp:312:9:312:10 | ref arg i3 | map.cpp:310:40:310:41 | i3 | |
| map.cpp:312:9:312:10 | ref arg i3 | map.cpp:312:9:312:10 | i3 | |
| map.cpp:312:9:312:10 | ref arg i3 | map.cpp:313:8:313:9 | i3 | |
| map.cpp:312:9:312:10 | ref arg i3 | map.cpp:314:8:314:9 | i3 | |
| map.cpp:313:8:313:9 | i3 | map.cpp:313:10:313:10 | call to operator-> | TAINT |
| map.cpp:313:8:313:9 | ref arg i3 | map.cpp:310:24:310:25 | i3 | |
| map.cpp:313:8:313:9 | ref arg i3 | map.cpp:310:40:310:41 | i3 | |
| map.cpp:313:8:313:9 | ref arg i3 | map.cpp:312:9:312:10 | i3 | |
| map.cpp:313:8:313:9 | ref arg i3 | map.cpp:313:8:313:9 | i3 | |
| map.cpp:313:8:313:9 | ref arg i3 | map.cpp:314:8:314:9 | i3 | |
| map.cpp:314:8:314:9 | i3 | map.cpp:314:10:314:10 | call to operator-> | TAINT |
| map.cpp:314:8:314:9 | ref arg i3 | map.cpp:310:24:310:25 | i3 | |
| map.cpp:314:8:314:9 | ref arg i3 | map.cpp:310:40:310:41 | i3 | |
| map.cpp:314:8:314:9 | ref arg i3 | map.cpp:312:9:312:10 | i3 | |
| map.cpp:314:8:314:9 | ref arg i3 | map.cpp:313:8:313:9 | i3 | |
| map.cpp:314:8:314:9 | ref arg i3 | map.cpp:314:8:314:9 | i3 | |
| map.cpp:318:37:318:39 | call to unordered_map | map.cpp:319:7:319:9 | m10 | |
| map.cpp:318:37:318:39 | call to unordered_map | map.cpp:323:7:323:9 | m10 | |
| map.cpp:318:37:318:39 | call to unordered_map | map.cpp:438:1:438:1 | m10 | |
@@ -2347,6 +2448,9 @@
| set.cpp:55:40:55:41 | ref arg i1 | set.cpp:55:40:55:41 | i1 | |
| set.cpp:55:40:55:41 | ref arg i1 | set.cpp:57:9:57:10 | i1 | |
| set.cpp:57:9:57:10 | i1 | set.cpp:57:8:57:8 | call to operator* | TAINT |
| set.cpp:57:9:57:10 | ref arg i1 | set.cpp:55:24:55:25 | i1 | |
| set.cpp:57:9:57:10 | ref arg i1 | set.cpp:55:40:55:41 | i1 | |
| set.cpp:57:9:57:10 | ref arg i1 | set.cpp:57:9:57:10 | i1 | |
| set.cpp:59:12:59:13 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:59:12:59:13 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:59:12:59:13 | s2 | set.cpp:59:15:59:19 | call to begin | TAINT |
@@ -2362,6 +2466,9 @@
| set.cpp:59:40:59:41 | ref arg i2 | set.cpp:59:40:59:41 | i2 | |
| set.cpp:59:40:59:41 | ref arg i2 | set.cpp:61:9:61:10 | i2 | |
| set.cpp:61:9:61:10 | i2 | set.cpp:61:8:61:8 | call to operator* | TAINT |
| set.cpp:61:9:61:10 | ref arg i2 | set.cpp:59:24:59:25 | i2 | |
| set.cpp:61:9:61:10 | ref arg i2 | set.cpp:59:40:59:41 | i2 | |
| set.cpp:61:9:61:10 | ref arg i2 | set.cpp:61:9:61:10 | i2 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:66:2:66:4 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:67:2:67:4 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:68:2:68:4 | s11 | |
@@ -2845,6 +2952,9 @@
| set.cpp:169:40:169:41 | ref arg i1 | set.cpp:169:40:169:41 | i1 | |
| set.cpp:169:40:169:41 | ref arg i1 | set.cpp:171:9:171:10 | i1 | |
| set.cpp:171:9:171:10 | i1 | set.cpp:171:8:171:8 | call to operator* | TAINT |
| set.cpp:171:9:171:10 | ref arg i1 | set.cpp:169:24:169:25 | i1 | |
| set.cpp:171:9:171:10 | ref arg i1 | set.cpp:169:40:169:41 | i1 | |
| set.cpp:171:9:171:10 | ref arg i1 | set.cpp:171:9:171:10 | i1 | |
| set.cpp:173:12:173:13 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:173:12:173:13 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:173:12:173:13 | s2 | set.cpp:173:15:173:19 | call to begin | TAINT |
@@ -2860,6 +2970,9 @@
| set.cpp:173:40:173:41 | ref arg i2 | set.cpp:173:40:173:41 | i2 | |
| set.cpp:173:40:173:41 | ref arg i2 | set.cpp:175:9:175:10 | i2 | |
| set.cpp:175:9:175:10 | i2 | set.cpp:175:8:175:8 | call to operator* | TAINT |
| set.cpp:175:9:175:10 | ref arg i2 | set.cpp:173:24:173:25 | i2 | |
| set.cpp:175:9:175:10 | ref arg i2 | set.cpp:173:40:173:41 | i2 | |
| set.cpp:175:9:175:10 | ref arg i2 | set.cpp:175:9:175:10 | i2 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:180:2:180:4 | s11 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:181:2:181:4 | s11 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:182:2:182:4 | s11 | |
@@ -3111,21 +3224,27 @@
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:13:10:13:10 | p | |
| smart_pointer.cpp:11:52:11:57 | call to source | smart_pointer.cpp:11:30:11:50 | call to make_shared | TAINT |
| smart_pointer.cpp:12:11:12:11 | p | smart_pointer.cpp:12:10:12:10 | call to operator* | TAINT |
| smart_pointer.cpp:12:11:12:11 | ref arg p | smart_pointer.cpp:13:10:13:10 | p | |
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:18:11:18:11 | p | |
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:19:10:19:10 | p | |
| smart_pointer.cpp:18:11:18:11 | p | smart_pointer.cpp:18:10:18:10 | call to operator* | TAINT |
| smart_pointer.cpp:18:11:18:11 | ref arg p | smart_pointer.cpp:19:10:19:10 | p | |
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:24:11:24:11 | p | |
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:25:10:25:10 | p | |
| smart_pointer.cpp:23:52:23:57 | call to source | smart_pointer.cpp:23:30:23:50 | call to make_unique | TAINT |
| smart_pointer.cpp:24:11:24:11 | p | smart_pointer.cpp:24:10:24:10 | call to operator* | TAINT |
| smart_pointer.cpp:24:11:24:11 | ref arg p | smart_pointer.cpp:25:10:25:10 | p | |
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:30:11:30:11 | p | |
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:31:10:31:10 | p | |
| smart_pointer.cpp:30:11:30:11 | p | smart_pointer.cpp:30:10:30:10 | call to operator* | TAINT |
| smart_pointer.cpp:30:11:30:11 | ref arg p | smart_pointer.cpp:31:10:31:10 | p | |
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:37:6:37:6 | p | |
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:38:10:38:10 | p | |
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:39:11:39:11 | p | |
| smart_pointer.cpp:37:5:37:17 | ... = ... | smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | |
| smart_pointer.cpp:37:6:37:6 | p | smart_pointer.cpp:37:5:37:5 | call to operator* | TAINT |
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:38:10:38:10 | p | |
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
| smart_pointer.cpp:37:10:37:15 | call to source | smart_pointer.cpp:37:5:37:17 | ... = ... | |
| smart_pointer.cpp:38:10:38:10 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
| smart_pointer.cpp:39:11:39:11 | p | smart_pointer.cpp:39:10:39:10 | call to operator* | TAINT |
@@ -3134,6 +3253,8 @@
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:47:11:47:11 | p | |
| smart_pointer.cpp:45:5:45:17 | ... = ... | smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | |
| smart_pointer.cpp:45:6:45:6 | p | smart_pointer.cpp:45:5:45:5 | call to operator* | TAINT |
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:46:10:46:10 | p | |
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
| smart_pointer.cpp:45:10:45:15 | call to source | smart_pointer.cpp:45:5:45:17 | ... = ... | |
| smart_pointer.cpp:46:10:46:10 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
| smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | TAINT |
@@ -3147,6 +3268,7 @@
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:67:10:67:10 | p | |
| smart_pointer.cpp:65:48:65:53 | call to source | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
| smart_pointer.cpp:65:58:65:58 | 0 | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
| smart_pointer.cpp:66:10:66:10 | ref arg p | smart_pointer.cpp:67:10:67:10 | p | |
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | |
@@ -3197,6 +3319,56 @@
| standalone_iterators.cpp:90:8:90:8 | call to operator-- | standalone_iterators.cpp:90:5:90:5 | call to operator* | TAINT |
| standalone_iterators.cpp:90:8:90:8 | ref arg call to operator-- | standalone_iterators.cpp:90:6:90:7 | ref arg i2 | |
| standalone_iterators.cpp:90:13:90:13 | 0 | standalone_iterators.cpp:90:5:90:5 | ref arg call to operator* | TAINT |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:101:6:101:7 | c1 | |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:102:6:102:7 | c1 | |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:101:6:101:7 | c1 | standalone_iterators.cpp:101:9:101:13 | call to begin | TAINT |
| standalone_iterators.cpp:101:6:101:7 | ref arg c1 | standalone_iterators.cpp:102:6:102:7 | c1 | |
| standalone_iterators.cpp:101:6:101:7 | ref arg c1 | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:101:6:101:7 | ref arg c1 | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:101:9:101:13 | call to begin | standalone_iterators.cpp:101:2:101:15 | ... = ... | |
| standalone_iterators.cpp:101:9:101:13 | call to begin | standalone_iterators.cpp:103:3:103:3 | a | |
| standalone_iterators.cpp:101:9:101:13 | call to begin | standalone_iterators.cpp:104:7:104:7 | a | |
| standalone_iterators.cpp:102:6:102:7 | c1 | standalone_iterators.cpp:102:9:102:13 | call to begin | TAINT |
| standalone_iterators.cpp:102:6:102:7 | ref arg c1 | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:102:6:102:7 | ref arg c1 | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:102:9:102:13 | call to begin | standalone_iterators.cpp:102:2:102:15 | ... = ... | |
| standalone_iterators.cpp:102:9:102:13 | call to begin | standalone_iterators.cpp:107:7:107:7 | b | |
| standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | standalone_iterators.cpp:103:3:103:3 | ref arg a | TAINT |
| standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:103:3:103:3 | a | standalone_iterators.cpp:103:2:103:2 | call to operator* | TAINT |
| standalone_iterators.cpp:103:3:103:3 | ref arg a | standalone_iterators.cpp:104:7:104:7 | a | |
| standalone_iterators.cpp:103:7:103:12 | call to source | standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | TAINT |
| standalone_iterators.cpp:104:7:104:7 | a [post update] | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:104:7:104:7 | a [post update] | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:106:6:106:7 | c1 | standalone_iterators.cpp:106:9:106:13 | call to begin | TAINT |
| standalone_iterators.cpp:106:6:106:7 | ref arg c1 | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:106:9:106:13 | call to begin | standalone_iterators.cpp:106:2:106:15 | ... = ... | |
| standalone_iterators.cpp:106:9:106:13 | call to begin | standalone_iterators.cpp:108:7:108:7 | c | |
| standalone_iterators.cpp:107:7:107:7 | b [post update] | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:108:7:108:7 | c [post update] | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:113:15:113:16 | call to container | standalone_iterators.cpp:116:7:116:8 | c1 | |
| standalone_iterators.cpp:113:15:113:16 | call to container | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:116:7:116:8 | c1 | standalone_iterators.cpp:116:10:116:14 | call to begin | TAINT |
| standalone_iterators.cpp:116:7:116:8 | ref arg c1 | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:116:2:116:16 | ... = ... | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:117:7:117:8 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:118:2:118:3 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:119:7:119:8 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:120:2:120:3 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:121:7:121:8 | it | |
| standalone_iterators.cpp:117:7:117:8 | it [post update] | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:118:2:118:3 | it | standalone_iterators.cpp:118:5:118:5 | call to operator+= | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:119:7:119:8 | it | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:120:2:120:3 | it | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:121:7:121:8 | it | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:118:8:118:8 | 1 | standalone_iterators.cpp:118:2:118:3 | ref arg it | TAINT |
| standalone_iterators.cpp:120:2:120:3 | it | standalone_iterators.cpp:120:5:120:5 | call to operator+= | |
| standalone_iterators.cpp:120:2:120:3 | ref arg it | standalone_iterators.cpp:121:7:121:8 | it | |
| standalone_iterators.cpp:120:8:120:13 | call to source | standalone_iterators.cpp:120:2:120:3 | ref arg it | TAINT |
| stl.h:75:8:75:8 | Unknown literal | stl.h:75:8:75:8 | constructor init of field container | TAINT |
| stl.h:75:8:75:8 | Unknown literal | stl.h:75:8:75:8 | constructor init of field container | TAINT |
| stl.h:75:8:75:8 | this | stl.h:75:8:75:8 | constructor init of field container [pre-this] | |
@@ -3408,6 +3580,9 @@
| string.cpp:121:15:121:15 | ref arg (__begin) | string.cpp:121:15:121:15 | (__begin) | |
| string.cpp:121:15:121:15 | ref arg (__begin) | string.cpp:121:15:121:15 | (__begin) | |
| string.cpp:121:15:121:15 | ref arg (__begin) | string.cpp:121:15:121:15 | (__begin) | |
| string.cpp:121:15:121:15 | ref arg (__begin) | string.cpp:121:15:121:15 | (__begin) | |
| string.cpp:121:15:121:15 | ref arg (__begin) | string.cpp:121:15:121:15 | (__begin) | |
| string.cpp:121:15:121:15 | ref arg (__begin) | string.cpp:121:15:121:15 | (__begin) | |
| string.cpp:121:15:121:15 | ref arg (__range) | string.cpp:121:15:121:15 | (__range) | |
| string.cpp:121:15:121:15 | s | string.cpp:121:15:121:15 | (__range) | |
| string.cpp:121:15:121:15 | s | string.cpp:121:15:121:15 | (__range) | |
@@ -3426,6 +3601,9 @@
| string.cpp:125:61:125:62 | ref arg it | string.cpp:125:61:125:62 | it | |
| string.cpp:125:61:125:62 | ref arg it | string.cpp:126:9:126:10 | it | |
| string.cpp:126:9:126:10 | it | string.cpp:126:8:126:8 | call to operator* | TAINT |
| string.cpp:126:9:126:10 | ref arg it | string.cpp:125:44:125:45 | it | |
| string.cpp:126:9:126:10 | ref arg it | string.cpp:125:61:125:62 | it | |
| string.cpp:126:9:126:10 | ref arg it | string.cpp:126:9:126:10 | it | |
| string.cpp:129:16:129:16 | (__begin) | string.cpp:129:16:129:16 | call to operator* | TAINT |
| string.cpp:129:16:129:16 | (__begin) | string.cpp:129:16:129:16 | call to operator++ | |
| string.cpp:129:16:129:16 | (__end) | string.cpp:129:16:129:16 | call to iterator | |
@@ -3439,6 +3617,9 @@
| string.cpp:129:16:129:16 | ref arg (__begin) | string.cpp:129:16:129:16 | (__begin) | |
| string.cpp:129:16:129:16 | ref arg (__begin) | string.cpp:129:16:129:16 | (__begin) | |
| string.cpp:129:16:129:16 | ref arg (__begin) | string.cpp:129:16:129:16 | (__begin) | |
| string.cpp:129:16:129:16 | ref arg (__begin) | string.cpp:129:16:129:16 | (__begin) | |
| string.cpp:129:16:129:16 | ref arg (__begin) | string.cpp:129:16:129:16 | (__begin) | |
| string.cpp:129:16:129:16 | ref arg (__begin) | string.cpp:129:16:129:16 | (__begin) | |
| string.cpp:129:16:129:16 | ref arg (__range) | string.cpp:129:16:129:16 | (__range) | |
| string.cpp:129:16:129:16 | s | string.cpp:129:16:129:16 | (__range) | |
| string.cpp:129:16:129:16 | s | string.cpp:129:16:129:16 | (__range) | |
@@ -3807,11 +3988,13 @@
| string.cpp:376:31:376:35 | call to begin | string.cpp:378:9:378:13 | iter1 | |
| string.cpp:376:31:376:35 | call to begin | string.cpp:379:8:379:12 | iter1 | |
| string.cpp:378:9:378:13 | iter1 | string.cpp:378:8:378:8 | call to operator* | TAINT |
| string.cpp:378:9:378:13 | ref arg iter1 | string.cpp:379:8:379:12 | iter1 | |
| string.cpp:379:8:379:12 | iter1 | string.cpp:379:13:379:13 | call to operator[] | TAINT |
| string.cpp:380:28:380:29 | s2 | string.cpp:380:31:380:35 | call to begin | TAINT |
| string.cpp:380:31:380:35 | call to begin | string.cpp:382:9:382:13 | iter2 | |
| string.cpp:380:31:380:35 | call to begin | string.cpp:383:8:383:12 | iter2 | |
| string.cpp:382:9:382:13 | iter2 | string.cpp:382:8:382:8 | call to operator* | TAINT |
| string.cpp:382:9:382:13 | ref arg iter2 | string.cpp:383:8:383:12 | iter2 | |
| string.cpp:383:8:383:12 | iter2 | string.cpp:383:13:383:13 | call to operator[] | TAINT |
| string.cpp:388:18:388:24 | hello | string.cpp:388:18:388:25 | call to basic_string | TAINT |
| string.cpp:388:18:388:25 | call to basic_string | string.cpp:391:25:391:26 | s1 | |
@@ -3855,10 +4038,12 @@
| string.cpp:398:8:398:9 | i2 | string.cpp:398:3:398:9 | ... = ... | |
| string.cpp:398:8:398:9 | i2 | string.cpp:399:12:399:13 | i3 | |
| string.cpp:399:10:399:10 | call to operator++ | string.cpp:399:8:399:8 | call to operator* | TAINT |
| string.cpp:399:10:399:10 | ref arg call to operator++ | string.cpp:399:12:399:13 | ref arg i3 | |
| string.cpp:399:12:399:13 | i3 | string.cpp:399:10:399:10 | call to operator++ | |
| string.cpp:400:8:400:9 | i2 | string.cpp:400:3:400:9 | ... = ... | |
| string.cpp:400:8:400:9 | i2 | string.cpp:401:12:401:13 | i4 | |
| string.cpp:401:10:401:10 | call to operator-- | string.cpp:401:8:401:8 | call to operator* | TAINT |
| string.cpp:401:10:401:10 | ref arg call to operator-- | string.cpp:401:12:401:13 | ref arg i4 | |
| string.cpp:401:12:401:13 | i4 | string.cpp:401:10:401:10 | call to operator-- | |
| string.cpp:402:8:402:9 | i2 | string.cpp:402:3:402:9 | ... = ... | |
| string.cpp:402:8:402:9 | i2 | string.cpp:403:3:403:4 | i5 | |
@@ -3876,12 +4061,14 @@
| string.cpp:408:8:408:9 | i2 | string.cpp:409:10:409:11 | i7 | |
| string.cpp:409:10:409:11 | i7 | string.cpp:409:12:409:12 | call to operator+= | |
| string.cpp:409:12:409:12 | call to operator+= | string.cpp:409:8:409:8 | call to operator* | TAINT |
| string.cpp:409:14:409:14 | 1 | string.cpp:409:12:409:12 | call to operator+= | |
| string.cpp:409:12:409:12 | ref arg call to operator+= | string.cpp:409:10:409:11 | ref arg i7 | TAINT |
| string.cpp:409:14:409:14 | 1 | string.cpp:409:10:409:11 | ref arg i7 | TAINT |
| string.cpp:410:8:410:9 | i2 | string.cpp:410:3:410:9 | ... = ... | |
| string.cpp:410:8:410:9 | i2 | string.cpp:411:10:411:11 | i8 | |
| string.cpp:411:10:411:11 | i8 | string.cpp:411:12:411:12 | call to operator-= | |
| string.cpp:411:12:411:12 | call to operator-= | string.cpp:411:8:411:8 | call to operator* | TAINT |
| string.cpp:411:14:411:14 | 1 | string.cpp:411:12:411:12 | call to operator-= | |
| string.cpp:411:12:411:12 | ref arg call to operator-= | string.cpp:411:10:411:11 | ref arg i8 | TAINT |
| string.cpp:411:14:411:14 | 1 | string.cpp:411:10:411:11 | ref arg i8 | TAINT |
| string.cpp:413:8:413:9 | s2 | string.cpp:413:11:413:13 | call to end | TAINT |
| string.cpp:413:11:413:13 | call to end | string.cpp:413:3:413:15 | ... = ... | |
| string.cpp:413:11:413:13 | call to end | string.cpp:414:5:414:6 | i9 | |
@@ -6042,6 +6229,22 @@
| taint.cpp:631:6:631:14 | call to _strnextc | taint.cpp:631:2:631:18 | ... = ... | |
| taint.cpp:631:6:631:14 | call to _strnextc | taint.cpp:632:7:632:7 | c | |
| taint.cpp:631:16:631:17 | | taint.cpp:631:6:631:14 | call to _strnextc | TAINT |
| taint.cpp:640:9:640:12 | this | taint.cpp:640:25:640:29 | this | |
| taint.cpp:643:33:643:38 | source | taint.cpp:645:20:645:25 | source | |
| taint.cpp:644:30:644:30 | c | taint.cpp:645:10:645:10 | c | |
| taint.cpp:644:30:644:30 | c | taint.cpp:646:8:646:8 | c | |
| taint.cpp:645:10:645:10 | ref arg c | taint.cpp:646:8:646:8 | c | |
| taint.cpp:645:12:645:15 | call to data | taint.cpp:645:3:645:8 | call to memcpy | |
| taint.cpp:645:20:645:25 | source | taint.cpp:645:3:645:8 | call to memcpy | TAINT |
| taint.cpp:645:20:645:25 | source | taint.cpp:645:12:645:15 | ref arg call to data | TAINT |
| taint.cpp:652:9:652:12 | this | taint.cpp:652:31:652:35 | this | |
| taint.cpp:655:35:655:40 | source | taint.cpp:657:20:657:25 | source | |
| taint.cpp:656:27:656:27 | c | taint.cpp:657:10:657:10 | c | |
| taint.cpp:656:27:656:27 | c | taint.cpp:658:8:658:8 | c | |
| taint.cpp:657:10:657:10 | ref arg c | taint.cpp:658:8:658:8 | c | |
| taint.cpp:657:12:657:15 | call to data | taint.cpp:657:3:657:8 | call to memcpy | |
| taint.cpp:657:20:657:25 | source | taint.cpp:657:3:657:8 | call to memcpy | TAINT |
| taint.cpp:657:20:657:25 | source | taint.cpp:657:12:657:15 | ref arg call to data | TAINT |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
@@ -6063,6 +6266,9 @@
| vector.cpp:19:14:19:14 | ref arg (__begin) | vector.cpp:19:14:19:14 | (__begin) | |
| vector.cpp:19:14:19:14 | ref arg (__begin) | vector.cpp:19:14:19:14 | (__begin) | |
| vector.cpp:19:14:19:14 | ref arg (__begin) | vector.cpp:19:14:19:14 | (__begin) | |
| vector.cpp:19:14:19:14 | ref arg (__begin) | vector.cpp:19:14:19:14 | (__begin) | |
| vector.cpp:19:14:19:14 | ref arg (__begin) | vector.cpp:19:14:19:14 | (__begin) | |
| vector.cpp:19:14:19:14 | ref arg (__begin) | vector.cpp:19:14:19:14 | (__begin) | |
| vector.cpp:19:14:19:14 | ref arg (__range) | vector.cpp:19:14:19:14 | (__range) | |
| vector.cpp:19:14:19:14 | v | vector.cpp:19:14:19:14 | (__range) | |
| vector.cpp:19:14:19:14 | v | vector.cpp:19:14:19:14 | (__range) | |
@@ -6083,6 +6289,9 @@
| vector.cpp:23:66:23:67 | ref arg it | vector.cpp:23:66:23:67 | it | |
| vector.cpp:23:66:23:67 | ref arg it | vector.cpp:24:9:24:10 | it | |
| vector.cpp:24:9:24:10 | it | vector.cpp:24:8:24:8 | call to operator* | TAINT |
| vector.cpp:24:9:24:10 | ref arg it | vector.cpp:23:49:23:50 | it | |
| vector.cpp:24:9:24:10 | ref arg it | vector.cpp:23:66:23:67 | it | |
| vector.cpp:24:9:24:10 | ref arg it | vector.cpp:24:9:24:10 | it | |
| vector.cpp:27:15:27:15 | (__begin) | vector.cpp:27:15:27:15 | call to operator* | TAINT |
| vector.cpp:27:15:27:15 | (__begin) | vector.cpp:27:15:27:15 | call to operator++ | |
| vector.cpp:27:15:27:15 | (__end) | vector.cpp:27:15:27:15 | call to iterator | |
@@ -6096,6 +6305,9 @@
| vector.cpp:27:15:27:15 | ref arg (__begin) | vector.cpp:27:15:27:15 | (__begin) | |
| vector.cpp:27:15:27:15 | ref arg (__begin) | vector.cpp:27:15:27:15 | (__begin) | |
| vector.cpp:27:15:27:15 | ref arg (__begin) | vector.cpp:27:15:27:15 | (__begin) | |
| vector.cpp:27:15:27:15 | ref arg (__begin) | vector.cpp:27:15:27:15 | (__begin) | |
| vector.cpp:27:15:27:15 | ref arg (__begin) | vector.cpp:27:15:27:15 | (__begin) | |
| vector.cpp:27:15:27:15 | ref arg (__begin) | vector.cpp:27:15:27:15 | (__begin) | |
| vector.cpp:27:15:27:15 | ref arg (__range) | vector.cpp:27:15:27:15 | (__range) | |
| vector.cpp:27:15:27:15 | v | vector.cpp:27:15:27:15 | (__range) | |
| vector.cpp:27:15:27:15 | v | vector.cpp:27:15:27:15 | (__range) | |
@@ -7019,16 +7231,20 @@
| vector.cpp:329:62:329:65 | iter | vector.cpp:329:62:329:65 | iter | |
| vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | |
| vector.cpp:330:2:330:2 | call to operator* [post update] | vector.cpp:329:62:329:65 | iter | |
| vector.cpp:330:2:330:2 | call to operator* [post update] | vector.cpp:330:3:330:6 | ref arg iter | TAINT |
| vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | |
| vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT |
| vector.cpp:330:3:330:6 | ref arg iter | vector.cpp:329:62:329:65 | iter | |
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT |
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | |
| vector.cpp:333:64:333:67 | iter | vector.cpp:333:64:333:67 | iter | |
| vector.cpp:333:64:333:67 | iter | vector.cpp:334:3:334:6 | iter | |
| vector.cpp:333:74:333:74 | i | vector.cpp:334:10:334:10 | i | |
| vector.cpp:334:2:334:2 | call to operator* [post update] | vector.cpp:333:64:333:67 | iter | |
| vector.cpp:334:2:334:2 | call to operator* [post update] | vector.cpp:334:3:334:6 | ref arg iter | TAINT |
| vector.cpp:334:2:334:10 | ... = ... | vector.cpp:334:2:334:2 | call to operator* [post update] | |
| vector.cpp:334:3:334:6 | iter | vector.cpp:334:2:334:2 | call to operator* | TAINT |
| vector.cpp:334:3:334:6 | ref arg iter | vector.cpp:333:64:333:67 | iter | |
| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:2 | call to operator* [post update] | TAINT |
| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:10 | ... = ... | |
| vector.cpp:337:38:337:38 | b | vector.cpp:372:5:372:5 | b | |
@@ -7086,6 +7302,7 @@
| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:415:1:415:1 | v1 | |
| vector.cpp:340:34:340:35 | v1 | vector.cpp:340:37:340:41 | call to begin | TAINT |
| vector.cpp:340:37:340:41 | call to begin | vector.cpp:341:3:341:4 | i1 | |
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:341:3:341:4 | ref arg i1 | TAINT |
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:342:7:342:8 | v1 | |
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v1 | |
| vector.cpp:341:2:341:15 | ... = ... | vector.cpp:341:2:341:2 | call to operator* [post update] | |
@@ -7109,10 +7326,14 @@
| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:68:344:69 | it | |
| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:345:4:345:5 | it | |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:344:56:344:57 | v2 | |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:345:4:345:5 | ref arg it | TAINT |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:347:7:347:8 | v2 | |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:415:1:415:1 | v2 | |
| vector.cpp:345:3:345:16 | ... = ... | vector.cpp:345:3:345:3 | call to operator* [post update] | |
| vector.cpp:345:4:345:5 | it | vector.cpp:345:3:345:3 | call to operator* | TAINT |
| vector.cpp:345:4:345:5 | ref arg it | vector.cpp:344:50:344:51 | it | |
| vector.cpp:345:4:345:5 | ref arg it | vector.cpp:344:68:344:69 | it | |
| vector.cpp:345:4:345:5 | ref arg it | vector.cpp:345:4:345:5 | it | |
| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:3 | call to operator* [post update] | TAINT |
| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:16 | ... = ... | |
| vector.cpp:347:7:347:8 | ref arg v2 | vector.cpp:415:1:415:1 | v2 | |
@@ -7128,6 +7349,9 @@
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
| vector.cpp:349:15:349:15 | ref arg (__range) | vector.cpp:349:15:349:15 | (__range) | |
| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | |
| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | |
@@ -7164,15 +7388,18 @@
| vector.cpp:359:34:359:35 | v5 | vector.cpp:359:37:359:41 | call to begin | TAINT |
| vector.cpp:359:37:359:41 | call to begin | vector.cpp:360:3:360:4 | i5 | |
| vector.cpp:359:37:359:41 | call to begin | vector.cpp:362:3:362:4 | i5 | |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:360:3:360:4 | ref arg i5 | TAINT |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:361:7:361:8 | v5 | |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:360:2:360:15 | ... = ... | vector.cpp:360:2:360:2 | call to operator* [post update] | |
| vector.cpp:360:3:360:4 | i5 | vector.cpp:360:2:360:2 | call to operator* | TAINT |
| vector.cpp:360:3:360:4 | ref arg i5 | vector.cpp:362:3:362:4 | i5 | |
| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:2 | call to operator* [post update] | TAINT |
| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:15 | ... = ... | |
| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:362:3:362:4 | ref arg i5 | TAINT |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:362:2:362:8 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | |
@@ -7186,6 +7413,7 @@
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:415:1:415:1 | v6 | |
| vector.cpp:365:34:365:35 | v6 | vector.cpp:365:37:365:41 | call to begin | TAINT |
| vector.cpp:365:37:365:41 | call to begin | vector.cpp:366:3:366:4 | i6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:366:3:366:4 | ref arg i6 | TAINT |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:367:7:367:8 | v6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:368:2:368:3 | v6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:369:7:369:8 | v6 | |
@@ -7209,6 +7437,7 @@
| vector.cpp:371:34:371:35 | v7 | vector.cpp:371:37:371:41 | call to begin | TAINT |
| vector.cpp:371:37:371:41 | call to begin | vector.cpp:373:4:373:5 | i7 | |
| vector.cpp:371:37:371:41 | call to begin | vector.cpp:376:4:376:5 | i7 | |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:373:4:373:5 | ref arg i7 | TAINT |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:374:8:374:9 | v7 | |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:415:1:415:1 | v7 | |
@@ -7218,6 +7447,7 @@
| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:16 | ... = ... | |
| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:376:4:376:5 | ref arg i7 | TAINT |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:377:8:377:9 | v7 | |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:415:1:415:1 | v7 | |
@@ -7234,15 +7464,18 @@
| vector.cpp:381:34:381:35 | v8 | vector.cpp:381:37:381:41 | call to begin | TAINT |
| vector.cpp:381:37:381:41 | call to begin | vector.cpp:382:3:382:4 | i8 | |
| vector.cpp:381:37:381:41 | call to begin | vector.cpp:384:3:384:4 | i8 | |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:382:3:382:4 | ref arg i8 | TAINT |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:383:7:383:8 | v8 | |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:382:2:382:15 | ... = ... | vector.cpp:382:2:382:2 | call to operator* [post update] | |
| vector.cpp:382:3:382:4 | i8 | vector.cpp:382:2:382:2 | call to operator* | TAINT |
| vector.cpp:382:3:382:4 | ref arg i8 | vector.cpp:384:3:384:4 | i8 | |
| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:2 | call to operator* [post update] | TAINT |
| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:15 | ... = ... | |
| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:384:3:384:4 | ref arg i8 | TAINT |
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:384:2:384:8 | ... = ... | vector.cpp:384:2:384:2 | call to operator* [post update] | |
@@ -7255,10 +7488,12 @@
| vector.cpp:387:34:387:35 | v9 | vector.cpp:387:37:387:41 | call to begin | TAINT |
| vector.cpp:387:37:387:41 | call to begin | vector.cpp:389:3:389:4 | i9 | |
| vector.cpp:387:37:387:41 | call to begin | vector.cpp:390:31:390:32 | i9 | |
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:389:3:389:4 | ref arg i9 | TAINT |
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:392:7:392:8 | v9 | |
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v9 | |
| vector.cpp:389:2:389:15 | ... = ... | vector.cpp:389:2:389:2 | call to operator* [post update] | |
| vector.cpp:389:3:389:4 | i9 | vector.cpp:389:2:389:2 | call to operator* | TAINT |
| vector.cpp:389:3:389:4 | ref arg i9 | vector.cpp:390:31:390:32 | i9 | |
| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:2 | call to operator* [post update] | TAINT |
| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:15 | ... = ... | |
| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:392:7:392:8 | v9 | |
@@ -7300,6 +7535,7 @@
| vector.cpp:403:6:403:6 | call to operator++ | vector.cpp:403:2:403:2 | call to operator* | TAINT |
| vector.cpp:403:11:403:11 | 0 | vector.cpp:403:2:403:2 | call to operator* [post update] | TAINT |
| vector.cpp:403:11:403:11 | 0 | vector.cpp:403:2:403:11 | ... = ... | |
| vector.cpp:404:2:404:2 | call to operator* [post update] | vector.cpp:404:3:404:5 | ref arg i12 | TAINT |
| vector.cpp:404:2:404:2 | call to operator* [post update] | vector.cpp:405:7:405:9 | v12 | |
| vector.cpp:404:2:404:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v12 | |
| vector.cpp:404:2:404:16 | ... = ... | vector.cpp:404:2:404:2 | call to operator* [post update] | |
@@ -7481,3 +7717,70 @@
| vector.cpp:496:25:496:30 | call to source | vector.cpp:496:2:496:3 | ref arg v2 | TAINT |
| vector.cpp:496:25:496:30 | call to source | vector.cpp:496:5:496:11 | call to emplace | TAINT |
| vector.cpp:497:7:497:8 | ref arg v2 | vector.cpp:498:1:498:1 | v2 | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:506:8:506:9 | as | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:507:8:507:9 | as | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:509:9:509:10 | as | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:515:8:515:9 | as | |
| vector.cpp:503:20:503:20 | 0 | vector.cpp:503:18:503:21 | {...} | TAINT |
| vector.cpp:506:8:506:9 | as | vector.cpp:506:8:506:12 | access to array | |
| vector.cpp:506:11:506:11 | 1 | vector.cpp:506:8:506:12 | access to array | TAINT |
| vector.cpp:507:8:507:9 | as | vector.cpp:507:8:507:19 | access to array | |
| vector.cpp:507:11:507:16 | call to source | vector.cpp:507:8:507:19 | access to array | TAINT |
| vector.cpp:509:9:509:10 | as | vector.cpp:509:3:509:10 | ... = ... | |
| vector.cpp:509:9:509:10 | as | vector.cpp:510:9:510:11 | ptr | |
| vector.cpp:509:9:509:10 | as | vector.cpp:511:3:511:5 | ptr | |
| vector.cpp:510:9:510:11 | ptr | vector.cpp:510:8:510:11 | * ... | TAINT |
| vector.cpp:511:3:511:5 | ptr | vector.cpp:511:3:511:10 | ... += ... | TAINT |
| vector.cpp:511:3:511:10 | ... += ... | vector.cpp:512:9:512:11 | ptr | |
| vector.cpp:511:3:511:10 | ... += ... | vector.cpp:513:3:513:5 | ptr | |
| vector.cpp:511:10:511:10 | 1 | vector.cpp:511:3:511:10 | ... += ... | TAINT |
| vector.cpp:512:9:512:11 | ptr | vector.cpp:512:8:512:11 | * ... | TAINT |
| vector.cpp:513:3:513:5 | ptr | vector.cpp:513:3:513:17 | ... += ... | TAINT |
| vector.cpp:513:3:513:17 | ... += ... | vector.cpp:514:9:514:11 | ptr | |
| vector.cpp:513:10:513:15 | call to source | vector.cpp:513:3:513:17 | ... += ... | TAINT |
| vector.cpp:514:9:514:11 | ptr | vector.cpp:514:8:514:11 | * ... | TAINT |
| vector.cpp:515:8:515:9 | as | vector.cpp:515:8:515:12 | access to array | |
| vector.cpp:515:11:515:11 | 1 | vector.cpp:515:8:515:12 | access to array | TAINT |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:523:8:523:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:524:8:524:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:526:8:526:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:520:30:520:30 | 0 | vector.cpp:520:25:520:31 | call to vector | TAINT |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:524:8:524:9 | vs | |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:526:8:526:9 | vs | |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:523:8:523:9 | vs | vector.cpp:523:10:523:10 | call to operator[] | TAINT |
| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:526:8:526:9 | vs | |
| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:524:8:524:9 | vs | vector.cpp:524:10:524:10 | call to operator[] | TAINT |
| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:526:8:526:9 | vs | vector.cpp:526:11:526:15 | call to begin | TAINT |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:526:3:526:17 | ... = ... | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:527:9:527:10 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:528:3:528:4 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:529:9:529:10 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:530:3:530:4 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:531:9:531:10 | it | |
| vector.cpp:527:9:527:10 | it | vector.cpp:527:8:527:8 | call to operator* | TAINT |
| vector.cpp:527:9:527:10 | ref arg it | vector.cpp:528:3:528:4 | it | |
| vector.cpp:527:9:527:10 | ref arg it | vector.cpp:529:9:529:10 | it | |
| vector.cpp:527:9:527:10 | ref arg it | vector.cpp:530:3:530:4 | it | |
| vector.cpp:527:9:527:10 | ref arg it | vector.cpp:531:9:531:10 | it | |
| vector.cpp:528:3:528:4 | it | vector.cpp:528:6:528:6 | call to operator+= | |
| vector.cpp:528:3:528:4 | ref arg it | vector.cpp:529:9:529:10 | it | |
| vector.cpp:528:3:528:4 | ref arg it | vector.cpp:530:3:530:4 | it | |
| vector.cpp:528:3:528:4 | ref arg it | vector.cpp:531:9:531:10 | it | |
| vector.cpp:528:9:528:9 | 1 | vector.cpp:528:3:528:4 | ref arg it | TAINT |
| vector.cpp:529:9:529:10 | it | vector.cpp:529:8:529:8 | call to operator* | TAINT |
| vector.cpp:529:9:529:10 | ref arg it | vector.cpp:530:3:530:4 | it | |
| vector.cpp:529:9:529:10 | ref arg it | vector.cpp:531:9:531:10 | it | |
| vector.cpp:530:3:530:4 | it | vector.cpp:530:6:530:6 | call to operator+= | |
| vector.cpp:530:3:530:4 | ref arg it | vector.cpp:531:9:531:10 | it | |
| vector.cpp:530:9:530:14 | call to source | vector.cpp:530:3:530:4 | ref arg it | TAINT |
| vector.cpp:531:9:531:10 | it | vector.cpp:531:8:531:8 | call to operator* | TAINT |
| vector.cpp:532:8:532:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:532:8:532:9 | vs | vector.cpp:532:10:532:10 | call to operator[] | TAINT |

View File

@@ -90,3 +90,34 @@ void test_insert_iterator() {
*i2-- = 0;
sink(c2); // clean
}
void sink(insert_iterator_by_trait);
insert_iterator_by_trait &operator+=(insert_iterator_by_trait &it, int amount);
void test_assign_through_iterator() {
container c1;
insert_iterator_by_trait a, b, c;
a = c1.begin();
b = c1.begin();
*a = source();
sink(a); // $ ast MISSING: ir
c = c1.begin();
sink(b); // MISSING: ast,ir
sink(c); // $ ast MISSING: ir
sink(c1); // $ ast MISSING: ir
}
void test_nonmember_iterator() {
container c1;
insert_iterator_by_trait it;
it = c1.begin();
sink(it);
it += 1;
sink(it);
it += source();
sink(it); // $ ast,ir
sink(c1);
}

View File

@@ -630,4 +630,30 @@ void test__strnextc(const char* source) {
} while(c != '\0');
c = _strnextc("");
sink(c);
}
// --- taint through const specified function ---
class C_no_const_member_function {
char* data_;
public:
char* data() { return data_; }
};
void test_no_const_member(char* source) {
C_no_const_member_function c;
memcpy(c.data(), source, 16);
sink(c.data()); // $ ast MISSING: ir
}
class C_const_member_function {
char* data_;
public:
char* data() const { return data_; }
};
void test_with_const_member(char* source) {
C_const_member_function c;
memcpy(c.data(), source, 16);
sink(c.data()); // $ ast MISSING: ir
}

View File

@@ -496,3 +496,39 @@ void test_vector_emplace() {
v2.emplace(v2.begin(), source());
sink(v2); // $ ast,ir
}
void test_vector_iterator() {
{
// array behaviour, for comparison
short as[100] = {0};
short *ptr;
sink(as[1]);
sink(as[source()]); // $ ast,ir
ptr = as;
sink(*ptr);
ptr += 1;
sink(*ptr);
ptr += source();
sink(*ptr); // $ ast,ir
sink(as[1]);
}
{
// iterator behaviour
std::vector<short> vs(100, 0);
std::vector<short>::iterator it;
sink(vs[1]);
sink(vs[source()]); // $ MISSING: ast,ir
it = vs.begin();
sink(*it);
it += 1;
sink(*it);
it += source();
sink(*it); // $ ast,ir
sink(vs[1]);
}
}

View File

@@ -0,0 +1,3 @@
| test.cpp:48:5:48:10 | call to memset | Call to memset may be deleted by the compiler. |
| test.cpp:79:5:79:10 | call to memset | Call to memset may be deleted by the compiler. |
| test.cpp:208:2:208:7 | call to memset | Call to memset may be deleted by the compiler. |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-014/MemsetMayBeDeleted.ql

View File

@@ -0,0 +1,140 @@
typedef unsigned long long size_t;
void *memset(void *s, int c, unsigned long n);
void *__builtin_memset(void *s, int c, unsigned long n);
typedef int errno_t;
typedef unsigned int rsize_t;
errno_t memset_s(void *dest, rsize_t destsz, int ch, rsize_t count);
char *strcpy(char *dest, const char *src);
extern void use_pw(char *pw);
#define PW_SIZE 32
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): deleted
int func1(void) {
char pw1[PW_SIZE];
use_pw(pw1);
memset(pw1, 0, PW_SIZE); // BAD [NOT DETECTED]
return 0;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): not deleted
int func1a(void) {
char pw1a[PW_SIZE];
use_pw(pw1a);
__builtin_memset(pw1a, 0, PW_SIZE); // BAD [NOT DETECTED]
return 0;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): deleted
char *func1b(void) {
char pw1b[PW_SIZE];
use_pw(pw1b);
memset(pw1b, 0, PW_SIZE); // BAD [NOT DETECTED]
pw1b[0] = pw1b[3] = 'a';
return 0;
}
// x86-64 gcc 9.2: not deleted
// x86-64 clang 9.0.0: not deleted
// x64 msvc v19.14 (WINE): not deleted
int func1c(char pw1c[PW_SIZE]) {
use_pw(pw1c);
memset(pw1c, 0, PW_SIZE); // GOOD
return 0;
}
// x86-64 gcc 9.2: not deleted
// x86-64 clang 9.0.0: not deleted
// x64 msvc v19.14 (WINE): not deleted
char pw1d[PW_SIZE];
int func1d() {
use_pw(pw1d);
memset(pw1d, 0, PW_SIZE); // GOOD
return 0;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): deleted
char *func2(void) {
char pw2[PW_SIZE];
use_pw(pw2);
memset(pw2, 1, PW_SIZE); // BAD [NOT DETECTED]
return pw2;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): partially deleted
int func3(void) {
char pw3[PW_SIZE];
use_pw(pw3);
memset(pw3, 4, PW_SIZE); // BAD [NOT DETECTED]
return pw3[2];
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): not deleted
int func4(void) {
char pw1a[PW_SIZE];
use_pw(pw1a);
__builtin_memset(pw1a + 3, 0, PW_SIZE - 3); // BAD [NOT DETECTED]
return 0;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): not deleted
int func6(void) {
char pw1a[PW_SIZE];
use_pw(pw1a);
__builtin_memset(&pw1a[3], 0, PW_SIZE - 3); // BAD [NOT DETECTED]
return pw1a[2];
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): not deleted
int func5(void) {
char pw1a[PW_SIZE];
use_pw(pw1a);
__builtin_memset(pw1a + 3, 0, PW_SIZE - 4); // GOOD
return pw1a[4];
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): not deleted
int func7(void) {
char pw1a[PW_SIZE];
use_pw(pw1a);
__builtin_memset(&pw1a[3], 0, PW_SIZE - 5); // BAD [NOT DETECTED]
return 0;
}
// x86-64 gcc 9.2: not deleted
// x86-64 clang 9.0.0: not deleted
// x64 msvc v19.14 (WINE): not deleted
int func8(void) {
char pw1a[PW_SIZE];
use_pw(pw1a);
__builtin_memset(pw1a + pw1a[3], 0, PW_SIZE - 4); // GOOD
return pw1a[4];
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.14 (WINE): deleted
char *func9(void) {
char pw1[PW_SIZE];
use_pw(pw1);
memset(pw1, 0, PW_SIZE); // BAD [NOT DETECTED]
return 0;
}

View File

@@ -0,0 +1,401 @@
extern "C" {
typedef unsigned long long size_t;
void *memset(void *s, int c, unsigned long n);
void *__builtin_memset(void *s, int c, unsigned long n);
typedef int errno_t;
typedef unsigned int rsize_t;
errno_t memset_s(void *dest, rsize_t destsz, int ch, rsize_t count);
char *strcpy(char *dest, const char *src);
void *memcpy(void *dest, const void *src, unsigned long n);
void *malloc(unsigned long size);
void free(void *ptr);
extern void use_pw(char *pw);
int printf(const char* format, ...);
char* gets(char * str);
}
#define PW_SIZE 32
struct mem {
int a;
char b[PW_SIZE];
int c;
};
// x86-64 gcc 9.2: not deleted
// x86-64 clang 9.0.0: not deleted
// x64 msvc v19.22: not deleted
void func(char buff[128], unsigned long long sz) {
gets(buff);
memset(buff, 0, PW_SIZE); // GOOD
}
// x86-64 gcc 9.2: not deleted
// x86-64 clang 9.0.0: not deleted
// x64 msvc v19.22: not deleted
char *func2(char buff[128], unsigned long long sz) {
gets(buff);
memset(buff, 0, PW_SIZE); // GOOD
return buff;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: deleted
void func3(unsigned long long sz) {
char buff[128];
gets(buff);
memset(buff, 0, PW_SIZE); // BAD
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: deleted
void func4(unsigned long long sz) {
char buff[128];
gets(buff);
memset(buff, 0, PW_SIZE); // BAD [NOT DETECTED]
strcpy(buff, "Hello");
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: deleted
void func5(unsigned long long sz) {
char buff[128];
gets(buff);
memset(buff, 0, PW_SIZE); // BAD [NOT DETECTED]
if (sz > 5) {
strcpy(buff, "Hello");
}
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: deleted
void func6(unsigned long long sz) {
struct mem m;
gets(m.b);
memset(&m, 0, PW_SIZE); // BAD
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: deleted
void func7(unsigned long long sz) {
struct mem m;
gets(m.b);
memset(&m, 0, PW_SIZE); // BAD [NOT DETECTED]
m.a = 15;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: not deleted
void func8(unsigned long long sz) {
struct mem *m = (struct mem *)malloc(sizeof(struct mem));
gets(m->b);
memset(m, 0, PW_SIZE); // BAD [NOT DETECTED]
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: not deleted
void func9(unsigned long long sz) {
struct mem *m = (struct mem *)malloc(sizeof(struct mem));
gets(m->b);
memset(m, 0, PW_SIZE); // BAD [NOT DETECTED]
free(m);
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: not deleted
void func10(unsigned long long sz) {
struct mem *m = (struct mem *)malloc(sizeof(struct mem));
gets(m->b);
memset(m, 0, PW_SIZE); // BAD [NOT DETECTED]
m->a = sz;
m->c = m->a + 1;
}
// x86-64 gcc 9.2: deleted
// x86-64 clang 9.0.0: deleted
// x64 msvc v19.22: not deleted
void func11(unsigned long long sz) {
struct mem *m = (struct mem *)malloc(sizeof(struct mem));
gets(m->b);
::memset(m, 0, PW_SIZE); // BAD [NOT DETECTED]
if (sz > 5) {
strcpy(m->b, "Hello");
}
}
// x86-64 gcc 9.2: not deleted
// x86-64 clang 9.0.0: not deleted
// x64 msvc v19.22: not deleted
int func12(unsigned long long sz) {
struct mem *m = (struct mem *)malloc(sizeof(struct mem));
gets(m->b);
memset(m, 0, sz); // GOOD
return m->c;
}
int funcN1() {
char pw[PW_SIZE];
gets(pw);
char *pw_ptr = pw;
memset(pw, 0, PW_SIZE); // GOOD
use_pw(pw_ptr);
return 0;
}
char pw_global[PW_SIZE];
int funcN2() {
gets(pw_global);
use_pw(pw_global);
memset(pw_global, 0, PW_SIZE); // GOOD
return 0;
}
int funcN3(unsigned long long sz) {
struct mem m;
gets(m.b);
memset(&m, 0, sizeof(m)); // GOOD
return m.a;
}
void funcN(int num) {
char pw[PW_SIZE];
int i;
for (i = 0; i < num; i++)
{
gets(pw);
use_pw(pw);
memset(pw, 0, PW_SIZE); // GOOD
}
}
class MyClass
{
public:
void set(int _x) {
x = _x;
}
int get()
{
return x;
}
void clear1() {
memset(&x, 0, sizeof(x)); // GOOD
}
void clear2() {
memset(&(this->x), 0, sizeof(this->x)); // GOOD
}
private:
int x;
};
void badFunc0_0(){
unsigned char buff1[PW_SIZE];
for(int i = 0; i < PW_SIZE; i++) {
buff1[i] = 13;
}
memset(buff1, 0, PW_SIZE); // BAD
}
void nobadFunc1_0() {
char* buff1 = (char *) malloc(PW_SIZE);
gets(buff1);
memset(buff1, 0, PW_SIZE); // BAD [NOT DETECTED]
}
void badFunc1_0(){
char * buff1 = (char *) malloc(PW_SIZE);
gets(buff1);
memset(buff1, 0, PW_SIZE); // BAD [NOT DETECTED]
free(buff1);
}
void badFunc1_1(){
unsigned char buff1[PW_SIZE];
for(int i = 0; i < PW_SIZE; i++) {
buff1[i] = 'a' + i;
}
memset(buff1, 0, PW_SIZE); // BAD [NOT DETECTED]
free(buff1);
}
void nobadFunc2_0_0(){
unsigned char buff1[PW_SIZE];
buff1[sizeof(buff1) - 1] = '\0';
memset(buff1, 0, PW_SIZE); // GOOD
printf("%s", buff1);
}
void nobadFunc2_0_1(){
char buff1[PW_SIZE];
gets(buff1);
memset(buff1, '\0', sizeof(buff1));
memset(buff1, 0, PW_SIZE); // GOOD
printf("%s", buff1 + 3);
}
void nobadFunc2_0_2(){
char buff1[PW_SIZE];
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
printf("%c", *buff1);
}
void nobadFunc2_0_3(char ch){
unsigned char buff1[PW_SIZE];
for(int i = 0; i < PW_SIZE; i++) {
buff1[i] = ch;
}
memset(buff1, 0, PW_SIZE); // GOOD
printf("%c", *(buff1 + 3));
}
char * nobadFunc2_0_4(){
char buff1[PW_SIZE];
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
return buff1;
}
char * nobadFunc2_0_5(){
char buff1[PW_SIZE];
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
return buff1+3;
}
unsigned char nobadFunc2_0_6(){
unsigned char buff1[PW_SIZE];
buff1[0] = 'z';
int i;
memset(buff1, 0, PW_SIZE); // GOOD
return *buff1;
}
unsigned char nobadFunc2_0_7(){
char buff1[PW_SIZE];
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
return *(buff1 + 3);
}
bool nobadFunc2_1_0(unsigned char ch){
char buff1[PW_SIZE];
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
if(*buff1 == ch) { return true; }
return false;
}
void nobadFunc2_1_2(){
char buff1[PW_SIZE];
gets(buff1);
memset(buff1, 0, PW_SIZE); // BAD [NOT DETECTED]
buff1[2] = 5;
}
void nobadFunc3_0(char * buffAll){
char * buff1 = buffAll;
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc3_1(unsigned char * buffAll){
unsigned char * buff1 = buffAll + 3;
memset(buff1, 0, PW_SIZE); // GOOD
}
struct buffers
{
char buff1[50];
unsigned char *buff2;
};
void nobadFunc3_2(struct buffers buffAll) {
char * buff1 = buffAll.buff1;
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc3_3(struct buffers buffAll) {
unsigned char * buff1 = buffAll.buff2;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc3_4(struct buffers buffAll) {
unsigned char * buff1 = buffAll.buff2 + 3;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc3_5(struct buffers * buffAll) {
char * buff1 = buffAll->buff1;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc3_6(struct buffers *buffAll){
unsigned char * buff1 = buffAll->buff2;
memset(buff1, 0, PW_SIZE); // GOOD
}
char * globalBuff;
void nobadFunc4(){
char * buff1 = globalBuff;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc4_0(){
char * buff1 = globalBuff;
gets(buff1);
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc4_1(){
char * buff1 = globalBuff + 3;
memset(buff1, 0, PW_SIZE); // GOOD
}
buffers globalBuff1, *globalBuff2;
void nobadFunc4_2(){
char * buff1 = globalBuff1.buff1;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc4_3(){
unsigned char * buff1 = globalBuff1.buff2;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc4_4(){
unsigned char * buff1 = globalBuff1.buff2+3;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc4_5(){
char * buff1 = globalBuff2->buff1;
memset(buff1, 0, PW_SIZE); // GOOD
}
void nobadFunc4_6(){
unsigned char * buff1 = globalBuff2->buff2;
memset(buff1, 0, PW_SIZE); // GOOD
}
extern void use_byte(unsigned char);
void test_static_func() {
static unsigned char buffer[PW_SIZE] = {0};
use_byte(buffer[0]);
memset(buffer, 42, sizeof(buffer)); // GOOD
}

View File

@@ -8,14 +8,14 @@ edges
| search.c:22:24:22:28 | *query | search.c:23:39:23:43 | query |
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
| search.c:41:21:41:26 | call to getenv | search.c:14:24:14:28 | *query |
| search.c:41:21:41:26 | call to getenv | search.c:14:24:14:28 | *query |
| search.c:41:21:41:26 | call to getenv | search.c:14:24:14:28 | query |
| search.c:41:21:41:26 | call to getenv | search.c:14:24:14:28 | query |
| search.c:41:21:41:26 | call to getenv | search.c:22:24:22:28 | *query |
| search.c:41:21:41:26 | call to getenv | search.c:22:24:22:28 | *query |
| search.c:41:21:41:26 | call to getenv | search.c:22:24:22:28 | query |
| search.c:41:21:41:26 | call to getenv | search.c:22:24:22:28 | query |
| search.c:51:21:51:26 | call to getenv | search.c:14:24:14:28 | *query |
| search.c:51:21:51:26 | call to getenv | search.c:14:24:14:28 | *query |
| search.c:51:21:51:26 | call to getenv | search.c:14:24:14:28 | query |
| search.c:51:21:51:26 | call to getenv | search.c:14:24:14:28 | query |
| search.c:51:21:51:26 | call to getenv | search.c:22:24:22:28 | *query |
| search.c:51:21:51:26 | call to getenv | search.c:22:24:22:28 | *query |
| search.c:51:21:51:26 | call to getenv | search.c:22:24:22:28 | query |
| search.c:51:21:51:26 | call to getenv | search.c:22:24:22:28 | query |
nodes
| search.c:14:24:14:28 | *query | semmle.label | *query |
| search.c:14:24:14:28 | query | semmle.label | query |
@@ -29,12 +29,12 @@ nodes
| search.c:23:39:23:43 | query | semmle.label | query |
| search.c:23:39:23:43 | query | semmle.label | query |
| search.c:23:39:23:43 | query | semmle.label | query |
| search.c:41:21:41:26 | call to getenv | semmle.label | call to getenv |
| search.c:41:21:41:26 | call to getenv | semmle.label | call to getenv |
| search.c:45:5:45:15 | Argument 0 | semmle.label | Argument 0 |
| search.c:45:17:45:25 | Argument 0 indirection | semmle.label | Argument 0 indirection |
| search.c:47:5:47:15 | Argument 0 | semmle.label | Argument 0 |
| search.c:47:17:47:25 | Argument 0 indirection | semmle.label | Argument 0 indirection |
| search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv |
| search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv |
| search.c:55:5:55:15 | Argument 0 | semmle.label | Argument 0 |
| search.c:55:17:55:25 | Argument 0 indirection | semmle.label | Argument 0 indirection |
| search.c:57:5:57:15 | Argument 0 | semmle.label | Argument 0 |
| search.c:57:17:57:25 | Argument 0 indirection | semmle.label | Argument 0 indirection |
#select
| search.c:17:8:17:12 | query | search.c:41:21:41:26 | call to getenv | search.c:17:8:17:12 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |
| search.c:23:39:23:43 | query | search.c:41:21:41:26 | call to getenv | search.c:23:39:23:43 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |
| search.c:17:8:17:12 | query | search.c:51:21:51:26 | call to getenv | search.c:17:8:17:12 | query | Cross-site scripting vulnerability due to $@. | search.c:51:21:51:26 | call to getenv | this query data |
| search.c:23:39:23:43 | query | search.c:51:21:51:26 | call to getenv | search.c:23:39:23:43 | query | Cross-site scripting vulnerability due to $@. | search.c:51:21:51:26 | call to getenv | this query data |

View File

@@ -26,7 +26,7 @@ void bad_server2(char* query) {
puts(do_search(query));
}
void good_server(char* query) {
void good_server1(char* query) {
puts("<p>Query results for ");
// GOOD: Escape HTML characters before adding to a page
char* query_escaped = escape_html(query);
@@ -37,14 +37,25 @@ void good_server(char* query) {
puts(do_search(query));
}
int main(int argc, char** argv) {
char* raw_query = getenv("QUERY_STRING");
if (strcmp("good", argv[0]) == 0) {
good_server(raw_query);
} else if (strcmp("bad1", argv[0]) == 0) {
bad_server1(raw_query);
} else {
bad_server2(raw_query);
}
int sscanf(const char *s, const char *format, ...);
void good_server2(char* query) {
puts("<p>Query results for ");
// GOOD: Only an integer is added to the page.
int i = 0;
sscanf(query, "value=%i", &i);
printf("\n<p>%i</p>\n", i);
}
int main(int argc, char** argv) {
char* raw_query = getenv("QUERY_STRING");
if (strcmp("good1", argv[0]) == 0) {
good_server1(raw_query);
} else if (strcmp("bad1", argv[0]) == 0) {
bad_server1(raw_query);
} else if (strcmp("bad2", argv[0]) == 0) {
bad_server2(raw_query);
} else if (strcmp("good2", argv[0]) == 0) {
good_server2(raw_query);
}
}

View File

@@ -45,6 +45,7 @@ namespace Semmle.Autobuild.Shared
private readonly SolutionFile? solution;
private readonly IEnumerable<Project> includedProjects;
public override IEnumerable<IProjectOrSolution> IncludedProjects => includedProjects;
public IEnumerable<SolutionConfigurationInSolution> Configurations =>
@@ -84,8 +85,12 @@ namespace Semmle.Autobuild.Shared
.ToArray();
}
private IEnumerable<Version> ToolsVersions => includedProjects.Where(p => p.ValidToolsVersion).Select(p => p.ToolsVersion);
private IEnumerable<Version> ToolsVersions => includedProjects
.Where(p => p.ValidToolsVersion)
.Select(p => p.ToolsVersion);
public Version ToolsVersion => ToolsVersions.Any() ? ToolsVersions.Max() : new Version();
public Version ToolsVersion => ToolsVersions.Any()
? ToolsVersions.Max()
: new Version();
}
}

View File

@@ -0,0 +1,3 @@
lgtm,codescanning
* The underlying methods of `foreach` statements are now explicitly extracted and
they are made available on the `ForeachStmt` class.

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* C# 9 `with` expressions are now extracted. Data flow support has been added to
handle flow through `with` expressions and also from `record` constructor arguments
to its properties.

View File

@@ -163,7 +163,7 @@ namespace Semmle.Extraction.CIL.Driver
}
private readonly HashSet<string> filesAnalyzed = new HashSet<string>();
public HashSet<AssemblyName> MissingReferences {get;} = new HashSet<AssemblyName>();
public HashSet<AssemblyName> MissingReferences { get; } = new HashSet<AssemblyName>();
}
/// <summary>

View File

@@ -24,7 +24,7 @@ namespace Semmle.Extraction.CIL.Driver
{
var sw = new Stopwatch();
sw.Start();
Entities.Assembly.ExtractCIL(layout, assemblyPath, logger, nocache, extractPdbs, trapCompression, out _, out _);
Analyser.ExtractCIL(layout, assemblyPath, logger, nocache, extractPdbs, trapCompression, out _, out _);
sw.Stop();
logger.Log(Severity.Info, " {0} ({1})", assemblyPath, sw.Elapsed);
}

View File

@@ -0,0 +1,53 @@
using Semmle.Util.Logging;
using System;
using Semmle.Util;
using Semmle.Extraction.CIL.Entities;
namespace Semmle.Extraction.CIL
{
public static class Analyser
{
private static void ExtractCIL(Extractor extractor, TrapWriter trapWriter, bool extractPdbs)
{
using var cilContext = new Context(extractor, trapWriter, extractor.OutputPath, extractPdbs);
cilContext.Populate(new Assembly(cilContext));
cilContext.PopulateAll();
}
/// <summary>
/// Main entry point to the CIL extractor.
/// Call this to extract a given assembly.
/// </summary>
/// <param name="layout">The trap layout.</param>
/// <param name="assemblyPath">The full path of the assembly to extract.</param>
/// <param name="logger">The logger.</param>
/// <param name="nocache">True to overwrite existing trap file.</param>
/// <param name="extractPdbs">Whether to extract PDBs.</param>
/// <param name="trapFile">The path of the trap file.</param>
/// <param name="extracted">Whether the file was extracted (false=cached).</param>
public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs, TrapWriter.CompressionMode trapCompression, out string trapFile, out bool extracted)
{
trapFile = "";
extracted = false;
try
{
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
var pathTransformer = new PathTransformer(canonicalPathCache);
var extractor = new Extractor(false, assemblyPath, logger, pathTransformer);
var transformedAssemblyPath = pathTransformer.Transform(assemblyPath);
var project = layout.LookupProjectOrDefault(transformedAssemblyPath);
using var trapWriter = project.CreateTrapWriter(logger, transformedAssemblyPath.WithSuffix(".cil"), trapCompression, discardDuplicates: true);
trapFile = trapWriter.TrapFile;
if (nocache || !System.IO.File.Exists(trapFile))
{
ExtractCIL(extractor, trapWriter, extractPdbs);
extracted = true;
}
}
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{
logger.Log(Severity.Error, string.Format("Exception extracting {0}: {1}", assemblyPath, ex));
}
}
}
}

View File

@@ -9,11 +9,11 @@ namespace Semmle.Extraction.CIL
/// <summary>
/// Provides methods for creating and caching various entities.
/// </summary>
public sealed partial class Context
internal sealed partial class Context
{
private readonly Dictionary<object, Label> ids = new Dictionary<object, Label>();
public T Populate<T>(T e) where T : IExtractedEntity
internal T Populate<T>(T e) where T : IExtractedEntity
{
if (e.Label.Valid)
{
@@ -27,10 +27,10 @@ namespace Semmle.Extraction.CIL
}
else
{
e.Label = Cx.GetNewLabel();
Cx.DefineLabel(e, Cx.TrapWriter.Writer, Cx.Extractor);
e.Label = GetNewLabel();
DefineLabel(e);
ids.Add(e, e.Label);
Cx.PopulateLater(() =>
PopulateLater(() =>
{
foreach (var c in e.Contents)
c.Extract(this);
@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CIL
if (debugLabels.TryGetValue(id, out var previousEntity))
{
Cx.Extractor.Message(new Message("Duplicate trap ID", id, null, severity: Util.Logging.Severity.Warning));
Extractor.Message(new Message("Duplicate trap ID", id, null, severity: Util.Logging.Severity.Warning));
}
else
{
@@ -74,9 +74,9 @@ namespace Semmle.Extraction.CIL
{
e = new PrimitiveType(this, code)
{
Label = Cx.GetNewLabel()
Label = GetNewLabel()
};
Cx.DefineLabel(e, Cx.TrapWriter.Writer, Cx.Extractor);
DefineLabel(e);
primitiveTypes[(int)code] = e;
}
@@ -95,11 +95,11 @@ namespace Semmle.Extraction.CIL
/// <param name="h">The handle of the entity.</param>
/// <param name="genericContext">The generic context.</param>
/// <returns></returns>
public IExtractedEntity CreateGeneric(GenericContext genericContext, Handle h) => genericHandleFactory[genericContext, h];
public IExtractedEntity CreateGeneric(IGenericContext genericContext, Handle h) => genericHandleFactory[genericContext, h];
private readonly GenericContext defaultGenericContext;
private readonly IGenericContext defaultGenericContext;
private IExtractedEntity CreateGenericHandle(GenericContext gc, Handle handle)
private IExtractedEntity CreateGenericHandle(IGenericContext gc, Handle handle)
{
IExtractedEntity entity;
switch (handle.Kind)
@@ -136,7 +136,7 @@ namespace Semmle.Extraction.CIL
return entity;
}
private IExtractedEntity Create(GenericContext gc, MemberReferenceHandle handle)
private IExtractedEntity Create(IGenericContext gc, MemberReferenceHandle handle)
{
var mr = MdReader.GetMemberReference(handle);
switch (mr.GetKind())
@@ -228,7 +228,7 @@ namespace Semmle.Extraction.CIL
#endregion
private readonly CachedFunction<GenericContext, Handle, IExtractedEntity> genericHandleFactory;
private readonly CachedFunction<IGenericContext, Handle, IExtractedEntity> genericHandleFactory;
/// <summary>
/// Gets the short name of a member, without the preceding interface qualifier.

View File

@@ -10,12 +10,10 @@ namespace Semmle.Extraction.CIL
/// Adds additional context that is specific for CIL extraction.
/// One context = one DLL/EXE.
/// </summary>
public sealed partial class Context : IDisposable
internal sealed partial class Context : Extraction.Context, IDisposable
{
private readonly FileStream stream;
private Entities.Assembly? assemblyNull;
public Extraction.Context Cx { get; }
public MetadataReader MdReader { get; }
public PEReader PeReader { get; }
public string AssemblyPath { get; }
@@ -26,9 +24,9 @@ namespace Semmle.Extraction.CIL
}
public PDB.IPdb? Pdb { get; }
public Context(Extraction.Context cx, string assemblyPath, bool extractPdbs)
public Context(Extractor extractor, TrapWriter trapWriter, string assemblyPath, bool extractPdbs)
: base(extractor, trapWriter)
{
this.Cx = cx;
this.AssemblyPath = assemblyPath;
stream = File.OpenRead(assemblyPath);
PeReader = new PEReader(stream, PEStreamOptions.PrefetchEntireImage);
@@ -37,7 +35,7 @@ namespace Semmle.Extraction.CIL
globalNamespace = new Lazy<Entities.Namespace>(() => Populate(new Entities.Namespace(this, "", null)));
systemNamespace = new Lazy<Entities.Namespace>(() => Populate(new Entities.Namespace(this, "System")));
genericHandleFactory = new CachedFunction<GenericContext, Handle, IExtractedEntity>(CreateGenericHandle);
genericHandleFactory = new CachedFunction<IGenericContext, Handle, IExtractedEntity>(CreateGenericHandle);
namespaceFactory = new CachedFunction<StringHandle, Entities.Namespace>(n => CreateNamespace(MdReader.GetString(n)));
namespaceDefinitionFactory = new CachedFunction<NamespaceDefinitionHandle, Entities.Namespace>(CreateNamespace);
sourceFiles = new CachedFunction<PDB.ISourceFile, Entities.PdbSourceFile>(path => new Entities.PdbSourceFile(this, path));
@@ -51,7 +49,7 @@ namespace Semmle.Extraction.CIL
Pdb = PDB.PdbReader.Create(assemblyPath, PeReader);
if (Pdb != null)
{
cx.Extractor.Logger.Log(Util.Logging.Severity.Info, string.Format("Found PDB information for {0}", assemblyPath));
Extractor.Logger.Log(Util.Logging.Severity.Info, string.Format("Found PDB information for {0}", assemblyPath));
}
}
}

View File

@@ -5,14 +5,18 @@ namespace Semmle.Extraction.CIL
/// <summary>
/// A generic context which does not contain any type parameters.
/// </summary>
public class EmptyContext : GenericContext
internal class EmptyContext : IGenericContext
{
public EmptyContext(Context cx) : base(cx)
public EmptyContext(Context cx)
{
Cx = cx;
}
public override IEnumerable<Entities.Type> TypeParameters { get { yield break; } }
public Context Cx { get; }
public IEnumerable<Entities.Type> TypeParameters { get { yield break; } }
public IEnumerable<Entities.Type> MethodParameters { get { yield break; } }
public override IEnumerable<Entities.Type> MethodParameters { get { yield break; } }
}
}

View File

@@ -1,18 +1,15 @@
using System.Reflection;
using System.Globalization;
using System.Collections.Generic;
using Semmle.Util.Logging;
using System;
using Semmle.Extraction.Entities;
using System.IO;
using Semmle.Util;
namespace Semmle.Extraction.CIL.Entities
{
/// <summary>
/// An assembly to extract.
/// </summary>
public class Assembly : LabelledEntity, ILocation
internal class Assembly : LabelledEntity, ILocation
{
private readonly File file;
private readonly AssemblyName assemblyName;
@@ -40,6 +37,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(FullName);
trapFile.Write("#file:///");
trapFile.Write(Cx.AssemblyPath.Replace("\\", "/"));
trapFile.Write(";assembly");
}
public override bool Equals(object? obj)
@@ -49,8 +47,6 @@ namespace Semmle.Extraction.CIL.Entities
public override int GetHashCode() => 7 * file.GetHashCode();
public override string IdSuffix => ";assembly";
private string FullName => assemblyName.GetPublicKey() is null ? assemblyName.FullName + ", PublicKeyToken=null" : assemblyName.FullName;
public override IEnumerable<IExtractionProduct> Contents
@@ -77,7 +73,7 @@ namespace Semmle.Extraction.CIL.Entities
}
catch (InternalError e)
{
Cx.Cx.ExtractionError("Error processing type definition", e.Message, GeneratedLocation.Create(Cx.Cx), e.StackTrace);
Cx.ExtractionError("Error processing type definition", e.Message, GeneratedLocation.Create(Cx), e.StackTrace);
}
// Limitation of C#: Cannot yield return inside a try-catch.
@@ -94,7 +90,7 @@ namespace Semmle.Extraction.CIL.Entities
}
catch (InternalError e)
{
Cx.Cx.ExtractionError("Error processing bytecode", e.Message, GeneratedLocation.Create(Cx.Cx), e.StackTrace);
Cx.ExtractionError("Error processing bytecode", e.Message, GeneratedLocation.Create(Cx), e.StackTrace);
}
if (product != null)
@@ -102,49 +98,5 @@ namespace Semmle.Extraction.CIL.Entities
}
}
}
private static void ExtractCIL(Extraction.Context cx, string assemblyPath, bool extractPdbs)
{
using var cilContext = new Context(cx, assemblyPath, extractPdbs);
cilContext.Populate(new Assembly(cilContext));
cilContext.Cx.PopulateAll();
}
/// <summary>
/// Main entry point to the CIL extractor.
/// Call this to extract a given assembly.
/// </summary>
/// <param name="layout">The trap layout.</param>
/// <param name="assemblyPath">The full path of the assembly to extract.</param>
/// <param name="logger">The logger.</param>
/// <param name="nocache">True to overwrite existing trap file.</param>
/// <param name="extractPdbs">Whether to extract PDBs.</param>
/// <param name="trapFile">The path of the trap file.</param>
/// <param name="extracted">Whether the file was extracted (false=cached).</param>
public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs, TrapWriter.CompressionMode trapCompression, out string trapFile, out bool extracted)
{
trapFile = "";
extracted = false;
try
{
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
var pathTransformer = new PathTransformer(canonicalPathCache);
var extractor = new Extractor(false, assemblyPath, logger, pathTransformer);
var transformedAssemblyPath = pathTransformer.Transform(assemblyPath);
var project = layout.LookupProjectOrDefault(transformedAssemblyPath);
using var trapWriter = project.CreateTrapWriter(logger, transformedAssemblyPath.WithSuffix(".cil"), trapCompression, discardDuplicates: true);
trapFile = trapWriter.TrapFile;
if (nocache || !System.IO.File.Exists(trapFile))
{
var cx = extractor.CreateContext(null, trapWriter, null, false);
ExtractCIL(cx, assemblyPath, extractPdbs);
extracted = true;
}
}
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{
logger.Log(Severity.Error, string.Format("Exception extracting {0}: {1}", assemblyPath, ex));
}
}
}
}

View File

@@ -12,9 +12,9 @@ namespace Semmle.Extraction.CIL.Entities
{
private readonly CustomAttributeHandle handle;
private readonly CustomAttribute attrib;
private readonly IEntity @object;
private readonly IExtractedEntity @object;
public Attribute(Context cx, IEntity @object, CustomAttributeHandle handle) : base(cx)
public Attribute(Context cx, IExtractedEntity @object, CustomAttributeHandle handle) : base(cx)
{
attrib = cx.MdReader.GetCustomAttribute(handle);
this.handle = handle;
@@ -45,7 +45,7 @@ namespace Semmle.Extraction.CIL.Entities
}
catch
{
Cx.Cx.Extractor.Logger.Log(Util.Logging.Severity.Info,
Cx.Extractor.Logger.Log(Util.Logging.Severity.Info,
$"Attribute decoding is partial. Decoding attribute {constructor.DeclaringType.GetQualifiedName()} failed on {@object}.");
yield break;
}
@@ -80,7 +80,7 @@ namespace Semmle.Extraction.CIL.Entities
return value?.ToString() ?? "null";
}
public static IEnumerable<IExtractionProduct> Populate(Context cx, IEntity @object, CustomAttributeHandleCollection attributes)
public static IEnumerable<IExtractionProduct> Populate(Context cx, IExtractedEntity @object, CustomAttributeHandleCollection attributes)
{
foreach (var attrib in attributes)
{

View File

@@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace Semmle.Extraction.CIL
{
/// <summary>
/// A CIL entity which has been extracted.
/// </summary>
internal interface IExtractedEntity : IExtractionProduct, IEntity
{
/// <summary>
/// The contents of the entity.
/// </summary>
IEnumerable<IExtractionProduct> Contents { get; }
}
}

View File

@@ -0,0 +1,24 @@
namespace Semmle.Extraction.CIL
{
/// <summary>
/// Something that is extracted from an entity.
/// </summary>
///
/// <remarks>
/// The extraction algorithm proceeds as follows:
/// - Construct entity
/// - Call Extract()
/// - IExtractedEntity check if already extracted
/// - Enumerate Contents to produce more extraction products
/// - Extract these until there is nothing left to extract
/// </remarks>
internal interface IExtractionProduct
{
/// <summary>
/// Perform further extraction/population of this item as necessary.
/// </summary>
///
/// <param name="cx">The extraction context.</param>
void Extract(Context cx);
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace Semmle.Extraction.CIL
{
/// <summary>
/// When we decode a type/method signature, we need access to
/// generic parameters.
/// </summary>
internal interface IGenericContext
{
Context Cx { get; }
/// <summary>
/// The list of generic type parameters/arguments, including type parameters/arguments of
/// containing types.
/// </summary>
IEnumerable<Entities.Type> TypeParameters { get; }
/// <summary>
/// The list of generic method parameters/arguments.
/// </summary>
IEnumerable<Entities.Type> MethodParameters { get; }
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Semmle.Extraction.CIL
{
/// <summary>
/// An entity that needs to be populated during extraction.
/// This assigns a key and optionally extracts its contents.
/// </summary>
internal abstract class LabelledEntity : Extraction.LabelledEntity, IExtractedEntity
{
// todo: with .NET 5 this can override the base context, and change the return type.
public Context Cx => (Context)base.Context;
protected LabelledEntity(Context cx) : base(cx)
{
}
public override Microsoft.CodeAnalysis.Location ReportingLocation => throw new NotImplementedException();
public void Extract(Context cx2)
{
cx2.Populate(this);
}
public override string ToString()
{
using var writer = new StringWriter();
WriteQuotedId(writer);
return writer.ToString();
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
public abstract IEnumerable<IExtractionProduct> Contents { get; }
}
}

View File

@@ -0,0 +1,22 @@
namespace Semmle.Extraction.CIL
{
/// <summary>
/// A tuple that is an extraction product.
/// </summary>
internal class Tuple : IExtractionProduct
{
private readonly Extraction.Tuple tuple;
public Tuple(string name, params object[] args)
{
tuple = new Extraction.Tuple(name, args);
}
public void Extract(Context cx)
{
cx.TrapWriter.Emit(tuple);
}
public override string ToString() => tuple.ToString();
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
namespace Semmle.Extraction.CIL
{
/// <summary>
/// An entity that has contents to extract. There is no need to populate
/// a key as it's done in the contructor.
/// </summary>
internal abstract class UnlabelledEntity : Extraction.UnlabelledEntity, IExtractedEntity
{
// todo: with .NET 5 this can override the base context, and change the return type.
public Context Cx => (Context)base.Context;
protected UnlabelledEntity(Context cx) : base(cx)
{
}
public override Microsoft.CodeAnalysis.Location ReportingLocation => throw new NotImplementedException();
public void Extract(Context cx2)
{
cx2.Extract(this);
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
public abstract IEnumerable<IExtractionProduct> Contents { get; }
}
}

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