Compare commits

..

7 Commits

Author SHA1 Message Date
Ian Lynagh
62cbd2506c C++: Update stats to add coroutines 2020-09-01 11:48:00 +01:00
Ian Lynagh
ce9432edda C++: Add an upgrade script 2020-08-28 13:52:54 +01:00
Ian Lynagh
8d67418870 C++: Remove co_await range-based-for support for now
Initial impl won't support it
2020-08-28 13:52:54 +01:00
Ian Lynagh
7068a2b5be C++: Split CoReturnStmt.getExpr into CoReturnStmt.{getOperand,getExpr} 2020-08-28 13:52:54 +01:00
Matthew Gretton-Dann
0e9fefd383 Actually sort add Statement support
This commit fixes the previous one.
2020-08-28 13:52:54 +01:00
Matthew Gretton-Dann
79a91bb2a2 Add initial QL support classes for coroutines
Add classes for expressions co_yield and co_await.
Adds classes for statements co_return and `for co_await`.
2020-08-28 13:52:54 +01:00
Matthew Gretton-Dann
c3efacf2df C++: Add DB schema support for coroutines 2020-08-28 13:52:54 +01:00
3981 changed files with 89201 additions and 265769 deletions

View File

@@ -4,6 +4,6 @@
"slevesque.vscode-zipexplorer"
],
"settings": {
"codeQL.runningQueries.memory": 2048
"codeQL.experimentalBqrsParsing": true
}
}

View File

@@ -7,5 +7,3 @@ paths-ignore:
- '/cpp/'
- '/java/'
- '/python/'
- '/javascript/ql/test'
- '/javascript/extractor/tests'

View File

@@ -1,11 +0,0 @@
name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v2
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -1,49 +0,0 @@
name: Build code scanning query list
on:
push:
branches:
- main
- 'rc/**'
pull_request:
paths:
- '.github/workflows/query-list.yml'
- 'misc/scripts/generate-code-scanning-query-list.py'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone self (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: Build code scanning query list
run: |
PATH="$PATH:codeql-cli/codeql" python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv
- name: Upload code scanning query list
uses: actions/upload-artifact@v2
with:
name: code-scanning-query-list
path: code-scanning-query-list.csv

View File

@@ -3,8 +3,8 @@
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"GitHub.vscode-codeql"
"github.vscode-codeql"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}
}

View File

