Compare commits

..

9 Commits

Author SHA1 Message Date
Esben Sparre Andreasen
96d796579e XXX: add hacky SQL changes for experiments 2020-06-30 09:54:59 +02:00
Esben Sparre Andreasen
246f8755e4 JS: improve CoreKnowledge.qll 2020-06-30 09:54:59 +02:00
Esben Sparre Andreasen
f2e43ad5da JS: add boosted js/sql-injection, js/path-injection, js/xss 2020-06-30 09:54:59 +02:00
Esben Sparre Andreasen
e723c6e790 JS: core improvements 2020-06-25 11:53:42 +02:00
Esben Sparre Andreasen
f60a82dfc3 Merge remote-tracking branch 'origin/master' into HEAD 2020-06-23 12:21:26 +02:00
Henry Mercer
092b0c867e Docs: Fix punctation in section header 2020-06-01 12:15:39 +01:00
Henry Mercer
9ca415f297 Merge pull request #3412 from Z80coder/patch-1
correct "known endpoints" to "candidate endpoints"
2020-05-05 11:25:44 +01:00
Ian Wright
6d02494e61 correct "known endpoints" to "candidate endpoints" 2020-05-05 11:23:32 +01:00
Henry Mercer
15c3820fd9 ATM: Initial commit of ATM for JavaScript beta 2020-05-05 11:15:27 +01:00
8418 changed files with 196864 additions and 648560 deletions

View File

@@ -1,6 +1,5 @@
{ "provide": [ "*/ql/src/qlpack.yml",
"*/ql/test/qlpack.yml",
"*/ql/examples/qlpack.yml",
"*/upgrades/qlpack.yml",
"misc/legacy-support/*/qlpack.yml",
"misc/suite-helpers/qlpack.yml" ] }

View File

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

View File

@@ -2,10 +2,3 @@ name: "CodeQL config"
queries:
- uses: security-and-quality
paths-ignore:
- '/cpp/'
- '/java/'
- '/python/'
- '/javascript/ql/test'
- '/javascript/extractor/tests'

View File

@@ -1,23 +0,0 @@
name: Check change note
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

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

View File

@@ -2,15 +2,7 @@ name: "Code scanning - action"
on:
push:
branches:
- main
- 'rc/*'
pull_request:
branches:
- main
- 'rc/*'
paths:
- 'csharp/**'
schedule:
- cron: '0 9 * * 1'
@@ -22,7 +14,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1

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

3
.gitignore vendored
View File

@@ -17,9 +17,6 @@
# Byte-compiled python files
*.pyc
# python virtual environment folder
.venv/
# It's useful (though not required) to be able to unpack codeql in the ql checkout itself
/codeql/

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

@@ -1,3 +0,0 @@
{
"omnisharp.autoStart": false
}

View File

@@ -4,16 +4,17 @@
/javascript/ @github/codeql-javascript
/python/ @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
# 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
# Notify members of codeql-go about PRs to the shared data-flow library files
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
# 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

View File

@@ -38,8 +38,6 @@ If you have an idea for a query that you would like to share with other CodeQL u
- The queries and libraries must be autoformatted, for example using the "Format Document" command in [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode/procedures/about-codeql-for-vscode.html).
If you prefer, you can use this [pre-commit hook](misc/scripts/pre-commit) that automatically checks whether your files are correctly formatted. See the [pre-commit hook installation guide](docs/pre-commit-hook-setup.md) for instructions on how to install the hook.
4. **Compilation**
- Compilation of the query and any associated libraries and tests must be resilient to future development of the [supported](docs/supported-queries.md) libraries. This means that the functionality cannot use internal libraries, cannot depend on the output of `getAQlClass`, and cannot make use of regexp matching on `toString`.
@@ -49,11 +47,7 @@ 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.
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.
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.
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

@@ -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

@@ -13,8 +13,6 @@ The following changes in version 1.25 affect C/C++ analysis in all applications.
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Uncontrolled format string (`cpp/tainted-format-string`) | | This query is now displayed by default on LGTM. |
| Uncontrolled format string (through global variable) (`cpp/tainted-format-string-through-global`) | | This query is now displayed by default on LGTM. |
## Changes to libraries

View File