@@ -9,7 +9,7 @@ You can use the [interactive query console](https://lgtm.com/help/lgtm/using-que
## Contributing
We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our [contributing guidelines](CONTRIBUTING.md). You can also consult our [style guides](https://github.com/github/codeql/tree/main/docs) to learn how to format your code for consistency and clarity, how to write query metadata, and how to write query help documentation for your query.
We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our [contributing guidelines](CONTRIBUTING.md). You can also consult our [style guides](https://github.com/github/codeql/tree/master/docs) to learn how to format your code for consistency and clarity, how to write query metadata, and how to write query help documentation for your query.
## License

View File

@@ -4,26 +4,20 @@ The following changes in version 1.25 affect Java analysis in all applications.
## General improvements
The Java autobuilder has been improved to detect more Gradle Java versions.
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|------------------------------|------------------------|-----------------------------------|
| Hard-coded credential in API call (`java/hardcoded-credential-api-call`) | More results | The query now recognizes the `BasicAWSCredentials` class of the Amazon client SDK library with hardcoded access key/secret key. |
| Deserialization of user-controlled data (`java/unsafe-deserialization`) | Fewer false positive results | The query no longer reports results using `org.apache.commons.io.serialization.ValidatingObjectInputStream`. |
| Use of a broken or risky cryptographic algorithm (`java/weak-cryptographic-algorithm`) | More results | The query now recognizes the `MessageDigest.getInstance` method. |
| Use of a potentially broken or risky cryptographic algorithm (`java/potentially-weak-cryptographic-algorithm`) | More results | The query now recognizes the `MessageDigest.getInstance` method. |
| Reading from a world writable file (`java/world-writable-file-read`) | More results | The query now recognizes more JDK file operations. |
## Changes to libraries
* The data-flow library has been improved with more taint flow modeling for the
Collections framework and other classes of the JDK. This affects all security
queries using data flow and can yield additional results.
* The data-flow library has been improved with more taint flow modeling for the
Spring framework. This affects all security queries using data flow and can
yield additional results on project that rely on the Spring framework.
* The data-flow library has been improved, which affects most security queries by potentially
adding more results. Flow through methods now takes nested field reads/writes into account.
For example, the library is able to track flow from `"taint"` to `sink()` via the method
@@ -45,5 +39,3 @@ The Java autobuilder has been improved to detect more Gradle Java versions.
}
}
```
* The library has been extended with more support for Java 14 features
(`switch` expressions and pattern-matching for `instanceof`).

View File

@@ -30,7 +30,7 @@
- [yargs](https://www.npmjs.com/package/yargs)
- [webpack-dev-server](https://www.npmjs.com/package/webpack-dev-server)
* TypeScript 4.0 is now supported.
* TypeScript 3.9 is now supported.
* TypeScript code embedded in HTML and Vue files is now extracted and analyzed.

View File

@@ -1,9 +1,22 @@
# Improvements to Python analysis
The following changes in version 1.25 affect Python analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
## Changes to libraries
* Importing `semmle.python.web.HttpRequest` will no longer import `UntrustedStringKind` transitively. `UntrustedStringKind` is the most commonly used non-abstract subclass of `ExternalStringKind`. If not imported (by one mean or another), taint-tracking queries that concern `ExternalStringKind` will not produce any results. Please ensure such queries contain an explicit import (`import semmle.python.security.strings.Untrusted`).
* Added model of taint sources for HTTP servers using `http.server`.
* Added taint modeling of routed parameters in Flask.
* Improved modeling of built-in methods on strings for taint tracking.
* Improved classification of test files.
* New class `BoundMethodValue` represents a bound method during runtime.
* The query `py/command-line-injection` now recognizes command execution with the `fabric` and `invoke` Python libraries.

View File

@@ -13,19 +13,13 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Declaration hides parameter (`cpp/declaration-hides-parameter`) | Fewer false positive results | False positives involving template functions have been fixed. |
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | | The precision of this query has been decreased from "high" to "medium". As a result, the query is still run but results are no longer displayed on LGTM by default. |
| Comparison result is always the same (`cpp/constant-comparison`) | More correct results | Bounds on expressions involving multiplication can now be determined in more cases. |
## Changes to libraries
* The QL class `Block`, denoting the `{ ... }` statement, is renamed to `BlockStmt`.
* The models library now models many taint flows through `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`.
* The models library now models some taint flows through `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`.
* The models library now models many more taint flows through `std::string`.
* The models library now models many taint flows through `std::istream` and `std::ostream`.
* The models library now models some taint flows through `std::shared_ptr`, `std::unique_ptr`, `std::make_shared` and `std::make_unique`.
* The models library now models many taint flows through `std::pair`, `std::map`, `std::unordered_map`, `std::set` and `std::unordered_set`.
* The models library now models `bcopy`.
* The `SimpleRangeAnalysis` library now supports multiplications of the form
`e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant.

View File

@@ -0,0 +1,31 @@
# Improvements to C# analysis
The following changes in version 1.26 affect C# analysis in all applications.
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|------------------------------|------------------------|-----------------------------------|
## Removal of old queries
## Changes to code extraction
* Partial method bodies are extracted. Previously, partial method bodies were skipped completely.
* Inferring the lengths of implicitely sized arrays is fixed. Previously, multidimensional arrays were always extracted with the same length for
each dimension. With the fix, the array sizes `2` and `1` are extracted for `new int[,]{{1},{2}}`. Previously `2` and `2` were extracted.
## Changes to libraries
## Changes to autobuilder
## Changes to tooling support
* The Abstract Syntax Tree of C# files can be printed in Visual Studio Code.

View File

@@ -1,20 +0,0 @@
# Improvements to Java analysis
The following changes in version 1.26 affect Java analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|------------------------------|------------------------|-----------------------------------|
## Changes to libraries

View File

@@ -2,49 +2,19 @@
## General improvements
* Angular-specific taint sources and sinks are now recognized by the security queries.
* Support for React has improved, with better handling of react hooks, react-router path parameters, lazy-loaded components, and components transformed using `react-redux` and/or `styled-components`.
* Dynamic imports are now analyzed more precisely.
* Support for the following frameworks and libraries has been improved:
- [@angular/*](https://www.npmjs.com/package/@angular/core)
- [AWS Serverless](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
- [Alibaba Serverless](https://www.alibabacloud.com/help/doc-detail/156876.htm)
- [debounce](https://www.npmjs.com/package/debounce)
- [bluebird](https://www.npmjs.com/package/bluebird)
- [call-limit](https://www.npmjs.com/package/call-limit)
- [classnames](https://www.npmjs.com/package/classnames)
- [clsx](https://www.npmjs.com/package/clsx)
- [express](https://www.npmjs.com/package/express)
- [fast-json-stable-stringify](https://www.npmjs.com/package/fast-json-stable-stringify)
- [fast-safe-stringify](https://www.npmjs.com/package/fast-safe-stringify)
- [http](https://nodejs.org/api/http.html)
- [javascript-stringify](https://www.npmjs.com/package/javascript-stringify)
- [js-stringify](https://www.npmjs.com/package/js-stringify)
- [json-stable-stringify](https://www.npmjs.com/package/json-stable-stringify)
- [json-stringify-safe](https://www.npmjs.com/package/json-stringify-safe)
- [json3](https://www.npmjs.com/package/json3)
- [jQuery throttle / debounce](https://github.com/cowboy/jquery-throttle-debounce)
- [lodash](https://www.npmjs.com/package/lodash)
- [lodash.debounce](https://www.npmjs.com/package/lodash.debounce)
- [lodash.throttle](https://www.npmjs.com/package/lodash.throttle)
- [needle](https://www.npmjs.com/package/needle)
- [object-inspect](https://www.npmjs.com/package/object-inspect)
- [pretty-format](https://www.npmjs.com/package/pretty-format)
- [react](https://www.npmjs.com/package/react)
- [react-router-dom](https://www.npmjs.com/package/react-router-dom)
- [react-redux](https://www.npmjs.com/package/react-redux)
- [redis](https://www.npmjs.com/package/redis)
- [redux](https://www.npmjs.com/package/redux)
- [stringify-object](https://www.npmjs.com/package/stringify-object)
- [styled-components](https://www.npmjs.com/package/styled-components)
- [throttle-debounce](https://www.npmjs.com/package/throttle-debounce)
- [underscore](https://www.npmjs.com/package/underscore)
* Analyzing files with the ".cjs" extension is now supported.
* ES2021 features are now supported.
## New queries
@@ -56,18 +26,8 @@
| **Query** | **Expected impact** | **Change** |
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
| Potentially unsafe external link (`js/unsafe-external-link`) | Fewer results | This query no longer flags URLs constructed using a template system where only the hash or query part of the URL is dynamic. |
| Incomplete URL substring sanitization (`js/incomplete-url-substring-sanitization`) | More results | This query now recognizes additional URLs when the substring check is an inclusion check. |
| Ambiguous HTML id attribute (`js/duplicate-html-id`) | Results no longer shown | Precision tag reduced to "low". The query is no longer run by default. |
| Unused loop iteration variable (`js/unused-loop-variable`) | Fewer results | This query no longer flags variables in a destructuring array assignment that are not the last variable in the destructed array. |
| Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | More results | This query now recognizes more commands where colon, dash, and underscore are used. |
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | More results | This query now detects more unsafe uses of nested option properties. |
| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | More results | This query now recognizes some unsafe uses of `importScripts()` inside WebWorkers. |
| Missing CSRF middleware (`js/missing-token-validation`) | More results | This query now recognizes writes to cookie and session variables as potentially vulnerable to CSRF attacks. |
| Missing CSRF middleware (`js/missing-token-validation`) | Fewer results | This query now recognizes more ways of protecting against CSRF attacks. |
| Client-side cross-site scripting (`js/xss`) | More results | This query now tracks data flow from `location.hash` more precisely. |
## Changes to libraries
* The predicate `TypeAnnotation.hasQualifiedName` now works in more cases when the imported library was not present during extraction.
* The class `DomBasedXss::Configuration` has been deprecated, as it has been split into `DomBasedXss::HtmlInjectionConfiguration` and `DomBasedXss::JQueryHtmlOrSelectorInjectionConfiguration`. Unless specifically working with jQuery sinks, subclasses should instead be based on `HtmlInjectionConfiguration`. To use both configurations in a query, see [Xss.ql](https://github.com/github/codeql/blob/main/javascript/ql/src/Security/CWE-079/Xss.ql) for an example.

View File

@@ -19,17 +19,15 @@
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll"
"python/ql/src/experimental/dataflow/internal/DataFlowImpl.qll",
"python/ql/src/experimental/dataflow/internal/DataFlowImpl2.qll"
],
"DataFlow Java/C++/C#/Python Common": [
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll"
"python/ql/src/experimental/dataflow/internal/DataFlowImplCommon.qll"
],
"TaintTracking::Configuration Java/C++/C#/Python": [
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
@@ -43,37 +41,14 @@
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll",
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll",
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll",
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll",
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll"
"python/ql/src/experimental/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
],
"DataFlow Java/C++/C#/Python Consistency checks": [
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
],
"SsaReadPosition Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
],
"Sign Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
],
"SignAnalysis Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
],
"Bound Java/C#": [
"java/ql/src/semmle/code/java/dataflow/Bound.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/Bound.qll"
],
"ModulusAnalysis Java/C#": [
"java/ql/src/semmle/code/java/dataflow/ModulusAnalysis.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/ModulusAnalysis.qll"
"python/ql/src/experimental/dataflow/internal/DataFlowImplConsistency.qll"
],
"C++ SubBasicBlocks": [
"cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
@@ -112,7 +87,7 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll",
"csharp/ql/src/experimental/ir/implementation/raw/Operand.qll",
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll"
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll"
],
"IR IRType": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll",
@@ -134,11 +109,11 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
"csharp/ql/src/experimental/ir/implementation/internal/OperandTag.qll"
],
"IR TInstruction": [
"IR TInstruction":[
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
"csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll"
],
"IR TIRVariable": [
"IR TIRVariable":[
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
"csharp/ql/src/experimental/ir/implementation/internal/TIRVariable.qll"
],
@@ -350,79 +325,15 @@
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll"
],
"C# ControlFlowReachability": [
"csharp/ql/src/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ControlFlowReachability.qll"
],
"Inline Test Expectations": [
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"python/ql/test/TestUtilities/InlineExpectationsTest.qll"
],
"C++ ExternalAPIs": [
"cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll",
"cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll"
],
"C++ SafeExternalAPIFunction": [
"cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll",
"cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll"
],
"XML": [
"cpp/ql/src/semmle/code/cpp/XML.qll",
"csharp/ql/src/semmle/code/csharp/XML.qll",
"java/ql/src/semmle/code/xml/XML.qll",
"javascript/ql/src/semmle/javascript/XML.qll",
"python/ql/src/semmle/python/xml/XML.qll"
],
"DuplicationProblems.qhelp": [
"cpp/ql/src/Metrics/Files/DuplicationProblems.qhelp",
"csharp/ql/src/Metrics/Files/DuplicationProblems.qhelp",
"javascript/ql/src/Metrics/DuplicationProblems.qhelp",
"python/ql/src/Metrics/DuplicationProblems.qhelp"
],
"CommentedOutCodeQuery.qhelp": [
"cpp/ql/src/Documentation/CommentedOutCodeQuery.qhelp",
"python/ql/src/Lexical/CommentedOutCodeQuery.qhelp",
"csharp/ql/src/Bad Practices/Comments/CommentedOutCodeQuery.qhelp",
"java/ql/src/Violations of Best Practice/Comments/CommentedOutCodeQuery.qhelp",
"javascript/ql/src/Comments/CommentedOutCodeQuery.qhelp"
],
"FLinesOfCodeReferences.qhelp": [
"java/ql/src/Metrics/Files/FLinesOfCodeReferences.qhelp",
"javascript/ql/src/Metrics/FLinesOfCodeReferences.qhelp"
],
"FCommentRatioCommon.qhelp": [
"java/ql/src/Metrics/Files/FCommentRatioCommon.qhelp",
"javascript/ql/src/Metrics/FCommentRatioCommon.qhelp"
],
"FLinesOfCodeOverview.qhelp": [
"java/ql/src/Metrics/Files/FLinesOfCodeOverview.qhelp",
"javascript/ql/src/Metrics/FLinesOfCodeOverview.qhelp"
],
"CommentedOutCodeMetricOverview.qhelp": [
"cpp/ql/src/Metrics/Files/CommentedOutCodeMetricOverview.qhelp",
"csharp/ql/src/Metrics/Files/CommentedOutCodeMetricOverview.qhelp",
"java/ql/src/Metrics/Files/CommentedOutCodeMetricOverview.qhelp",
"javascript/ql/src/Comments/CommentedOutCodeMetricOverview.qhelp",
"python/ql/src/Lexical/CommentedOutCodeMetricOverview.qhelp"
],
"FLinesOfDuplicatedCodeCommon.qhelp": [
"cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.qhelp",
"java/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.qhelp",
"javascript/ql/src/Metrics/FLinesOfDuplicatedCodeCommon.qhelp",
"python/ql/src/Metrics/FLinesOfDuplicatedCodeCommon.qhelp"
],
"CommentedOutCodeReferences.qhelp": [
"cpp/ql/src/Metrics/Files/CommentedOutCodeReferences.qhelp",
"csharp/ql/src/Metrics/Files/CommentedOutCodeReferences.qhelp",
"java/ql/src/Metrics/Files/CommentedOutCodeReferences.qhelp",
"javascript/ql/src/Comments/CommentedOutCodeReferences.qhelp",
"python/ql/src/Lexical/CommentedOutCodeReferences.qhelp"
],
"IDE Contextual Queries": [
"cpp/ql/src/IDEContextual.qll",
"csharp/ql/src/IDEContextual.qll",
"java/ql/src/IDEContextual.qll",
"javascript/ql/src/IDEContextual.qll",
"python/ql/src/analysis/IDEContextual.qll"
]
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>Semmle.Autobuild.Cpp</AssemblyName>
<RootNamespace>Semmle.Autobuild.Cpp</RootNamespace>
<ApplicationIcon />

View File

@@ -1,14 +0,0 @@
lgtm,codescanning
* The `SimpleRangeAnalysis` library has gained support for several language
constructs it did not support previously. These improvements primarily affect
the queries `cpp/constant-comparison`, `cpp/comparison-with-wider-type`, and
`cpp/integer-multiplication-cast-to-long`. The newly supported language
features are:
* Multiplication of unsigned numbers.
* Multiplication by a constant.
* Reference-typed function parameters.
* Comparing a variable not equal to an endpoint of its range, thus narrowing the range by one.
* Using `if (x)` or `if (!x)` or similar to test for equality to zero.
* The `SimpleRangeAnalysis` library can now be extended with custom rules. See
examples in
`cpp/ql/src/experimental/semmle/code/cpp/rangeanalysis/extensions/`.

View File

@@ -1,2 +0,0 @@
lgtm,codescanning
* The `cpp/wrong-type-format-argument` and `cpp/non-portable-printf` queries have been hardened so that they do not produce nonsensical results on databases that contain errors (specifically the `ErroneousType`).

View File

@@ -1,2 +0,0 @@
lgtm,codescanning
* The 'Not enough memory allocated for pointer type' (cpp/allocation-too-small) and 'Not enough memory allocated for array of pointer type' (cpp/suspicious-allocation-size) queries have been improved. Previously some allocations would be reported by both queries, this no longer occurs. In addition more allocation functions are now understood by both queries.

View File

@@ -1,2 +0,0 @@
lgtm,codescanning
* Two issues causing the 'Unused local variable' query (`cpp/unused-local-variable`) to produce false positive results have been fixed.

View File

@@ -1,3 +0,0 @@
lgtm,codescanning
* Various classes in `semmle.code.cpp.models.implementations` have been made private. Users should not depend on library implementation details.
* The `OperatorNewAllocationFunction`, `OperatorDeleteDeallocationFunction`, `Iterator` and `Snprintf` classes now have interfaces in `semmle.code.cpp.models.interfaces`.

View File

@@ -1,2 +0,0 @@
lgtm,codescanning
* A new query (`cpp/unsafe-use-of-this`) has been added. The query finds pure virtual function calls whose qualifier is an object under construction.

View File

@@ -1,2 +0,0 @@
lgtm,codescanning
* The queries `cpp/local-variable-hides-global-variable` and `cpp/missing-header-guard` now have severity `recommendation` instead of `warning`.

View File

@@ -9,7 +9,6 @@
+ semmlecode-cpp-queries/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Security/CWE/CWE-253/HResultBooleanConversion.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Likely Bugs/OO/UnsafeUseOfThis.ql: /Correctness/Dangerous Conversions
# Consistent Use
+ semmlecode-cpp-queries/Critical/ReturnValueIgnored.ql: /Correctness/Consistent Use
+ semmlecode-cpp-queries/Likely Bugs/InconsistentCheckReturnNull.ql: /Correctness/Consistent Use

View File

@@ -9,6 +9,6 @@
import cpp
from BlockStmt blk
from Block blk
where blk.getNumStmt() = 0
select blk

View File

@@ -13,5 +13,5 @@
import cpp
from IfStmt i
where i.getThen().(BlockStmt).getNumStmt() = 0
where i.getThen().(Block).getNumStmt() = 0
select i

View File

@@ -8,6 +8,6 @@
import cpp
from BlockStmt b
from Block b
where b.getNumStmt() = 1
select b

View File

@@ -14,7 +14,7 @@ import cpp
class ComplexStmt extends Stmt {
ComplexStmt() {
exists(BlockStmt body |
exists(Block body |
body = this.(Loop).getStmt() or
body = this.(SwitchStmt).getStmt()
|
@@ -24,7 +24,7 @@ class ComplexStmt extends Stmt {
}
}
from BlockStmt b, int n, ComplexStmt complexStmt
from Block b, int n, ComplexStmt complexStmt
where
n = strictcount(ComplexStmt s | s = b.getAStmt()) and
n > 3 and

View File

@@ -39,7 +39,7 @@ void good() {
</example>
<references>
<li>MSDN Library for MFC: <a href="https://docs.microsoft.com/en-us/cpp/mfc/exceptions-catching-and-deleting-exceptions">Exceptions: Catching and Deleting Exceptions</a>.</li>
<li>MSDN Library for MFC: <a href="http://msdn.microsoft.com/en-us/library/0e5twxsh(v=vs.110).aspx">Exceptions: Catching and Deleting Exceptions</a>.</li>
</references>

View File

@@ -11,17 +11,6 @@
import cpp
/**
* Gets the template that a function `f` is constructed from, or just `f` if it
* is not from a template instantiation.
*/
Function getConstructedFrom(Function f) {
f.isConstructedFrom(result)
or
not f.isConstructedFrom(_) and
result = f
}
/**
* Gets the parameter of `f` with name `name`, which has to come from the
* _definition_ of `f` and not a prototype declaration.
@@ -29,17 +18,13 @@ Function getConstructedFrom(Function f) {
* This should not happen in a single application but since we
* have a system wide view it is likely to happen for instance for
* the main function.
*
* Note: we use `getConstructedFrom` to ensure that we look at template
* functions rather than their instantiations. We get better results this way
* as the instantiation is artificial and may have inherited parameter names
* from the declaration rather than the definition.
*/
ParameterDeclarationEntry functionParameterNames(Function f, string name) {
exists(FunctionDeclarationEntry fe |
result.getFunctionDeclarationEntry() = fe and
getConstructedFrom(f).getDefinition() = fe and
fe.getFunction() = f and
fe.getLocation() = f.getDefinitionLocation() and
result.getFile() = fe.getFile() and // Work around CPP-331
strictcount(f.getDefinitionLocation()) = 1 and
result.getName() = name
)

View File

@@ -17,7 +17,7 @@ where
shadowing(lv1, lv2) and
not lv1.isCompilerGenerated() and
not lv2.isCompilerGenerated() and
not lv1.getParentScope().(BlockStmt).isInMacroExpansion() and
not lv2.getParentScope().(BlockStmt).isInMacroExpansion()
not lv1.getParentScope().(Block).isInMacroExpansion() and
not lv2.getParentScope().(Block).isInMacroExpansion()
select lv1, "Variable " + lv1.getName() + " hides another variable of the same name (on $@).", lv2,
"line " + lv2.getLocation().getStartLine().toString()

View File

@@ -2,7 +2,7 @@
* @name Local variable hides global variable
* @description A local variable or parameter that hides a global variable of the same name. This may be confusing. Consider renaming one of the variables.
* @kind problem
* @problem.severity recommendation
* @problem.severity warning
* @precision very-high
* @id cpp/local-variable-hides-global-variable
* @tags maintainability

View File

@@ -14,7 +14,7 @@
import cpp
predicate emptyBlock(ControlStructure s, BlockStmt b) {
predicate emptyBlock(ControlStructure s, Block b) {
b = s.getAChild() and
not exists(b.getAChild()) and
not b.isInMacroExpansion() and
@@ -23,7 +23,7 @@ predicate emptyBlock(ControlStructure s, BlockStmt b) {
class AffectedFile extends File {
AffectedFile() {
exists(BlockStmt b |
exists(Block b |
emptyBlock(_, b) and
this = b.getFile()
)
@@ -37,7 +37,7 @@ class AffectedFile extends File {
class BlockOrNonChild extends Element {
BlockOrNonChild() {
(
this instanceof BlockStmt
this instanceof Block
or
this instanceof Comment
or
@@ -78,7 +78,7 @@ class BlockOrNonChild extends Element {
/**
* A block that contains a non-child element.
*/
predicate emptyBlockContainsNonchild(BlockStmt b) {
predicate emptyBlockContainsNonchild(Block b) {
emptyBlock(_, b) and
exists(BlockOrNonChild c, AffectedFile file |
c.(BlockOrNonChild).getStartRankIn(file) = 1 + b.(BlockOrNonChild).getStartRankIn(file) and
@@ -91,7 +91,7 @@ predicate emptyBlockContainsNonchild(BlockStmt b) {
* A block that is entirely on one line, which also contains a comment. Chances
* are the comment is intended to refer to the block.
*/
predicate lineComment(BlockStmt b) {
predicate lineComment(Block b) {
emptyBlock(_, b) and
exists(Location bLocation, File f, int line |
bLocation = b.getLocation() and
@@ -106,7 +106,7 @@ predicate lineComment(BlockStmt b) {
)
}
from ControlStructure s, BlockStmt eb
from ControlStructure s, Block eb
where
emptyBlock(s, eb) and
not emptyBlockContainsNonchild(eb) and

View File

@@ -57,12 +57,5 @@ where
not declarationHasSideEffects(v) and
not exists(AsmStmt s | f = s.getEnclosingFunction()) and
not v.getAnAttribute().getName() = "unused" and
not any(ErrorExpr e).getEnclosingFunction() = f and // unextracted expr may use `v`
not exists(
Literal l // this case can be removed when the `myFunction2( [obj](){} );` test case doesn't depend on this exclusion
|
l.getEnclosingFunction() = f and
not exists(l.getValue())
) and
not any(ConditionDeclExpr cde).getEnclosingFunction() = f // this case can be removed when the `if (a = b; a)` test case doesn't depend on this exclusion
not any(ErrorExpr e).getEnclosingFunction() = f // unextracted expr likely used `v`
select v, "Variable " + v.getName() + " is not used"

View File

@@ -27,7 +27,7 @@ then removing it will make code more readable. If the static variable is needed
<a href="https://www.securecoding.cert.org/confluence/display/c/MSC12-C.+Detect+and+remove+code+that+has+no+effect+or+is+never+executed">Detect and remove code that has no effect</a>
</li>
<li>
<a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL19-C.+Minimize+the+scope+of+variables+and+functions">Minimize the scope of variables and functions</a>
<a href="https://www.securecoding.cert.org/confluence/display/cplusplus/DCL07-CPP.+Minimize+the+scope+of+variables+and+methods">Minimize the scope of variables and methods</a>
</li>

View File

@@ -41,7 +41,7 @@ this rule.
E. W. Dijkstra Archive: <a href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD215.html">A Case against the GO TO Statement (EWD-215)</a>.
</li>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/goto-statement-cpp">goto Statement (C++)</a>.
MSDN Library: <a href="http://msdn.microsoft.com/en-gb/library/b34dt9cd%28v=vs.80%29.aspx">The goto Statement</a>.
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, Rule 4.6. Prentice Hall PTR, 1997.

View File

@@ -12,7 +12,7 @@
import cpp
import semmle.code.cpp.commons.Exclusions
Stmt getNextRealStmt(BlockStmt b, int i) {
Stmt getNextRealStmt(Block b, int i) {
result = b.getStmt(i + 1) and
not result instanceof EmptyStmt
or
@@ -20,7 +20,7 @@ Stmt getNextRealStmt(BlockStmt b, int i) {
result = getNextRealStmt(b, i + 1)
}
from JumpStmt js, BlockStmt b, int i, Stmt s
from JumpStmt js, Block b, int i, Stmt s
where
b.getStmt(i) = js and
s = getNextRealStmt(b, i) and

View File

@@ -27,6 +27,6 @@ this cannot happen.
</example>
<references>
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers">EXP34-C. Do not dereference null pointers</a>.</li>
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointerss">EXP34-C. Do not dereference null pointers</a>.</li>
</references>
</qhelp>

View File

@@ -5,6 +5,8 @@
import cpp
import semmle.code.cpp.controlflow.SSA
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.models.implementations.Allocation
import semmle.code.cpp.models.implementations.Deallocation
/**
* Holds if `alloc` is a use of `malloc` or `new`. `kind` is

View File

@@ -23,7 +23,10 @@ import semmle.code.cpp.security.TaintTracking
* ```
*/
predicate sourceSized(FunctionCall fc, Expr src) {
fc.getTarget().hasGlobalOrStdName(["strncpy", "strncat", "memcpy", "memmove"]) and
exists(string name |
(name = "strncpy" or name = "strncat" or name = "memcpy" or name = "memmove") and
fc.getTarget().hasGlobalOrStdName(name)
) and
exists(Expr dest, Expr size, Variable v |
fc.getArgument(0) = dest and
fc.getArgument(1) = src and

View File

@@ -13,9 +13,30 @@
*/
import cpp
import semmle.code.cpp.models.Models
predicate baseType(AllocationExpr alloc, Type base) {
class Allocation extends FunctionCall {
Allocation() {
exists(string name |
this.getTarget().hasGlobalOrStdName(name) and
(name = "malloc" or name = "calloc" or name = "realloc")
)
}
private string getName() { this.getTarget().hasGlobalOrStdName(result) }
int getSize() {
this.getName() = "malloc" and
this.getArgument(0).getValue().toInt() = result
or
this.getName() = "realloc" and
this.getArgument(1).getValue().toInt() = result
or
this.getName() = "calloc" and
result = this.getArgument(0).getValue().toInt() * this.getArgument(1).getValue().toInt()
}
}
predicate baseType(Allocation alloc, Type base) {
exists(PointerType pointer |
pointer.getBaseType() = base and
(
@@ -33,12 +54,11 @@ predicate decideOnSize(Type t, int size) {
size = min(t.getSize())
}
from AllocationExpr alloc, Type base, int basesize, int allocated
from Allocation alloc, Type base, int basesize, int allocated
where
baseType(alloc, base) and
allocated = alloc.getSizeBytes() and
allocated = alloc.getSize() and
decideOnSize(base, basesize) and
alloc.(FunctionCall).getTarget() instanceof AllocationFunction and // exclude `new` and similar
basesize > allocated
select alloc,
"Type '" + base.getName() + "' is " + basesize.toString() + " bytes, but only " +

View File

@@ -13,9 +13,30 @@
*/
import cpp
import semmle.code.cpp.models.Models
predicate baseType(AllocationExpr alloc, Type base) {
class Allocation extends FunctionCall {
Allocation() {
exists(string name |
this.getTarget().hasGlobalOrStdName(name) and
(name = "malloc" or name = "calloc" or name = "realloc")
)
}
private string getName() { this.getTarget().hasGlobalOrStdName(result) }
int getSize() {
this.getName() = "malloc" and
this.getArgument(0).getValue().toInt() = result
or
this.getName() = "realloc" and
this.getArgument(1).getValue().toInt() = result
or
this.getName() = "calloc" and
result = this.getArgument(0).getValue().toInt() * this.getArgument(1).getValue().toInt()
}
}
predicate baseType(Allocation alloc, Type base) {
exists(PointerType pointer |
pointer.getBaseType() = base and
(
@@ -28,23 +49,16 @@ predicate baseType(AllocationExpr alloc, Type base) {
)
}
predicate decideOnSize(Type t, int size) {
// If the codebase has more than one type with the same name, it can have more than one size.
size = min(t.getSize())
}
from AllocationExpr alloc, Type base, int basesize, int allocated
from Allocation alloc, Type base, int basesize, int allocated
where
baseType(alloc, base) and
allocated = alloc.getSizeBytes() and
decideOnSize(base, basesize) and
alloc.(FunctionCall).getTarget() instanceof AllocationFunction and // exclude `new` and similar
allocated = alloc.getSize() and
// If the codebase has more than one type with the same name, check if any matches
not exists(int size | base.getSize() = size |
size = 0 or
(allocated / size) * size = allocated
) and
not basesize > allocated // covered by SizeCheck.ql
basesize = min(base.getSize())
select alloc,
"Allocated memory (" + allocated.toString() + " bytes) is not a multiple of the size of '" +
base.getName() + "' (" + basesize.toString() + " bytes)."

View File

@@ -1,11 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<fragment>
<warning>
This check is an approximation, so some results may not be actual defects in the program.
It is not possible in general to compute the exact value of the variable without running the program with all possible input data.
</warning>
</fragment>
</qhelp>

View File

@@ -1,12 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<fragment>
<warning>
This check is an approximation, so some results may not be actual defects in the program.
It is not possible in general to compute which function is actually called in a virtual call,
or a call through a pointer, without running the program with all possible input data.
</warning>
</fragment>
</qhelp>

View File

@@ -1,13 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<fragment>
<warning>
This check is an approximation, so some results may not be actual defects in the program.
It is not possible in general to compute the actual branch taken in conditional statements such
as "if" without running the program with all possible input data. This means that it is not possible
to determine if a particular statement is going to be executed.
</warning>
</fragment>
</qhelp>

View File

@@ -1,11 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<fragment>
<warning>
This check is an approximation, so some results may not be actual defects in the program. It is not possible
in general to compute the values of pointers without running the program with all input data.
</warning>
</fragment>
</qhelp>

View File

@@ -3,5 +3,5 @@
"qhelp.dtd">
<qhelp>
<include src="CommentedOutCodeQuery.qhelp" />
<include src="../Metrics/Files/CommentedOutCodeReferences.qhelp" />
<include src="CommentedOutCodeReferences.qhelp" />
</qhelp>

View File

@@ -1,25 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Commented-out code is distracting and confusing for developers who read the surrounding code,
and its significance is often unclear. It will not get compiled or tested when the code around
it changes, so it's likely to break over time. For these reasons, commented-out code should be
avoided.
</p>
</overview>
<recommendation>
<p>
Remove or reinstate the commented-out code. If you want to include a snippet of example code
in a comment, consider enclosing it in quotes or marking it up as appropriate for the source
language.
</p>
</recommendation>
</qhelp>

View File

@@ -1,22 +0,0 @@
/**
* Provides shared predicates related to contextual queries in the code viewer.
*/
import semmle.files.FileSystem
/**
* Returns the `File` matching the given source file name as encoded by the VS
* Code extension.
*/
cached
File getFileBySourceArchiveName(string name) {
// The name provided for a file in the source archive by the VS Code extension
// has some differences from the absolute path in the database:
// 1. colons are replaced by underscores
// 2. there's a leading slash, even for Windows paths: "C:/foo/bar" ->
// "/C_/foo/bar"
// 3. double slashes in UNC prefixes are replaced with a single slash
// We can handle 2 and 3 together by unconditionally adding a leading slash
// before replacing double slashes.
name = ("/" + result.getAbsolutePath().replaceAll(":", "_")).replaceAll("//", "/")
}

View File

@@ -13,7 +13,14 @@
import cpp
class ForbiddenFunction extends Function {
ForbiddenFunction() { this.getName() = ["setjmp", "longjmp", "sigsetjmp", "siglongjmp"] }
ForbiddenFunction() {
exists(string name | name = this.getName() |
name = "setjmp" or
name = "longjmp" or
name = "sigsetjmp" or
name = "siglongjmp"
)
}
}
from FunctionCall call

View File

@@ -12,7 +12,7 @@
import cpp
int lineInBlock(File f) {
exists(BlockStmt block, Location blockLocation |
exists(Block block, Location blockLocation |
block.getFile() = f and blockLocation = block.getLocation()
|
result in [blockLocation.getStartLine() .. blockLocation.getEndLine()]

View File

@@ -23,7 +23,7 @@ As a result, this check incorrectly considers all negative numbers as even.
<references>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/multiplicative-operators-and-the-modulus-operator">Multiplicative Operators and the Modulus Operator</a>.
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/ty2ax9z9%28v=vs.71%29.aspx">Multiplicative Operators: *, /, and %</a>.
</li>
<li>
Wikipedia: <a href="http://en.wikipedia.org/wiki/Modulo_operation#Common_pitfalls">Modulo Operation - Common pitfalls</a>.

View File

@@ -24,7 +24,7 @@
Code Project: <a href="http://www.codeproject.com/Articles/2247/An-introduction-to-bitwise-operators">An introduction to bitwise operators</a>
</li>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/c-language/signed-bitwise-operations">Signed Bitwise Operations</a>
MSDN Library: <a href="https://msdn.microsoft.com/en-us/library/dxda59dh.aspx">Signed Bitwise Operations</a>
</li>

View File

@@ -21,7 +21,7 @@ It is best to fully parenthesize complex comparison expressions to explicitly de
<references>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/cpp-built-in-operators-precedence-and-associativity">C++ built-in operators, precedence, and associativity</a>
<a href="http://msdn.microsoft.com/en-us/library/126fe14k%28v=VS.80%29.aspx">Operator Precedence and Associativity</a>
</li>
<li>
<a href="http://www.cplusplus.com/doc/tutorial/operators/">Operators</a>

View File

@@ -24,7 +24,7 @@ as rounding errors will be more prominent when using such values.
<li>
D. Goldberg, <em>What Every Computer Scientist Should Know About Floating-Point Arithmetic</em>,
ACM Computing Surveys, Volume 23, Issue 1, March 1991 (<a href="https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html">available online</a>).
ACM Computing Surveys, Volume 23, Issue 1, March 1991 (<a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html">available online</a>).
</li>

View File

@@ -4,5 +4,3 @@ long j = i * i; //Wrong: due to overflow on the multiplication between ints,
long k = (long) i * i; //Correct: the multiplication is done on longs instead of ints,
//and will not overflow
long l = static_cast<long>(i) * i; //Correct: modern C++

View File

@@ -23,7 +23,7 @@ the expression would produce a result that would be too large to fit in the smal
<references>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/multiplicative-operators-and-the-modulus-operator">Multiplicative Operators and the Modulus Operator</a>.
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/ty2ax9z9%28v=vs.71%29.aspx">Multiplicative Operators: *, /, and %</a>.
</li>
<li>
Cplusplus.com: <a href="http://www.cplusplus.com/articles/DE18T05o/">Integer overflow</a>.

View File

@@ -23,7 +23,7 @@ the latter occupies eight bytes on a 64-bit machine.</p>
<references>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/type-conversions-and-type-safety-modern-cpp">Type Conversions and Type Safety</a>.
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/hh279667.aspx">Type Conversions and Type Safety (Modern C++)</a>.
</li>
<li>
Cplusplus.com: <a href="http://www.cplusplus.com/doc/tutorial/typecasting/">Type conversions</a>.

View File

@@ -23,7 +23,7 @@ the function.
<li>CERT C Coding
Standard: <a href="https://www.securecoding.cert.org/confluence/display/c/FIO30-C.+Exclude+user+input+from+format+strings">FIO30-C. Exclude user input from format strings</a>.</li>
<li>cplusplus.com: <a href="http://www.tutorialspoint.com/cplusplus/cpp_functions.htm">C++ Functions</a>.</li>
<li>CRT Alphabetical Function Reference: <a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l">printf, _printf_l, wprintf, _wprintf_l</a>.</li>
<li>MSDN Alphabetical Function Reference: <a href="http://msdn.microsoft.com/en-us/library/wc7014hz%28VS.71%29.aspx">printf, wprintf</a>.</li>

View File

@@ -155,8 +155,7 @@ where
not actual.getUnspecifiedType().(IntegralType).getSize() = sizeof_IntType()
) and
not arg.isAffectedByMacro() and
not arg.isFromUninstantiatedTemplate(_) and
not actual.getUnspecifiedType() instanceof ErroneousType
not arg.isFromUninstantiatedTemplate(_)
select arg,
"This argument should be of type '" + expected.getName() + "' but is of type '" +
actual.getUnspecifiedType().getName() + "'"

View File

@@ -15,7 +15,7 @@ of days. Alternatively, use an established library routine that already contain
</recommendation>
<references>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -22,7 +22,7 @@
</example>
<references>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -34,7 +34,7 @@
</example>
<references>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -40,7 +40,9 @@ class DateStructModifiedFieldAccess extends LeapYearFieldAccess {
*/
class SafeTimeGatheringFunction extends Function {
SafeTimeGatheringFunction() {
this.getQualifiedName() = ["GetFileTime", "GetSystemTime", "NtQuerySystemTime"]
this.getQualifiedName() = "GetFileTime" or
this.getQualifiedName() = "GetSystemTime" or
this.getQualifiedName() = "NtQuerySystemTime"
}
}
@@ -49,13 +51,15 @@ class SafeTimeGatheringFunction extends Function {
*/
class TimeConversionFunction extends Function {
TimeConversionFunction() {
this.getQualifiedName() =
[
"FileTimeToSystemTime", "SystemTimeToFileTime", "SystemTimeToTzSpecificLocalTime",
"SystemTimeToTzSpecificLocalTimeEx", "TzSpecificLocalTimeToSystemTime",
"TzSpecificLocalTimeToSystemTimeEx", "RtlLocalTimeToSystemTime",
"RtlTimeToSecondsSince1970", "_mkgmtime"
]
this.getQualifiedName() = "FileTimeToSystemTime" or
this.getQualifiedName() = "SystemTimeToFileTime" or
this.getQualifiedName() = "SystemTimeToTzSpecificLocalTime" or
this.getQualifiedName() = "SystemTimeToTzSpecificLocalTimeEx" or
this.getQualifiedName() = "TzSpecificLocalTimeToSystemTime" or
this.getQualifiedName() = "TzSpecificLocalTimeToSystemTimeEx" or
this.getQualifiedName() = "RtlLocalTimeToSystemTime" or
this.getQualifiedName() = "RtlTimeToSecondsSince1970" or
this.getQualifiedName() = "_mkgmtime"
}
}

View File

@@ -23,7 +23,7 @@
</example>
<references>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -27,11 +27,11 @@ predicate macroUseLocation(File f, int start, int end) {
}
pragma[noopt]
predicate emptyIf(IfStmt s, BlockStmt b, File f, int start, int end) {
predicate emptyIf(IfStmt s, Block b, File f, int start, int end) {
s instanceof IfStmt and
not exists(s.getElse()) and
b = s.getThen() and
b instanceof BlockStmt and
b instanceof Block and
not exists(b.getAChild()) and
f = b.getFile() and
exists(Location l |
@@ -42,7 +42,7 @@ predicate emptyIf(IfStmt s, BlockStmt b, File f, int start, int end) {
}
pragma[noopt]
predicate query(IfStmt s, BlockStmt b) {
predicate query(IfStmt s, Block b) {
exists(File f, int blockStart, int blockEnd |
emptyIf(s, b, f, blockStart, blockEnd) and
not exists(int macroStart, int macroEnd |
@@ -53,7 +53,7 @@ predicate query(IfStmt s, BlockStmt b) {
)
}
from IfStmt s, BlockStmt b
from IfStmt s, Block b
where
query(s, b) and
not b.isInMacroExpansion()

View File

@@ -23,7 +23,7 @@ indication that there may be cases unhandled by the <code>switch</code> statemen
Tutorialspoint - The C++ Programming Language: <a href="http://www.tutorialspoint.com/cplusplus/cpp_switch_statement.htm">C++ switch statement</a>
</li>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/switch-statement-cpp">switch statement (C++)</a>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/k0t5wee3%28v=VS.80%29.aspx">The switch Statement</a>
</li>
<li>
M. Henricson and E. Nyquist, <i>Industrial Strength C++</i>, Chapter 4: Control Flow, Rec 4.5. Prentice Hall PTR, 1997 (<a href="http://mongers.org/industrial-c++/">available online</a>).

View File

@@ -88,8 +88,7 @@ where
not arg.isAffectedByMacro() and
size32 = ilp32.paddedSize(actual) and
size64 = lp64.paddedSize(actual) and
size64 != size32 and
not actual instanceof ErroneousType
size64 != size32
select arg,
"This argument should be of type '" + expected.getName() + "' but is of type '" + actual.getName()
+ "' (which changes size from " + size32 + " to " + size64 + " on 64-bit systems)."

View File

@@ -30,7 +30,7 @@ For an array, the size is the number of elements of the array multiplied by the
Cplusplus.comn: <a href="http://www.cplusplus.com/reference/clibrary/cstring/memset/">memset</a>
</li>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memset-wmemset">memset, wmemset</a>, <a href="https://docs.microsoft.com/en-us/cpp/cpp/sizeof-operator">sizeof Operator</a>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/aa246471%28v=VS.60%29.aspx">memset</a>, <a href="http://msdn.microsoft.com/en-us/library/4s7x1k91%28v=VS.71%29.aspx">sizeof Operator</a>
</li>

View File

@@ -25,6 +25,9 @@ outer loop. </p>
<li>
Tutorialspoint - The C++ Programming Language: <a href="http://www.tutorialspoint.com/cplusplus/cpp_nested_loops.htm">C++ nested loops</a>
</li>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/8y82wx12%28v=VS.80%29.aspx">Nested Control Structures</a>
</li>

View File

@@ -20,7 +20,7 @@ object instance).</p>
</example>
<references>
<li>R. Chen, <a href="https://devblogs.microsoft.com/oldnewthing/20040507-00/?p=39443">When should your destructor be virtual?</a>.</li>
<li>R. Chen, <a href="http://blogs.msdn.com/oldnewthing/archive/2004/05/07/127826.aspx">When should your destructor be virtual?</a>.</li>
<li>S. Meyers. <em>Effective C++ 3d ed.</em> pp 40-44. Addison-Wesley Professional, 2005.</li>
</references>
</qhelp>

View File

@@ -1,20 +0,0 @@
class Base {
private:
// pure virtual member function used for initialization of derived classes.
virtual void construct() = 0;
public:
Base() {
// wrong: the virtual table of `Derived` has not been initialized yet. So this
// call will resolve to `Base::construct`, which cannot be called as it is a pure
// virtual function.
construct();
}
};
class Derived : public Base {
int field;
void construct() override {
field = 1;
}
};

View File

@@ -1,30 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>This rule finds calls to pure virtual member functions in constructors and destructors. When executing the body of a constructor of class <code>T</code>, the virtual table of <code>T</code> refers to the virtual table of one of <code>T</code>'s base classes. This can produce unexpected behavior, including program abort that can lead to denial of service attacks. The same problem exists during destruction of an object.</p>
</overview>
<recommendation>
<p>Do not rely on virtual dispatch in constructors and destructors. Instead, each class should be responsible for acquiring and releasing its resources. If a base class needs to refer to a derived class during initialization, use the Dynamic Binding During Initialization idiom.</p>
</recommendation>
<example><sample src="UnsafeUseOfThis.cpp" />
</example>
<references>
<li>ISO C++ FAQ: <a href="https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctors">When my base class's constructor calls a virtual function on its this object, why doesn't my derived class's override of that virtual function get invoked?</a>
</li>
<li>SEI CERT C++ Coding Standard <a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/OOP50-CPP.+Do+not+invoke+virtual+functions+from+constructors+or+destructors">OOP50-CPP. Do not invoke virtual functions from constructors or destructors</a>
</li>
<li>ISO C++ FAQ: <a href="https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctor-idiom">Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?</a>
</li>
</references></qhelp>

View File

@@ -1,212 +0,0 @@
/**
* @name Unsafe use of this in constructor
* @description A call to a pure virtual function using a 'this'
* pointer of an object that is under construction
* may lead to undefined behavior.
* @kind path-problem
* @id cpp/unsafe-use-of-this
* @problem.severity error
* @precision very-high
* @tags correctness
* language-features
* security
*/
import cpp
// We don't actually use the global value numbering library in this query, but without it we end up
// recomputing the IR.
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
private import semmle.code.cpp.ir.IR
bindingset[n, result]
int unbind(int n) { result >= n and result <= n }
/** Holds if `p` is the `n`'th parameter of the non-virtual function `f`. */
predicate parameterOf(Parameter p, Function f, int n) {
not f.isVirtual() and f.getParameter(n) = p
}
/**
* Holds if `instr` is the `n`'th argument to a call to the non-virtual function `f`, and
* `init` is the corresponding initiazation instruction that receives the value of `instr` in `f`.
*/
predicate flowIntoParameter(
CallInstruction call, Instruction instr, Function f, int n, InitializeParameterInstruction init
) {
not f.isVirtual() and
call.getPositionalArgument(n) = instr and
f = call.getStaticCallTarget() and
getEnclosingNonVirtualFunctionInitializeParameter(init, f) and
init.getParameter().getIndex() = unbind(n)
}
/**
* Holds if `instr` is an argument to a call to the function `f`, and `init` is the
* corresponding initialization instruction that receives the value of `instr` in `f`.
*/
pragma[noinline]
predicate getPositionalArgumentInitParam(
CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f
) {
exists(int n |
parameterOf(_, f, n) and
flowIntoParameter(call, instr, f, unbind(n), init)
)
}
/**
* Holds if `instr` is the qualifier to a call to the non-virtual function `f`, and
* `init` is the corresponding initiazation instruction that receives the value of
* `instr` in `f`.
*/
pragma[noinline]
predicate getThisArgumentInitParam(
CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f
) {
not f.isVirtual() and
call.getStaticCallTarget() = f and
getEnclosingNonVirtualFunctionInitializeParameter(init, f) and
call.getThisArgument() = instr and
init.getIRVariable() instanceof IRThisVariable
}
/** Holds if `instr` is a `this` pointer used by the call instruction `call`. */
predicate isSink(Instruction instr, CallInstruction call) {
exists(PureVirtualFunction func |
call.getStaticCallTarget() = func and
call.getThisArgument() = instr and
// Weed out implicit calls to destructors of a base class
not func instanceof Destructor
)
}
/** Holds if `init` initializes the `this` pointer in class `c`. */
predicate isSource(InitializeParameterInstruction init, string msg, Class c) {
(
exists(Constructor func |
not func instanceof CopyConstructor and
not func instanceof MoveConstructor and
func = init.getEnclosingFunction() and
msg = "construction"
)
or
init.getEnclosingFunction() instanceof Destructor and msg = "destruction"
) and
init.getIRVariable() instanceof IRThisVariable and
init.getEnclosingFunction().getDeclaringType() = c
}
/**
* Holds if `instr` flows to a sink (which is a use of the value of `instr` as a `this` pointer).
*/
predicate flowsToSink(Instruction instr, Instruction sink) {
flowsFromSource(instr) and
(
isSink(instr, _) and instr = sink
or
exists(Instruction mid |
successor(instr, mid) and
flowsToSink(mid, sink)
)
)
}
/** Holds if `instr` flows from a source. */
predicate flowsFromSource(Instruction instr) {
isSource(instr, _, _)
or
exists(Instruction mid |
successor(mid, instr) and
flowsFromSource(mid)
)
}
/** Holds if `f` is the enclosing non-virtual function of `init`. */
predicate getEnclosingNonVirtualFunctionInitializeParameter(
InitializeParameterInstruction init, Function f
) {
not f.isVirtual() and
init.getEnclosingFunction() = f
}
/** Holds if `f` is the enclosing non-virtual function of `init`. */
predicate getEnclosingNonVirtualFunctionInitializeIndirection(
InitializeIndirectionInstruction init, Function f
) {
not f.isVirtual() and
init.getEnclosingFunction() = f
}
/**
* Holds if `instr` is an argument (or argument indirection) to a call, and
* `succ` is the corresponding initialization instruction in the call target.
*/
predicate flowThroughCallable(Instruction instr, Instruction succ) {
// Flow from an argument to a parameter
exists(CallInstruction call, InitializeParameterInstruction init | init = succ |
getPositionalArgumentInitParam(call, instr, init, call.getStaticCallTarget())
or
getThisArgumentInitParam(call, instr, init, call.getStaticCallTarget())
)
or
// Flow from argument indirection to parameter indirection
exists(
CallInstruction call, ReadSideEffectInstruction read, InitializeIndirectionInstruction init
|
init = succ and
read.getPrimaryInstruction() = call and
getEnclosingNonVirtualFunctionInitializeIndirection(init, call.getStaticCallTarget())
|
exists(int n |
read.getSideEffectOperand().getAnyDef() = instr and
read.getIndex() = n and
init.getParameter().getIndex() = unbind(n)
)
or
call.getThisArgument() = instr and
init.getIRVariable() instanceof IRThisVariable
)
}
/** Holds if `instr` flows to `succ`. */
predicate successor(Instruction instr, Instruction succ) {
succ.(CopyInstruction).getSourceValue() = instr or
succ.(CheckedConvertOrNullInstruction).getUnary() = instr or
succ.(ChiInstruction).getTotal() = instr or
succ.(ConvertInstruction).getUnary() = instr or
succ.(InheritanceConversionInstruction).getUnary() = instr or
flowThroughCallable(instr, succ)
}
/**
* Holds if:
* - `source` is an initialization of a `this` pointer of type `sourceClass`, and
* - `sink` is a use of the `this` pointer, and
* - `call` invokes a pure virtual function using `sink` as the `this` pointer, and
* - `msg` is a string describing whether `source` is from a constructor or destructor.
*/
predicate flows(
Instruction source, string msg, Class sourceClass, Instruction sink, CallInstruction call
) {
isSource(source, msg, sourceClass) and
flowsToSink(source, sink) and
isSink(sink, call)
}
query predicate edges(Instruction a, Instruction b) { successor(a, b) and flowsToSink(b, _) }
query predicate nodes(Instruction n, string key, string val) {
flowsToSink(n, _) and
key = "semmle.label" and
val = n.toString()
}
from Instruction source, Instruction sink, CallInstruction call, string msg, Class sourceClass
where
flows(source, msg, sourceClass, sink, call) and
// Only raise an alert if there is no override of the pure virtual function in any base class.
not exists(Class c | c = sourceClass.getABaseClass*() |
c.getAMemberFunction().getAnOverriddenFunction() = call.getStaticCallTarget()
)
select call.getUnconvertedResultExpression(), source, sink,
"Call to pure virtual function during " + msg

View File

@@ -1,5 +1,4 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies a C/C++ source file has on external libraries.
* @kind treemap

View File

@@ -1,5 +1,4 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,12 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
This metric counts the number of lines of commented-out code in each file. Large amounts of
commented-out code often indicate poorly maintained code.
</p>
</overview>
</qhelp>

View File

@@ -1,12 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<references>
<li>Mark Needham: <a href="http://www.markhneedham.com/blog/2009/01/17/the-danger-of-commenting-out-code/">The danger of commenting out code</a>.</li>
<li>Los Techies: <a href="http://lostechies.com/rodpaddock/2010/12/29/commented-code-technical-debt">Commented Code == Technical Debt</a>.</li>
<li>High Integrity C++ Coding Standard: <a href="http://www.codingstandard.com/rule/2-3-2-do-not-comment-out-code/">2.3.2 Do not comment out code</a>.</li>
</references>
</qhelp>

View File

@@ -1,16 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Duplicated code increases overall code size, making the code base
harder to maintain and harder to understand. It also becomes harder to fix bugs,
since a programmer applying a fix to one copy has to always remember to update
other copies accordingly. Finally, code duplication is generally an indication of
a poorly designed or hastily written code base, which typically suffers from other
problems as well.
</p>
</overview>
</qhelp>

View File

@@ -1,5 +1,4 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file, including code, comment
* and whitespace lines, which are duplicated in at least

View File

@@ -1,35 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
This metric measures the number of lines in a file that are contained within a block that is duplicated elsewhere. These lines may include code, comments and whitespace, and the duplicate block may be in this file or in another file.
</p>
<p>
A file that contains many lines that are duplicated within the code base is problematic
for a number of reasons.
</p>
</overview>
<include src="DuplicationProblems.qhelp" />
<recommendation>
<p>
Refactor files with lots of duplicated code to extract the common code into
a shared library or module.
</p>
</recommendation>
<references>
<li>Wikipedia: <a href="http://en.wikipedia.org/wiki/Duplicate_code">Duplicate code</a>.</li>
<li>M. Fowler, <em>Refactoring</em>. Addison-Wesley, 1999.</li>
</references>
</qhelp>

View File

@@ -27,7 +27,7 @@ and IDE support than macros.</p>
<references>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/preprocessor/macros-c-cpp">Macros (C/C++)</a>
<a href="http://msdn.microsoft.com/en-us/library/503x3e3s%28v=vs.80%29.aspx">Macros</a>
</li>
<li>
<a href="http://www.stroustrup.com/icsm-2012-demacro.pdf">Rejuvenating C++ Programs through

View File

@@ -15,7 +15,7 @@
<references>
<li>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/preprocessor/hash-include-directive-c-cpp">#include directive (C/C++)</a>
<a href="http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=VS.80%29.aspx">The #include Directive</a>
</li>
<li>
<a href="http://gcc.gnu.org/onlinedocs/cpp/Include-Operation.html#Include-Operation">Include operation</a>

View File

@@ -10,8 +10,13 @@ import cpp
*/
class SALMacro extends Macro {
SALMacro() {
this.getFile().getBaseName() =
["sal.h", "specstrings_strict.h", "specstrings.h", "w32p.h", "minwindef.h"] and
exists(string filename | filename = this.getFile().getBaseName() |
filename = "sal.h" or
filename = "specstrings_strict.h" or
filename = "specstrings.h" or
filename = "w32p.h" or
filename = "minwindef.h"
) and
(
// Dialect for Windows 8 and above
this.getName().matches("\\_%\\_")
@@ -53,7 +58,10 @@ class SALAnnotation extends MacroInvocation {
*/
class SALCheckReturn extends SALAnnotation {
SALCheckReturn() {
this.getMacro().(SALMacro).getName() = ["_Check_return_", "_Must_inspect_result_"]
exists(SALMacro m | m = this.getMacro() |
m.getName() = "_Check_return_" or
m.getName() = "_Must_inspect_result_"
)
}
}

View File

@@ -27,7 +27,7 @@ int logicalLength(FunctionDeclarationEntry f) {
count(Stmt s |
s.getEnclosingFunction() = f.getFunction() and
s.getFile() = f.getFile() and
not s instanceof BlockStmt and
not s instanceof Block and
not s instanceof EmptyStmt and
not exists(ForStmt for | s = for.getInitialization()) and
not s.isAffectedByMacro()

View File

@@ -14,7 +14,7 @@ import cpp
class OneLineStmt extends Stmt {
OneLineStmt() {
this.getLocation().getStartLine() = this.getLocation().getEndLine() and
not this instanceof BlockStmt and
not this instanceof Block and
not exists(ForStmt for | this = for.getInitialization()) and
(
// Either this statement is not touched by a macro at all...

View File

@@ -27,7 +27,7 @@ int logicalLength(FunctionDeclarationEntry f) {
count(Stmt s |
s.getEnclosingFunction() = f.getFunction() and
s.getFile() = f.getFile() and
not s instanceof BlockStmt and
not s instanceof Block and
not s instanceof EmptyStmt and
not exists(ForStmt for | s = for.getInitialization()) and
not s.isAffectedByMacro()

View File

@@ -1,48 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
all external APIs that are used with untrusted data, along with how frequently the API is used, and how many
unique sources of untrusted data flow to this API. This query is designed primarily to help identify which APIs
may be relevant for security analysis of this application.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not
modeled as a taint step in the default taint library. External APIs may be from the C++ standard library,
third party dependencies or from internal dependencies. The query will report the function name, along with
either <code>[param x]</code>, where <code>x</code> indicates the position of the parameter receiving the
untrusted data or <code>[qualifier]</code> indicating the untrusted data is used as the qualifier to the
function call.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, no action is required.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query.</li>
<li>If the result represents a call to an external API which transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>If the query were to return the API <code>fputs [param 1]</code>
then we should first consider whether this a security relevant sink. In this case, this is writing to a <code>FILE*</code>, so we should
consider whether this is an XSS sink. If it is, we should confirm that it is handled by the XSS query.</p>
<p>If the query were to return the API <code>strcat [param 1]</code>, then this should be
reviewed as a possible taint step, because tainted data would flow from the 1st argument to the 0th argument of the call.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -1,17 +0,0 @@
/**
* @name Frequency counts for external APIs that are used with untrusted data
* @description This reports the external APIs that are used with untrusted data, along with how
* frequently the API is called, and how many unique sources of untrusted data flow
* to it.
* @id cpp/count-untrusted-data-external-api
* @kind table
* @tags security external/cwe/cwe-20
*/
import cpp
import ExternalAPIs
from ExternalAPIUsedWithUntrustedData externalAPI
select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses,
externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by
numberOfUntrustedSources desc

View File

@@ -1,13 +0,0 @@
#include <cstdio>
void do_get(FILE* request, FILE* response) {
char page[1024];
fgets(page, 1024, request);
char buffer[1024];
strcat(buffer, "The page \"");
strcat(buffer, page);
strcat(buffer, "\" was not found.");
fputs(buffer, response);
}

View File

@@ -1,13 +0,0 @@
#include <cstdio>
void do_get(FILE* request, FILE* response) {
char user_id[1024];
fgets(user_id, 1024, request);
char buffer[1024];
strcat(buffer, "SELECT * FROM user WHERE user_id='");
strcat(buffer, user_id);
strcat(buffer, "'");
// ...
}

View File

@@ -1,50 +0,0 @@
/**
* Definitions for reasoning about untrusted data used in APIs defined outside the
* database.
*/
private import cpp
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
import ExternalAPIsSpecific
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalAPIDataNode extends ExternalAPIDataNode {
UntrustedExternalAPIDataNode() { any(UntrustedDataToExternalAPIConfig c).hasFlow(_, this) }
/** Gets a source of untrusted data which is passed to this external API data node. */
DataFlow::Node getAnUntrustedSource() {
any(UntrustedDataToExternalAPIConfig c).hasFlow(result, this)
}
}
private newtype TExternalAPI =
TExternalAPIParameter(Function f, int index) {
exists(UntrustedExternalAPIDataNode n |
f = n.getExternalFunction() and
index = n.getIndex()
)
}
/** An external API which is used with untrusted data. */
class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
/** Gets a possibly untrusted use of this external API. */
UntrustedExternalAPIDataNode getUntrustedDataNode() {
this = TExternalAPIParameter(result.getExternalFunction(), result.getIndex())
}
/** Gets the number of untrusted sources used with this external API. */
int getNumberOfUntrustedSources() {
result = strictcount(getUntrustedDataNode().getAnUntrustedSource())
}
/** Gets a textual representation of this element. */
string toString() {
exists(Function f, int index, string indexString |
if index = -1 then indexString = "qualifier" else indexString = "param " + index
|
this = TExternalAPIParameter(f, index) and
result = f.toString() + " [" + indexString + "]"
)
}
}

View File

@@ -1,56 +0,0 @@
/**
* Provides AST-specific definitions for use in the `ExternalAPI` library.
*/
import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.models.interfaces.DataFlow
import SafeExternalAPIFunction
/** A node representing untrusted data being passed to an external API. */
class ExternalAPIDataNode extends DataFlow::Node {
Call call;
int i;
ExternalAPIDataNode() {
// Argument to call to a function
(
this.asExpr() = call.getArgument(i)
or
i = -1 and this.asExpr() = call.getQualifier()
) and
exists(Function f |
f = call.getTarget() and
// Defined outside the source archive
not f.hasDefinition() and
// Not already modeled as a dataflow or taint step
not f instanceof DataFlowFunction and
not f instanceof TaintFunction and
// Not a call to a known safe external API
not f instanceof SafeExternalAPIFunction
)
}
/** Gets the called API `Function`. */
Function getExternalFunction() { result = call.getTarget() }
/** Gets the index which is passed untrusted data (where -1 indicates the qualifier). */
int getIndex() { result = i }
/** Gets the description of the function being called. */
string getFunctionDescription() { result = getExternalFunction().toString() }
}
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */
class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration {
UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" }
override predicate isSource(DataFlow::Node source) {
exists(RemoteFlowFunction remoteFlow |
remoteFlow = source.asExpr().(Call).getTarget() and
remoteFlow.hasRemoteFlowSource(_, _)
)
}
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode }
}

View File

@@ -1,48 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
all external APIs that are used with untrusted data, along with how frequently the API is used, and how many
unique sources of untrusted data flow to this API. This query is designed primarily to help identify which APIs
may be relevant for security analysis of this application.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not
modeled as a taint step in the default taint library. External APIs may be from the C++ standard library,
third party dependencies or from internal dependencies. The query will report the function name, along with
either <code>[param x]</code>, where <code>x</code> indicates the position of the parameter receiving the
untrusted data or <code>[qualifier]</code> indicating the untrusted data is used as the qualifier to the
function call.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, no action is required.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query.</li>
<li>If the result represents a call to an external API which transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>If the query were to return the API <code>fputs [param 1]</code>
then we should first consider whether this a security relevant sink. In this case, this is writing to a <code>FILE*</code>, so we should
consider whether this is an XSS sink. If it is, we should confirm that it is handled by the XSS query.</p>
<p>If the query were to return the API <code>strcat [param 1]</code>, then this should be
reviewed as a possible taint step, because tainted data would flow from the 1st argument to the 0th argument of the call.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -1,17 +0,0 @@
/**
* @name Frequency counts for external APIs that are used with untrusted data
* @description This reports the external APIs that are used with untrusted data, along with how
* frequently the API is called, and how many unique sources of untrusted data flow
* to it.
* @id cpp/count-untrusted-data-external-api-ir
* @kind table
* @tags security external/cwe/cwe-20
*/
import cpp
import ir.ExternalAPIs
from ExternalAPIUsedWithUntrustedData externalAPI
select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses,
externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by
numberOfUntrustedSources desc

View File

@@ -1,59 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
external APIs that use untrusted data. The results are not filtered, so you can audit all examples.
The query provides data for security reviews of the application and you can also use it to identify external APIs
that should be modeled as either taint steps, or sinks for specific problems.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not modeled
as a taint step in the default taint library. External APIs may be from the
C++ standard library, third-party dependencies or from internal dependencies. The query reports uses of
untrusted data in either the qualifier or as one of the arguments of external APIs.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, confirm that the result is reported by the relevant query, or
that the result is a false positive because this data is sanitized.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query,
and confirm that the result is either found, or is safe due to appropriate sanitization.</li>
<li>If the result represents a call to an external API that transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>In this first example, input is read from <code>fgets</code> and then ultimately used in a call to the
<code>fputs</code> external API:</p>
<sample src="ExternalAPISinkExample.cpp" />
<p>This is an XSS sink. The XSS query should therefore be reviewed to confirm that this sink is appropriately modeled,
and if it is, to confirm that the query reports this particular result, or that the result is a false positive due to
some existing sanitization.</p>
<p>In this second example, again a request parameter is read from <code>fgets</code>.</p>
<sample src="ExternalAPITaintStepExample.cpp" />
<p>If the query reported the call to <code>strcat</code> on line 9, this would suggest that this external API is
not currently modeled as a taint step in the taint tracking library. The next step would be to model this as a taint step, then
re-run the query to determine what additional results might be found. In this example, it seems likely that <code>buffer</code>
will be executed as an SQL query, potentially leading to an SQL injection vulnerability.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -1,21 +0,0 @@
/**
* @name Untrusted data passed to external API
* @description Data provided remotely is used in this external API without sanitization, which could be a security risk.
* @id cpp/untrusted-data-to-external-api-ir
* @kind path-problem
* @precision low
* @problem.severity error
* @tags security external/cwe/cwe-20
*/
import cpp
import semmle.code.cpp.ir.dataflow.TaintTracking
import ir.ExternalAPIs
import semmle.code.cpp.security.FlowSources
import DataFlow::PathGraph
from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink,
"Call to " + sink.getNode().(ExternalAPIDataNode).getExternalFunction().toString() +
" with untrusted data from $@.", source, source.getNode().(RemoteFlowSource).getSourceType()

View File

@@ -1,24 +0,0 @@
/**
* Provides a class for modeling external functions that are "safe" from a security perspective.
*/
private import cpp
private import semmle.code.cpp.models.interfaces.SideEffect
/**
* A `Function` that is considered a "safe" external API from a security perspective.
*/
abstract class SafeExternalAPIFunction extends Function { }
/** The default set of "safe" external APIs. */
private class DefaultSafeExternalAPIFunction extends SafeExternalAPIFunction {
DefaultSafeExternalAPIFunction() {
// If a function does not write to any of its arguments, we consider it safe to
// pass untrusted data to it. This means that string functions such as `strcmp`
// and `strlen`, as well as memory functions such as `memcmp`, are considered safe.
exists(SideEffectFunction model | model = this |
model.hasOnlySpecificWriteSideEffects() and
not model.hasSpecificWriteSideEffect(_, _, _)
)
}
}

View File

@@ -1,59 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
external APIs that use untrusted data. The results are not filtered, so you can audit all examples.
The query provides data for security reviews of the application and you can also use it to identify external APIs
that should be modeled as either taint steps, or sinks for specific problems.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not modeled
as a taint step in the default taint library. External APIs may be from the
C++ standard library, third-party dependencies or from internal dependencies. The query reports uses of
untrusted data in either the qualifier or as one of the arguments of external APIs.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, confirm that the result is reported by the relevant query, or
that the result is a false positive because this data is sanitized.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query,
and confirm that the result is either found, or is safe due to appropriate sanitization.</li>
<li>If the result represents a call to an external API that transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>In this first example, input is read from <code>fgets</code> and then ultimately used in a call to the
<code>fputs</code> external API:</p>
<sample src="ExternalAPISinkExample.cpp" />
<p>This is an XSS sink. The XSS query should therefore be reviewed to confirm that this sink is appropriately modeled,
and if it is, to confirm that the query reports this particular result, or that the result is a false positive due to
some existing sanitization.</p>
<p>In this second example, again a request parameter is read from <code>fgets</code>.</p>
<sample src="ExternalAPITaintStepExample.cpp" />
<p>If the query reported the call to <code>strcat</code> on line 9, this would suggest that this external API is
not currently modeled as a taint step in the taint tracking library. The next step would be to model this as a taint step, then
re-run the query to determine what additional results might be found. In this example, it seems likely that <code>buffer</code>
will be executed as an SQL query, potentially leading to an SQL injection vulnerability.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -1,20 +0,0 @@
/**
* @name Untrusted data passed to external API
* @description Data provided remotely is used in this external API without sanitization, which could be a security risk.
* @id cpp/untrusted-data-to-external-api
* @kind path-problem
* @precision low
* @problem.severity error
* @tags security external/cwe/cwe-20
*/
import cpp
import semmle.code.cpp.dataflow.TaintTracking
import ExternalAPIs
import DataFlow::PathGraph
from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink,
"Call to " + sink.getNode().(ExternalAPIDataNode).getExternalFunction().toString() +
" with untrusted data from $@.", source, source.toString()

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