@@ -28,51 +28,27 @@ The following changes in version 1.25 affect C# analysis in all applications.
such as `A<int>.B`, no longer are considered unbound generics. (Such nested types do,
however, still have relevant `.getSourceDeclaration()`s, for example `A<>.B`.)
* 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
`GetF2F1()` in
```csharp
class C1
{
string F1;
}
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
`GetF2F1()` in
```csharp
class C1
{
string F1;
}
class C2
{
C1 F2;
class C2
{
C1 F2;
string GetF2F1() => F2.F1; // Nested field read
string GetF2F1() => F2.F1; // Nested field read
void M()
{
F2 = new C1() { F1 = "taint" };
Sink(GetF2F1()); // NEW: "taint" reaches here
}
}
```
- Flow through collections is now modeled precisely. For example, instead of modeling an array
store `a[i] = x` as a taint-step from `x` to `a`, we now model it as a data-flow step that
stores `x` into `a`. To get the value back out, a matching read step must be taken.
For source-code based data-flow analysis, the following constructs are modeled as stores into
collections:
- Direct array assignments, `a[i] = x`.
- Array initializers, `new [] { x }`.
- C# 6-style array initializers, `new C() { Array = { [i] = x } }`.
- Call arguments that match a `params` parameter, where the C# compiler creates an array under-the-hood.
- `yield return` statements.
The following source-code constructs read from a collection:
- Direct array reads, `a[i]`.
- `foreach` statements.
For calls out to library code, existing flow summaries have been refined to precisely
capture how they interact with collection contents. For example, a call to
`System.Collections.Generic.List<T>.Add(T)` stores the value of the argument into the
qualifier, and a call to `System.Collections.Generic.List<T>.get_Item(int)` (that is, an
indexer call) reads contents out of the qualifier. Moreover, the effect of
collection-clearing methods such as `System.Collections.Generic.List<T>.Clear()` is now
also modeled.
void M()
{
F2 = new C1() { F1 = "taint" };
Sink(GetF2F1()); // NEW: "taint" reaches here
}
}
```
## Changes to autobuilder

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

@@ -6,33 +6,23 @@
- [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
- [bluebird](http://bluebirdjs.com/)
- [express](https://www.npmjs.com/package/express)
- [execa](https://www.npmjs.com/package/execa)
- [fancy-log](https://www.npmjs.com/package/fancy-log)
- [fastify](https://www.npmjs.com/package/fastify)
- [foreground-child](https://www.npmjs.com/package/foreground-child)
- [fstream](https://www.npmjs.com/package/fstream)
- [jGrowl](https://github.com/stanlemon/jGrowl)
- [jQuery](https://jquery.com/)
- [marsdb](https://www.npmjs.com/package/marsdb)
- [micro](https://www.npmjs.com/package/micro/)
- [minimongo](https://www.npmjs.com/package/minimongo/)
- [mssql](https://www.npmjs.com/package/mssql)
- [mysql](https://www.npmjs.com/package/mysql)
- [npmlog](https://www.npmjs.com/package/npmlog)
- [opener](https://www.npmjs.com/package/opener)
- [pg](https://www.npmjs.com/package/pg)
- [sequelize](https://www.npmjs.com/package/sequelize)
- [spanner](https://www.npmjs.com/package/spanner)
- [sqlite](https://www.npmjs.com/package/sqlite)
- [ssh2-streams](https://www.npmjs.com/package/ssh2-streams)
- [ssh2](https://www.npmjs.com/package/ssh2)
- [vue](https://www.npmjs.com/package/vue)
- [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 code embedded in HTML and Vue files is now extracted and analyzed.
* TypeScript 3.9 is now supported.
* The analysis of sanitizers has improved, leading to more accurate
results from the security queries.
@@ -41,17 +31,10 @@
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| DOM text reinterpreted as HTML (`js/xss-through-dom`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities where existing text from the DOM is used as HTML. Results are shown on LGTM by default. |
| Cross-site scripting through DOM (`js/xss-through-dom`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities where existing text from the DOM is used as HTML. Results are not shown on LGTM by default. |
| Incomplete HTML attribute sanitization (`js/incomplete-html-attribute-sanitization`) | security, external/cwe/cwe-20, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities due to incomplete sanitization of HTML meta-characters. Results are shown on LGTM by default. |
| Unsafe expansion of self-closing HTML tag (`js/unsafe-html-expansion`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities caused by unsafe expansion of self-closing HTML tags. |
| Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | correctness, security, external/cwe/cwe-078, external/cwe/cwe-088 | Highlights potential command injections due to a shell command being constructed from library inputs. Results are shown on LGTM by default. |
| Download of sensitive file through insecure connection (`js/insecure-download`) | security, external/cwe/cwe-829 | Highlights downloads of sensitive files through an unencrypted protocol. Results are shown on LGTM by default. |
| Exposure of private files (`js/exposure-of-private-files`) | security, external/cwe/cwe-200 | Highlights servers that serve private files. Results are shown on LGTM by default. |
| Creating biased random numbers from a cryptographically secure source (`js/biased-cryptographic-random`) | security, external/cwe/cwe-327 | Highlights mathematical operations on cryptographically secure numbers that can create biased results. Results are shown on LGTM by default. |
| Storage of sensitive information in build artifact (`js/build-artifact-leak`) | security, external/cwe/cwe-312 | Highlights storage of sensitive information in build artifacts. Results are shown on LGTM by default. |
| Improper code sanitization (`js/bad-code-sanitization`) | security, external/cwe/cwe-094, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights string concatenation where code is constructed without proper sanitization. Results are shown on LGTM by default. |
| Disabling certificate validation (`js/disabling-certificate-validation`) | security, external/cwe-295 | Highlights locations where SSL certificate validation is disabled. Results are shown on LGTM by default. |
| Incomplete multi-character sanitization (`js/incomplete-multi-character-sanitization`) | correctness, security, external/cwe/cwe-20, external/cwe/cwe-116 | Highlights sanitizers that fail to remove dangerous substrings completely. Results are shown on LGTM by default. |
## Changes to existing queries
@@ -60,19 +43,15 @@
| Client-side cross-site scripting (`js/xss`) | Fewer results | This query now recognizes additional safe patterns of constructing HTML. |
| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | Fewer results | This query now recognizes additional safe patterns of doing URL redirects. |
| Code injection (`js/code-injection`) | More results | More potential vulnerabilities involving NoSQL code operators are now recognized. |
| Exception text reinterpreted as HTML (`js/exception-xss`) | Rephrased and changed visibility | Rephrased name and alert message. Severity lowered from error to warning. Results are now shown on LGTM by default. |
| Expression has no effect (`js/useless-expression`) | Fewer results | This query no longer flags an expression when that expression is the only content of the containing file. |
| Hard-coded credentials (`js/hardcoded-credentials`) | More results | This query now recognizes hard-coded credentials sent via HTTP authorization headers. |
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes additional url scheme checks. |
| Insecure randomness (`js/insecure-randomness`) | Fewer results | This query now recognizes when an insecure random value is used as a fallback when secure random values are unsupported. |
| Misspelled variable name (`js/misspelled-variable-name`) | Message changed | The message for this query now correctly identifies the misspelled variable in additional cases. |
| Non-linear pattern (`js/non-linear-pattern`) | Fewer duplicates and message changed | This query now generates fewer duplicate alerts and has a clearer explanation in case of type annotations used in a pattern. |
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | More results | This query now recognizes additional utility functions as vulnerable to prototype polution. |
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional command execution calls. |
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional file system calls. |
| Uncontrolled data used in path expression (`js/path-injection`) | Fewer results | This query no longer flags paths that have been checked to be part of a collection. |
| Unknown directive (`js/unknown-directive`) | Fewer results | This query no longer flags directives generated by the Babel compiler. |
| Unneeded defensive code (`js/unneeded-defensive-code`) | Fewer false-positive results | This query now recognizes checks meant to handle the `document.all` object. |
| Unused property (`js/unused-property`) | Fewer results | This query no longer flags properties of objects that are operands of `yield` expressions. |
| Zip Slip (`js/zipslip`) | More results | This query now recognizes additional vulnerabilities. |
@@ -108,4 +87,3 @@ The following low-precision queries are no longer run by default on LGTM (their
- `ParameterNode.asExpr()` and `.getAstNode()` now gets the parameter's AST node, whereas previously it had no result.
- `Expr.flow()` now has a more meaningful result for destructuring patterns. Previously this node was disconnected from the data flow graph. Now it represents the values being destructured by the pattern.
* The global data-flow and taint-tracking libraries now model indirect parameter accesses through the `arguments` object in some cases, which may lead to additional results from some of the security queries, particularly "Prototype pollution in utility function".
* The predicates `Type.getProperty()` and variants of `Type.getMethod()` have been deprecated due to lack of use-cases. Looking up a named property of a static type is no longer supported, favoring faster extraction times instead.

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

@@ -1,31 +0,0 @@
# Improvements to C/C++ analysis
The following changes in version 1.26 affect C/C++ analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **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 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

@@ -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

@@ -1,73 +0,0 @@
# Improvements to JavaScript analysis
## 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
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## Changes to existing queries
| **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

@@ -1,37 +0,0 @@
# Improvements to Python analysis
The following changes in version 1.26 affect Python analysis in all applications.
## General improvements
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
|`py/unsafe-deserialization` | Different results. | The underlying data flow library has been changed. See below for more details. |
|`py/path-injection` | Different results. | The underlying data flow library has been changed. See below for more details. |
|`py/command-line-injection` | Different results. | The underlying data flow library has been changed. See below for more details. |
|`py/reflective-xss` | Different results. | The underlying data flow library has been changed. See below for more details. |
|`py/sql-injection` | Different results. | The underlying data flow library has been changed. See below for more details. |
|`py/code-injection` | Different results. | The underlying data flow library has been changed. See below for more details. |
## Changes to libraries
* Some of the security queries now use the shared data flow library for data flow and taint tracking. This has resulted in an overall more robust and accurate analysis. The libraries mentioned below have been modelled in this new framework. Other libraries (e.g. the web framework `CherryPy`) have not been modelled yet, and this may lead to a temporary loss of results for these frameworks.
* Improved modelling of the following serialization libraries:
- `PyYAML`
- `dill`
- `pickle`
- `marshal`
* Improved modelling of the following web frameworks:
- `Django` (Note that modelling of class-based response handlers is currently incomplete.)
- `Flask`
* Support for Werkzeug `MultiDict`.
* Support for the [Python Database API Specification v2.0 (PEP-249)](https://www.python.org/dev/peps/pep-0249/), including the following libraries:
- `MySQLdb`
- `mysql-connector-python`
- `django.db`
* Improved modelling of the following command execution libraries:
- `Fabric`
- `Invoke`
* Improved modelling of security-related standard library modules, such as `os`, `popen2`, `platform`, and `base64`.
* The original versions of the updated queries have been preserved [here](https://github.com/github/codeql/tree/main/python/ql/src/experimental/Security-old-dataflow).
* Added taint tracking support for string formatting through f-strings.

View File

@@ -1,5 +1,5 @@
{
"DataFlow Java/C++/C#/Python": [
"DataFlow Java/C++/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll",
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll",
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll",
@@ -18,67 +18,32 @@
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll",
"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"
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll"
],
"DataFlow Java/C++/C#/Python Common": [
"DataFlow Java/C++/C# 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"
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll"
],
"TaintTracking::Configuration Java/C++/C#/Python": [
"TaintTracking::Configuration Java/C++/C#": [
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll",
"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"
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll"
],
"DataFlow Java/C++/C#/Python Consistency checks": [
"DataFlow Java/C++/C# 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"
],
"DataFlow Java/C# Flow Summaries": [
"java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll"
],
"SsaReadPosition Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
],
"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"
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll"
],
"C++ SubBasicBlocks": [
"cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
@@ -117,7 +82,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",
@@ -139,11 +104,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"
],
@@ -355,89 +320,11 @@
"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",
"java/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.inc.qhelp": [
"cpp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp",
"javascript/ql/src/Metrics/DuplicationProblems.inc.qhelp",
"python/ql/src/Metrics/DuplicationProblems.inc.qhelp"
],
"CommentedOutCodeQuery.inc.qhelp": [
"cpp/ql/src/Documentation/CommentedOutCodeQuery.inc.qhelp",
"python/ql/src/Lexical/CommentedOutCodeQuery.inc.qhelp",
"csharp/ql/src/Bad Practices/Comments/CommentedOutCodeQuery.inc.qhelp",
"java/ql/src/Violations of Best Practice/Comments/CommentedOutCodeQuery.inc.qhelp",
"javascript/ql/src/Comments/CommentedOutCodeQuery.inc.qhelp"
],
"FLinesOfCodeReferences.inc.qhelp": [
"java/ql/src/Metrics/Files/FLinesOfCodeReferences.inc.qhelp",
"javascript/ql/src/Metrics/FLinesOfCodeReferences.inc.qhelp"
],
"FCommentRatioCommon.inc.qhelp": [
"java/ql/src/Metrics/Files/FCommentRatioCommon.inc.qhelp",
"javascript/ql/src/Metrics/FCommentRatioCommon.inc.qhelp"
],
"FLinesOfCodeOverview.inc.qhelp": [
"java/ql/src/Metrics/Files/FLinesOfCodeOverview.inc.qhelp",
"javascript/ql/src/Metrics/FLinesOfCodeOverview.inc.qhelp"
],
"CommentedOutCodeMetricOverview.inc.qhelp": [
"cpp/ql/src/Metrics/Files/CommentedOutCodeMetricOverview.inc.qhelp",
"csharp/ql/src/Metrics/Files/CommentedOutCodeMetricOverview.inc.qhelp",
"java/ql/src/Metrics/Files/CommentedOutCodeMetricOverview.inc.qhelp",
"javascript/ql/src/Comments/CommentedOutCodeMetricOverview.inc.qhelp",
"python/ql/src/Lexical/CommentedOutCodeMetricOverview.inc.qhelp"
],
"FLinesOfDuplicatedCodeCommon.inc.qhelp": [
"cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.inc.qhelp",
"java/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.inc.qhelp",
"javascript/ql/src/Metrics/FLinesOfDuplicatedCodeCommon.inc.qhelp",
"python/ql/src/Metrics/FLinesOfDuplicatedCodeCommon.inc.qhelp"
],
"CommentedOutCodeReferences.inc.qhelp": [
"cpp/ql/src/Metrics/Files/CommentedOutCodeReferences.inc.qhelp",
"csharp/ql/src/Metrics/Files/CommentedOutCodeReferences.inc.qhelp",
"java/ql/src/Metrics/Files/CommentedOutCodeReferences.inc.qhelp",
"javascript/ql/src/Comments/CommentedOutCodeReferences.inc.qhelp",
"python/ql/src/Lexical/CommentedOutCodeReferences.inc.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"
],
"SSA C#": [
"csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll"
],
"CryptoAlgorithms Python/JS": [
"javascript/ql/src/semmle/javascript/security/CryptoAlgorithms.qll",
"python/ql/src/semmle/crypto/Crypto.qll"
]
}
}

View File

@@ -1,102 +0,0 @@
#!/usr/bin/env python3
import os
import re
path = os.path
needs_an_re = re.compile(r'^(?!Unary)[AEIOU]') # Name requiring "an" instead of "a".
start_qldoc_re = re.compile(r'^\s*/\*\*') # Start of a QLDoc comment
end_qldoc_re = re.compile(r'\*/\s*$') # End of a QLDoc comment
blank_qldoc_line_re = re.compile(r'^\s*\*\s*$') # A line in a QLDoc comment with only the '*'
instruction_class_re = re.compile(r'^class (?P<name>[A-aa-z0-9]+)Instruction\s') # Declaration of an `Instruction` class
opcode_base_class_re = re.compile(r'^abstract class (?P<name>[A-aa-z0-9]+)Opcode\s') # Declaration of an `Opcode` base class
opcode_class_re = re.compile(r'^ class (?P<name>[A-aa-z0-9]+)\s') # Declaration of an `Opcode` class
script_dir = path.realpath(path.dirname(__file__))
instruction_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll'))
opcode_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll'))
# Scan `Instruction.qll`, keeping track of the QLDoc comment attached to each declaration of a class
# whose name ends with `Instruction`.
instruction_comments = {}
in_qldoc = False
saw_blank_line_in_qldoc = False
qldoc_lines = []
with open(instruction_path, 'r', encoding='utf-8') as instr:
for line in instr:
if in_qldoc:
if end_qldoc_re.search(line):
qldoc_lines.append(line)
in_qldoc = False
elif blank_qldoc_line_re.search(line):
# We're going to skip any lines after the first blank line, to avoid duplicating all
# of the verbose description.
saw_blank_line_in_qldoc = True
elif not saw_blank_line_in_qldoc:
qldoc_lines.append(line)
else:
if start_qldoc_re.search(line):
# Starting a new QLDoc comment.
saw_blank_line_in_qldoc = False
qldoc_lines.append(line)
if not end_qldoc_re.search(line):
in_qldoc = True
else:
instruction_match = instruction_class_re.search(line)
if instruction_match:
# Found the declaration of an `Instruction` class. Record the QLDoc comments.
instruction_comments[instruction_match.group('name')] = qldoc_lines
qldoc_lines = []
# Scan `Opcode.qll`. Whenever we see the declaration of an `Opcode` class for which we have a
# corresponding `Instruction` class, we'll attach a copy of the `Instruction`'s QLDoc comment.
in_qldoc = False
qldoc_lines = []
output_lines = []
with open(opcode_path, 'r', encoding='utf-8') as opcode:
for line in opcode:
if in_qldoc:
qldoc_lines.append(line)
if end_qldoc_re.search(line):
in_qldoc = False
else:
if start_qldoc_re.search(line):
qldoc_lines.append(line)
if not end_qldoc_re.search(line):
in_qldoc = True
else:
name_without_suffix = None
name = None
indent = ''
opcode_base_match = opcode_base_class_re.search(line)
if opcode_base_match:
name_without_suffix = opcode_base_match.group('name')
name = name_without_suffix + 'Opcode'
else:
opcode_match = opcode_class_re.search(line)
if opcode_match:
name_without_suffix = opcode_match.group('name')
name = name_without_suffix
# Indent by two additional spaces, since opcodes are declared in the
# `Opcode` module.
indent = ' '
if name_without_suffix:
# Found an `Opcode` that matches a known `Instruction`. Replace the QLDoc with
# a copy of the one from the `Instruction`.
if instruction_comments.get(name_without_suffix):
article = 'an' if needs_an_re.search(name_without_suffix) else 'a'
qldoc_lines = [
indent + '/**\n',
indent + ' * The `Opcode` for ' + article + ' `' + name_without_suffix + 'Instruction`.\n',
indent + ' *\n',
indent + ' * See the `' + name_without_suffix + 'Instruction` documentation for more details.\n',
indent + ' */\n'
]
output_lines.extend(qldoc_lines)
qldoc_lines = []
output_lines.append(line)
# Write out the updated `Opcode.qll`
with open(opcode_path, 'w', encoding='utf-8') as opcode:
opcode.writelines(output_lines)

View File

@@ -1,13 +0,0 @@
obj/
TestResults/
*.manifest
*.pdb
*.suo
*.mdb
*.vsmdi
csharp.log
**/bin/Debug
**/bin/Release
*.tlog
.vs
*.user

View File

@@ -1,323 +0,0 @@
using Xunit;
using Semmle.Autobuild.Shared;
using System.Collections.Generic;
using System;
using System.Linq;
using Microsoft.Build.Construction;
using System.Xml;
using System.IO;
namespace Semmle.Autobuild.Cpp.Tests
{
/// <summary>
/// Test class to script Autobuilder scenarios.
/// For most methods, it uses two fields:
/// - an IList to capture the the arguments passed to it
/// - an IDictionary of possible return values.
/// </summary>
class TestActions : IBuildActions
{
/// <summary>
/// List of strings passed to FileDelete.
/// </summary>
public IList<string> FileDeleteIn = new List<string>();
void IBuildActions.FileDelete(string file)
{
FileDeleteIn.Add(file);
}
public IList<string> FileExistsIn = new List<string>();
public IDictionary<string, bool> FileExists = new Dictionary<string, bool>();
bool IBuildActions.FileExists(string file)
{
FileExistsIn.Add(file);
if (FileExists.TryGetValue(file, out var ret))
return ret;
if (FileExists.TryGetValue(System.IO.Path.GetFileName(file), out ret))
return ret;
throw new ArgumentException("Missing FileExists " + file);
}
public IList<string> RunProcessIn = new List<string>();
public IDictionary<string, int> RunProcess = new Dictionary<string, int>();
public IDictionary<string, string> RunProcessOut = new Dictionary<string, string>();
public IDictionary<string, string> RunProcessWorkingDirectory = new Dictionary<string, string>();
public HashSet<string> CreateDirectories { get; } = new HashSet<string>();
public HashSet<(string, string)> DownloadFiles { get; } = new HashSet<(string, string)>();
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? env, out IList<string> stdOut)
{
var pattern = cmd + " " + args;
RunProcessIn.Add(pattern);
if (RunProcessOut.TryGetValue(pattern, out var str))
stdOut = str.Split("\n");
else
throw new ArgumentException("Missing RunProcessOut " + pattern);
RunProcessWorkingDirectory.TryGetValue(pattern, out var wd);
if (wd != workingDirectory)
throw new ArgumentException("Missing RunProcessWorkingDirectory " + pattern);
if (RunProcess.TryGetValue(pattern, out var ret))
return ret;
throw new ArgumentException("Missing RunProcess " + pattern);
}
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? env)
{
var pattern = cmd + " " + args;
RunProcessIn.Add(pattern);
RunProcessWorkingDirectory.TryGetValue(pattern, out var wd);
if (wd != workingDirectory)
throw new ArgumentException("Missing RunProcessWorkingDirectory " + pattern);
if (RunProcess.TryGetValue(pattern, out var ret))
return ret;
throw new ArgumentException("Missing RunProcess " + pattern);
}
public IList<string> DirectoryDeleteIn = new List<string>();
void IBuildActions.DirectoryDelete(string dir, bool recursive)
{
DirectoryDeleteIn.Add(dir);
}
public IDictionary<string, bool> DirectoryExists = new Dictionary<string, bool>();
public IList<string> DirectoryExistsIn = new List<string>();
bool IBuildActions.DirectoryExists(string dir)
{
DirectoryExistsIn.Add(dir);
if (DirectoryExists.TryGetValue(dir, out var ret))
return ret;
throw new ArgumentException("Missing DirectoryExists " + dir);
}
public IDictionary<string, string?> GetEnvironmentVariable = new Dictionary<string, string?>();
string? IBuildActions.GetEnvironmentVariable(string name)
{
if (GetEnvironmentVariable.TryGetValue(name, out var ret))
return ret;
throw new ArgumentException("Missing GetEnvironmentVariable " + name);
}
public string GetCurrentDirectory = "";
string IBuildActions.GetCurrentDirectory()
{
return GetCurrentDirectory;
}
public IDictionary<string, string> EnumerateFiles = new Dictionary<string, string>();
IEnumerable<string> IBuildActions.EnumerateFiles(string dir)
{
if (EnumerateFiles.TryGetValue(dir, out var str))
return str.Split("\n");
throw new ArgumentException("Missing EnumerateFiles " + dir);
}
public IDictionary<string, string> EnumerateDirectories = new Dictionary<string, string>();
IEnumerable<string> IBuildActions.EnumerateDirectories(string dir)
{
if (EnumerateDirectories.TryGetValue(dir, out var str))
return string.IsNullOrEmpty(str) ? Enumerable.Empty<string>() : str.Split("\n");
throw new ArgumentException("Missing EnumerateDirectories " + dir);
}
public bool IsWindows;
bool IBuildActions.IsWindows() => IsWindows;
string IBuildActions.PathCombine(params string[] parts)
{
return string.Join(IsWindows ? '\\' : '/', parts.Where(p => !string.IsNullOrWhiteSpace(p)));
}
string IBuildActions.GetFullPath(string path) => path;
string? IBuildActions.GetFileName(string? path) => Path.GetFileName(path?.Replace('\\', '/'));
public string? GetDirectoryName(string? path)
{
var dir = Path.GetDirectoryName(path?.Replace('\\', '/'));
return dir is null ? path : path?.Substring(0, dir.Length);
}
void IBuildActions.WriteAllText(string filename, string contents)
{
}
public IDictionary<string, XmlDocument> LoadXml = new Dictionary<string, XmlDocument>();
XmlDocument IBuildActions.LoadXml(string filename)
{
if (LoadXml.TryGetValue(filename, out var xml))
return xml;
throw new ArgumentException("Missing LoadXml " + filename);
}
public string EnvironmentExpandEnvironmentVariables(string s)
{
foreach (var kvp in GetEnvironmentVariable)
s = s.Replace($"%{kvp.Key}%", kvp.Value);
return s;
}
public void CreateDirectory(string path)
{
if (!CreateDirectories.Contains(path))
throw new ArgumentException($"Missing CreateDirectory, {path}");
}
public void DownloadFile(string address, string fileName)
{
if (!DownloadFiles.Contains((address, fileName)))
throw new ArgumentException($"Missing DownloadFile, {address}, {fileName}");
}
}
/// <summary>
/// A fake solution to build.
/// </summary>
class TestSolution : ISolution
{
public IEnumerable<SolutionConfigurationInSolution> Configurations => throw new NotImplementedException();
public string DefaultConfigurationName => "Release";
public string DefaultPlatformName => "x86";
public string FullPath { get; set; }
public Version ToolsVersion => new Version("14.0");
public IEnumerable<IProjectOrSolution> IncludedProjects => throw new NotImplementedException();
public TestSolution(string path)
{
FullPath = path;
}
}
public class BuildScriptTests
{
TestActions Actions = new TestActions();
// Records the arguments passed to StartCallback.
IList<string> StartCallbackIn = new List<string>();
void StartCallback(string s, bool silent)
{
StartCallbackIn.Add(s);
}
// Records the arguments passed to EndCallback
IList<string> EndCallbackIn = new List<string>();
IList<int> EndCallbackReturn = new List<int>();
void EndCallback(int ret, string s, bool silent)
{
EndCallbackReturn.Add(ret);
EndCallbackIn.Add(s);
}
CppAutobuilder CreateAutoBuilder(bool isWindows,
string? buildless = null, string? solution = null, string? buildCommand = null, string? ignoreErrors = null,
string? msBuildArguments = null, string? msBuildPlatform = null, string? msBuildConfiguration = null, string? msBuildTarget = null,
string? dotnetArguments = null, string? dotnetVersion = null, string? vsToolsVersion = null,
string? nugetRestore = null, string? allSolutions = null,
string cwd = @"C:\Project")
{
string codeqlUpperLanguage = Language.Cpp.UpperCaseName;
Actions.GetEnvironmentVariable[$"CODEQL_AUTOBUILDER_{codeqlUpperLanguage}_NO_INDEXING"] = "false";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_SOURCE_ARCHIVE_DIR"] = "";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_ROOT"] = $@"C:\codeql\{codeqlUpperLanguage.ToLowerInvariant()}";
Actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
Actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = "win64";
Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa";
Actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java";
Actions.GetEnvironmentVariable["SEMMLE_PLATFORM_TOOLS"] = @"C:\odasa\tools";
Actions.GetEnvironmentVariable["LGTM_INDEX_VSTOOLS_VERSION"] = vsToolsVersion;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_ARGUMENTS"] = msBuildArguments;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_PLATFORM"] = msBuildPlatform;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_CONFIGURATION"] = msBuildConfiguration;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_TARGET"] = msBuildTarget;
Actions.GetEnvironmentVariable["LGTM_INDEX_DOTNET_ARGUMENTS"] = dotnetArguments;
Actions.GetEnvironmentVariable["LGTM_INDEX_DOTNET_VERSION"] = dotnetVersion;
Actions.GetEnvironmentVariable["LGTM_INDEX_BUILD_COMMAND"] = buildCommand;
Actions.GetEnvironmentVariable["LGTM_INDEX_SOLUTION"] = solution;
Actions.GetEnvironmentVariable["LGTM_INDEX_IGNORE_ERRORS"] = ignoreErrors;
Actions.GetEnvironmentVariable["LGTM_INDEX_BUILDLESS"] = buildless;
Actions.GetEnvironmentVariable["LGTM_INDEX_ALL_SOLUTIONS"] = allSolutions;
Actions.GetEnvironmentVariable["LGTM_INDEX_NUGET_RESTORE"] = nugetRestore;
Actions.GetEnvironmentVariable["ProgramFiles(x86)"] = isWindows ? @"C:\Program Files (x86)" : null;
Actions.GetCurrentDirectory = cwd;
Actions.IsWindows = isWindows;
var options = new AutobuildOptions(Actions, Language.Cpp);
return new CppAutobuilder(Actions, options);
}
void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun)
{
Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(Actions, StartCallback, EndCallback));
// Check expected commands actually ran
Assert.Equal(commandsRun, StartCallbackIn.Count);
Assert.Equal(commandsRun, EndCallbackIn.Count);
Assert.Equal(commandsRun, EndCallbackReturn.Count);
var action = Actions.RunProcess.GetEnumerator();
for (int cmd = 0; cmd < commandsRun; ++cmd)
{
Assert.True(action.MoveNext());
Assert.Equal(action.Current.Key, StartCallbackIn[cmd]);
Assert.Equal(action.Current.Value, EndCallbackReturn[cmd]);
}
}
[Fact]
public void TestDefaultCppAutobuilder()
{
Actions.EnumerateFiles[@"C:\Project"] = "";
Actions.EnumerateDirectories[@"C:\Project"] = "";
var autobuilder = CreateAutoBuilder(true);
var script = autobuilder.GetBuildScript();
// Fails due to no solutions present.
Assert.NotEqual(0, script.Run(Actions, StartCallback, EndCallback));
}
[Fact]
public void TestCppAutobuilderSuccess()
{
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /p:UseSharedCompilation=false /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = "";
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = true;
Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.slx";
Actions.EnumerateDirectories[@"C:\Project"] = "";
Actions.CreateDirectories.Add(@"C:\Project\.nuget");
Actions.DownloadFiles.Add(("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", @"C:\Project\.nuget\nuget.exe"));
var autobuilder = CreateAutoBuilder(true);
var solution = new TestSolution(@"C:\Project\test.sln");
autobuilder.ProjectsOrSolutionsToBuild.Add(solution);
TestAutobuilderScript(autobuilder, 0, 3);
}
}
}

View File

@@ -1,25 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Autobuild.Cpp\Semmle.Autobuild.Cpp.csproj" />
<ProjectReference Include="..\..\..\csharp\autobuilder\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,23 +0,0 @@
using Semmle.Autobuild.Shared;
namespace Semmle.Autobuild.Cpp
{
public class CppAutobuilder : Autobuilder
{
public CppAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { }
public override BuildScript GetBuildScript()
{
if (Options.BuildCommand != null)
return new BuildCommandRule((_, f) => f(null)).Analyse(this, false);
return
// First try MSBuild
new MsBuildRule().Analyse(this, true) |
// Then look for a script that might be a build script
(() => new BuildCommandAutoRule((_, f) => f(null)).Analyse(this, true)) |
// All attempts failed: print message
AutobuildFailure();
}
}
}

View File

@@ -1,33 +0,0 @@
using System;
using Semmle.Autobuild.Shared;
namespace Semmle.Autobuild.Cpp
{
class Program
{
static int Main()
{
try
{
var actions = SystemBuildActions.Instance;
var options = new AutobuildOptions(actions, Language.Cpp);
try
{
Console.WriteLine("CodeQL C++ autobuilder");
var builder = new CppAutobuilder(actions, options);
return builder.AttemptBuild();
}
catch(InvalidEnvironmentException ex)
{
Console.WriteLine("The environment is invalid: {0}", ex.Message);
}
}
catch (ArgumentOutOfRangeException ex)
{
Console.WriteLine("The value \"{0}\" for parameter \"{1}\" is invalid", ex.ActualValue, ex.ParamName);
}
return 1;
}
}
}

View File

@@ -1,32 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Semmle.Autobuild.Cpp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("GitHub")]
[assembly: AssemblyProduct("CodeQL autobuilder for C++")]
[assembly: AssemblyCopyright("Copyright © GitHub 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,28 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Autobuild.Cpp</AssemblyName>
<RootNamespace>Semmle.Autobuild.Cpp</RootNamespace>
<ApplicationIcon />
<OutputType>Exe</OutputType>
<StartupObject />
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.9.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\csharp\extractor\Semmle.Util\Semmle.Util.csproj" />
<ProjectReference Include="..\..\..\csharp\autobuilder\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj" />
</ItemGroup>
</Project>

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,4 +0,0 @@
lgtm,codescanning
* `FormattingFunction.getOutputParameterIndex` now has a parameter identifying whether the output at that index is a buffer or a stream.
* `FormattingFunction` now has a predicate `isOutputGlobal` indicating when the output is to a global stream.
* The `primitiveVariadicFormatter` and `variadicFormatter` predicates have more parameters exposing information about the function.

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

@@ -1,2 +0,0 @@
lgtm
* A new query (`cpp/unsigned-difference-expression-compared-zero`) is run but not yet displayed on LGTM. The query finds unsigned subtractions used in relational comparisons with the value 0. This query was originally submitted as an experimental query by @ihsinme in https://github.com/github/codeql/pull/4745.

View File

@@ -1,2 +0,0 @@
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

@@ -1,2 +0,0 @@
lgtm,codescanning
* The data-flow library now recognises more side-effects of method chaining (e.g. `someObject.setX(clean).setY(tainted).setZ...` having a side-effect on `someObject`), as well as other related circumstances where a function input is directly passed to its output. All queries that use data-flow analysis, including most security queries, may return more results accordingly.

View File

@@ -1,2 +0,0 @@
codescanning
* Added cpp/diagnostics/failed-extractions. This query gives information about which extractions did not run to completion.

View File

@@ -1,2 +0,0 @@
lgtm,codescanning
* The 'Resource not released in destructor' (cpp/resource-not-released-in-destructor) query has been improved to recognize more releases of resources.

View File

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

View File

@@ -9,8 +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
+ semmlecode-cpp-queries/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.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

@@ -1,3 +0,0 @@
name: codeql-cpp-examples
version: 0.0.0
libraryPathDependencies: codeql-cpp

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

@@ -4,6 +4,9 @@
* @kind graph
* @id cpp/architecture/class-hierarchies
* @graph.layout organic
* @workingset jhotdraw
* @result succeed 48
* @result_ondemand succeed 48
* @tags maintainability
*/

View File

@@ -4,6 +4,9 @@
* @kind chart
* @id cpp/architecture/inheritance-depth-distribution
* @chart.type line
* @workingset jhotdraw
* @result succeed 48
* @result_ondemand succeed 48
* @tags maintainability
*/

View File

@@ -1,8 +1,7 @@
/**
* @name Global namespace classes
* @description Finds classes that belong to no namespace.
* @kind problem
* @problem.severity recommendation
* @kind table
* @id cpp/architecture/global-namespace-classes
* @tags maintainability
* modularity

View File

@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/architecture/classes-with-many-dependencies
* @problem.severity recommendation
* @workingset jhotdraw
* @result succeed 20
* @result_ondemand succeed 20
* @tags maintainability
* statistical
* non-attributable

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

@@ -3,7 +3,6 @@
* @description If an exception is allocated on the heap, then it should be deleted when caught.
* @kind problem
* @problem.severity warning
* @problem.security-severity high
* @precision high
* @id cpp/catch-missing-free
* @tags efficiency

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

@@ -5,7 +5,6 @@
* @kind problem
* @id cpp/offset-use-before-range-check
* @problem.severity warning
* @problem.security-severity high
* @precision medium
* @tags reliability
* security

View File

@@ -8,41 +8,168 @@ import semmle.code.cpp.AutogeneratedFile
predicate trivialPositiveIntValue(string s) {
// Small numbers
s = [0 .. 20].toString() or
s =
[
// Popular powers of two (decimal)
"16", "24", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384", "32768",
"65536", "1048576", "2147483648", "4294967296",
// Popular powers of two, minus one (decimal)
"15", "31", "63", "127", "255", "511", "1023", "2047", "4095", "16383", "32767", "65535",
"1048577", "2147483647", "4294967295",
// Popular powers of two (32-bit hex)
"0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020",
"0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800",
"0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000",
"0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000",
"0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000",
"0x40000000", "0x80000000",
// Popular powers of two, minus one (32-bit hex)
"0x00000001", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f", "0x0000003f",
"0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff", "0x00000fff",
"0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff", "0x0003ffff",
"0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff", "0x00ffffff",
"0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff", "0x3fffffff",
"0x7fffffff", "0xffffffff",
// Popular powers of two (16-bit hex)
"0x0001", "0x0002", "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100",
"0x0200", "0x0400", "0x0800", "0x1000", "0x2000", "0x4000", "0x8000",
// Popular powers of two, minus one (16-bit hex)
"0x0001", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff",
"0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff",
// Popular powers of two (8-bit hex)
"0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80",
// Popular powers of two, minus one (8-bit hex)
"0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00",
// Powers of ten
"10", "100", "1000", "10000", "100000", "1000000", "10000000", "100000000", "1000000000"
]
// Popular powers of two (decimal)
s = "16" or
s = "24" or
s = "32" or
s = "64" or
s = "128" or
s = "256" or
s = "512" or
s = "1024" or
s = "2048" or
s = "4096" or
s = "16384" or
s = "32768" or
s = "65536" or
s = "1048576" or
s = "2147483648" or
s = "4294967296" or
// Popular powers of two, minus one (decimal)
s = "15" or
s = "31" or
s = "63" or
s = "127" or
s = "255" or
s = "511" or
s = "1023" or
s = "2047" or
s = "4095" or
s = "16383" or
s = "32767" or
s = "65535" or
s = "1048577" or
s = "2147483647" or
s = "4294967295" or
// Popular powers of two (32-bit hex)
s = "0x00000001" or
s = "0x00000002" or
s = "0x00000004" or
s = "0x00000008" or
s = "0x00000010" or
s = "0x00000020" or
s = "0x00000040" or
s = "0x00000080" or
s = "0x00000100" or
s = "0x00000200" or
s = "0x00000400" or
s = "0x00000800" or
s = "0x00001000" or
s = "0x00002000" or
s = "0x00004000" or
s = "0x00008000" or
s = "0x00010000" or
s = "0x00020000" or
s = "0x00040000" or
s = "0x00080000" or
s = "0x00100000" or
s = "0x00200000" or
s = "0x00400000" or
s = "0x00800000" or
s = "0x01000000" or
s = "0x02000000" or
s = "0x04000000" or
s = "0x08000000" or
s = "0x10000000" or
s = "0x20000000" or
s = "0x40000000" or
s = "0x80000000" or
// Popular powers of two, minus one (32-bit hex)
s = "0x00000001" or
s = "0x00000003" or
s = "0x00000007" or
s = "0x0000000f" or
s = "0x0000001f" or
s = "0x0000003f" or
s = "0x0000007f" or
s = "0x000000ff" or
s = "0x000001ff" or
s = "0x000003ff" or
s = "0x000007ff" or
s = "0x00000fff" or
s = "0x00001fff" or
s = "0x00003fff" or
s = "0x00007fff" or
s = "0x0000ffff" or
s = "0x0001ffff" or
s = "0x0003ffff" or
s = "0x0007ffff" or
s = "0x000fffff" or
s = "0x001fffff" or
s = "0x003fffff" or
s = "0x007fffff" or
s = "0x00ffffff" or
s = "0x01ffffff" or
s = "0x03ffffff" or
s = "0x07ffffff" or
s = "0x0fffffff" or
s = "0x1fffffff" or
s = "0x3fffffff" or
s = "0x7fffffff" or
s = "0xffffffff" or
// Popular powers of two (16-bit hex)
s = "0x0001" or
s = "0x0002" or
s = "0x0004" or
s = "0x0008" or
s = "0x0010" or
s = "0x0020" or
s = "0x0040" or
s = "0x0080" or
s = "0x0100" or
s = "0x0200" or
s = "0x0400" or
s = "0x0800" or
s = "0x1000" or
s = "0x2000" or
s = "0x4000" or
s = "0x8000" or
// Popular powers of two, minus one (16-bit hex)
s = "0x0001" or
s = "0x0003" or
s = "0x0007" or
s = "0x000f" or
s = "0x001f" or
s = "0x003f" or
s = "0x007f" or
s = "0x00ff" or
s = "0x01ff" or
s = "0x03ff" or
s = "0x07ff" or
s = "0x0fff" or
s = "0x1fff" or
s = "0x3fff" or
s = "0x7fff" or
s = "0xffff" or
// Popular powers of two (8-bit hex)
s = "0x01" or
s = "0x02" or
s = "0x04" or
s = "0x08" or
s = "0x10" or
s = "0x20" or
s = "0x40" or
s = "0x80" or
// Popular powers of two, minus one (8-bit hex)
s = "0x01" or
s = "0x03" or
s = "0x07" or
s = "0x0f" or
s = "0x1f" or
s = "0x3f" or
s = "0x7f" or
s = "0xff" or
s = "0x00" or
// Powers of ten
s = "10" or
s = "100" or
s = "1000" or
s = "10000" or
s = "100000" or
s = "1000000" or
s = "10000000" or
s = "100000000" or
s = "1000000000"
}
predicate trivialIntValue(string s) {
@@ -108,7 +235,10 @@ predicate joiningStringTrivial(Literal lit) {
// understand (which is against the spirit of these queries).
stringLiteral(lit) and
exists(FunctionCall fc |
fc.getTarget().getName() = ["operator+", "operator<<"] and
(
fc.getTarget().getName() = "operator+" or
fc.getTarget().getName() = "operator<<"
) and
fc.getAnArgument().getAChild*() = lit
) and
lit.getValue().length() < 16
@@ -161,7 +291,8 @@ predicate arrayInitializerChild(AggregateLiteral parent, Expr e) {
// i.e. not a constant folded expression
predicate literallyLiteral(Literal lit) {
lit.getValueText()
lit
.getValueText()
.regexpMatch(".*\".*|\\s*+[-+]?+\\s*+(0[xob][0-9a-fA-F]|[0-9])[0-9a-fA-F,._]*+([eE][-+]?+[0-9,._]*+)?+\\s*+[a-zA-Z]*+\\s*+")
}

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

@@ -9,7 +9,7 @@
It is likely that these conditions indicate an error in the branching condition.
Alternatively, the conditions may have been left behind after debugging.</p>
<include src="aliasAnalysisWarning.inc.qhelp" />
<include src="aliasAnalysisWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -13,7 +13,7 @@ If left in the code base they increase object code size, decrease code comprehen
This type of function may be part of the program's API and could be used by external programs.
</p>
<include src="callGraphWarning.inc.qhelp" />
<include src="callGraphWarning.qhelp" />
</overview>
<recommendation>

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

@@ -10,7 +10,7 @@ This query looks at functions that return file or socket descriptors, but may re
This can occur when an operation performed on the open descriptor fails, and the function returns with an error before it closes the open resource. An improperly handled error could cause the function to leak resource descriptors. Failing to close resources in the function that opened them also makes it more difficult to detect leaks.
</p>
<include src="dataFlowWarning.inc.qhelp" />
<include src="dataFlowWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -10,7 +10,7 @@ This rule finds calls to <code>socket</code> where there is no corresponding <co
Leaving descriptors open will cause a resource leak that will persist even after the program terminates.
</p>
<include src="aliasAnalysisWarning.inc.qhelp" />
<include src="aliasAnalysisWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -10,7 +10,7 @@ This rule looks at functions that return a <code>FILE*</code>, but may return an
This can occur when an operation performed on the open descriptor fails, and the function returns with an error before closing the open resource. An improperly handled error may cause the function to leak file descriptors.
</p>
<include src="dataFlowWarning.inc.qhelp" />
<include src="dataFlowWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -10,7 +10,7 @@ This rule finds calls to <code>fopen</code> with no corresponding <code>fclose</
Leaving files open will cause a resource leak that will persist even after the program terminates.
</p>
<include src="aliasAnalysisWarning.inc.qhelp" />
<include src="aliasAnalysisWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -10,7 +10,7 @@ Not all compilers generate code that zero-out memory, especially when optimizati
is not compliant with the latest language standards. Accessing uninitialized memory will lead to undefined results.
</p>
<include src="dataFlowWarning.inc.qhelp" />
<include src="dataFlowWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -12,7 +12,7 @@ Dereferencing a null pointer and attempting to modify its contents can lead to a
important system data (including the interrupt table in some architectures).
</p>
<include src="pointsToWarning.inc.qhelp" />
<include src="pointsToWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -4,7 +4,6 @@
* @kind problem
* @id cpp/inconsistent-nullness-testing
* @problem.severity warning
* @problem.security-severity high
* @tags reliability
* security
* external/cwe/cwe-476

View File

@@ -11,7 +11,7 @@ Uninitialized variables may contain any value, as not all compilers generate cod
optimizations are enabled or the compiler is not compliant with the latest language standards.
</p>
<include src="callGraphWarning.inc.qhelp" />
<include src="callGraphWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -13,7 +13,7 @@ after. Otherwise, if the value is negative then the program will have failed
before performing the test.
</p>
<include src="dataFlowWarning.inc.qhelp" />
<include src="dataFlowWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -9,7 +9,7 @@
This rule looks for functions that allocate memory, but may return without freeing it. This can occur when an operation performed on the memory block fails, and the function returns with an error before freeing the allocated block. This causes the function to leak memory and may eventually lead to software failure.
</p>
<include src="dataFlowWarning.inc.qhelp" />
<include src="dataFlowWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -4,7 +4,6 @@
* @kind problem
* @id cpp/memory-may-not-be-freed
* @problem.severity warning
* @problem.security-severity high
* @tags efficiency
* security
* external/cwe/cwe-401

View File

@@ -10,7 +10,7 @@ This rule finds calls to the <code>alloc</code> family of functions without a co
This leads to memory leaks.
</p>
<include src="aliasAnalysisWarning.inc.qhelp" />
<include src="aliasAnalysisWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -4,7 +4,6 @@
* @kind problem
* @id cpp/memory-never-freed
* @problem.severity warning
* @problem.security-severity high
* @tags efficiency
* security
* external/cwe/cwe-401

View File

@@ -16,7 +16,7 @@ buffer overruns.
The query looks only at the return values of functions that may return a negative value (not all functions).
</p>
<include src="dataFlowWarning.inc.qhelp" />
<include src="dataFlowWarning.qhelp" />
</overview>
<recommendation>

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

@@ -4,7 +4,6 @@
* @kind problem
* @id cpp/missing-null-test
* @problem.severity recommendation
* @problem.security-severity high
* @tags reliability
* security
* external/cwe/cwe-476

View File

@@ -63,7 +63,7 @@ destructors likely not be called (as previously noted), but the pointer will als
potentially less of a serious issue than that posed by the first approach, but it should still be avoided.</li>
</ul>
<include src="pointsToWarning.inc.qhelp" />
<include src="pointsToWarning.qhelp" />
</overview>
<recommendation>

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

@@ -18,7 +18,7 @@ an array (which could have header data specifying the length of the array) and w
element of the 'array', which would likely lead to a segfault due to the invalid header data.
</p>
<include src="pointsToWarning.inc.qhelp" />
<include src="pointsToWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -3,7 +3,6 @@
* @description An object that was allocated with 'malloc' or 'new' is being freed using a mismatching 'free' or 'delete'.
* @kind problem
* @problem.severity warning
* @problem.security-severity high
* @precision high
* @id cpp/new-free-mismatch
* @tags reliability

View File

@@ -19,7 +19,7 @@ the data being copied. Buffer overflows can result to anything from a segmentati
if the array is on stack-allocated memory).
</p>
<include src="aliasAnalysisWarning.inc.qhelp" />
<include src="aliasAnalysisWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -4,7 +4,6 @@
* @kind problem
* @id cpp/overflow-calculated
* @problem.severity warning
* @problem.security-severity critical
* @tags reliability
* security
* external/cwe/cwe-131

View File

@@ -14,7 +14,7 @@ Buffer overflows can lead to anything from a segmentation fault to a security vu
Ensure that the size parameter is derived from the size of the destination buffer, and
not the source buffer.</p>
<include src="aliasAnalysisWarning.inc.qhelp" />
<include src="aliasAnalysisWarning.qhelp" />
</recommendation>

View File

@@ -5,7 +5,6 @@
* @kind problem
* @id cpp/overflow-destination
* @problem.severity warning
* @problem.security-severity high
* @precision low
* @tags reliability
* security
@@ -24,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

@@ -4,7 +4,6 @@
* may result in a buffer overflow.
* @kind problem
* @problem.severity warning
* @problem.security-severity high
* @precision medium
* @id cpp/static-buffer-overflow
* @tags reliability

View File

@@ -12,7 +12,7 @@ the contents of that memory become undefined after that. Clearly, using a pointe
memory after the function has already returned will have undefined results.
</p>
<include src="pointsToWarning.inc.qhelp" />
<include src="pointsToWarning.qhelp" />
</overview>
<recommendation>

View File

@@ -4,7 +4,6 @@
* @kind problem
* @id cpp/return-value-ignored
* @problem.severity recommendation
* @problem.security-severity critical
* @precision medium
* @tags reliability
* correctness

View File

@@ -4,7 +4,6 @@
* an instance of the type of the pointer may result in a buffer overflow
* @kind problem
* @problem.severity warning
* @problem.security-severity high
* @precision medium
* @id cpp/allocation-too-small
* @tags reliability
@@ -14,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
(
@@ -34,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

@@ -4,7 +4,6 @@
* multiple instances of the type of the pointer may result in a buffer overflow
* @kind problem
* @problem.severity warning
* @problem.security-severity high
* @precision medium
* @id cpp/suspicious-allocation-size
* @tags reliability
@@ -14,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
(
@@ -29,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

@@ -12,7 +12,7 @@ from a segfault to memory corruption that would cause subsequent calls to the dy
erratically, to a possible security vulnerability.
</p>
<include src="pointsToWarning.inc.qhelp" />
<include src="pointsToWarning.qhelp" />
</overview>
<recommendation>

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