mirror of
https://github.com/github/codeql.git
synced 2026-05-27 09:31:30 +02:00
Compare commits
9 Commits
rc/3.7
...
erik-krogh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26f81f1c37 | ||
|
|
942392a9a1 | ||
|
|
39820ee561 | ||
|
|
fd581f74aa | ||
|
|
21bec8a3d3 | ||
|
|
108a0bbd29 | ||
|
|
f735821630 | ||
|
|
98acb1db01 | ||
|
|
ade7130935 |
1
.github/labeler.yml
vendored
1
.github/labeler.yml
vendored
@@ -42,4 +42,3 @@ documentation:
|
||||
|
||||
"QL-for-QL":
|
||||
- ql/**/*
|
||||
- .github/workflows/ql-for-ql*
|
||||
|
||||
12
.github/workflows/go-tests.yml
vendored
12
.github/workflows/go-tests.yml
vendored
@@ -11,10 +11,10 @@ jobs:
|
||||
name: Test Linux (Ubuntu)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.19
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
@@ -57,10 +57,10 @@ jobs:
|
||||
name: Test MacOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Set up Go 1.19
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
@@ -87,10 +87,10 @@ jobs:
|
||||
name: Test Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- name: Set up Go 1.19
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
|
||||
121
.github/workflows/ql-for-ql-build.yml
vendored
121
.github/workflows/ql-for-ql-build.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Find codeql
|
||||
id: find-codeql
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
- name: Get CodeQL version
|
||||
@@ -27,37 +27,31 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Cache entire pack
|
||||
id: cache-pack
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ runner.temp }}/pack
|
||||
key: ${{ runner.os }}-pack-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }}-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}--${{ hashFiles('.github/workflows/ql-for-ql-build.yml') }}
|
||||
- name: Cache queries
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
id: cache-queries
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ runner.temp }}/queries
|
||||
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}--${{ hashFiles('.github/workflows/ql-for-ql-build.yml') }}
|
||||
path: ${{ runner.temp }}/query-pack.zip
|
||||
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}
|
||||
- name: Build query pack
|
||||
if: steps.cache-queries.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-queries.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd ql/ql/src
|
||||
"${CODEQL}" pack create -j 16
|
||||
mv .codeql/pack/codeql/ql/0.0.0 ${{ runner.temp }}/queries
|
||||
"${CODEQL}" pack create
|
||||
cd .codeql/pack/codeql/ql/0.0.0
|
||||
zip "${PACKZIP}" -r .
|
||||
rm -rf *
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Move cache queries to pack
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cp -r ${{ runner.temp }}/queries ${{ runner.temp }}/pack
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
|
||||
PACKZIP: ${{ runner.temp }}/query-pack.zip
|
||||
- name: Upload query pack
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: query-pack-zip
|
||||
path: ${{ runner.temp }}/query-pack.zip
|
||||
|
||||
### Build the extractor ###
|
||||
- name: Cache entire extractor
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
id: cache-extractor
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
@@ -68,7 +62,7 @@ jobs:
|
||||
ql/target/release/ql-extractor.exe
|
||||
key: ${{ runner.os }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }}
|
||||
- name: Cache cargo
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
@@ -77,35 +71,73 @@ jobs:
|
||||
ql/target
|
||||
key: ${{ runner.os }}-rust-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
|
||||
- name: Check formatting
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo fmt --all -- --check
|
||||
- name: Build
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo build --verbose
|
||||
- name: Run tests
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo test --verbose
|
||||
- name: Release build
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo build --release
|
||||
- name: Generate dbscheme
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: ql/target/release/ql-generator --dbscheme ql/ql/src/ql.dbscheme --library ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: extractor-ubuntu-latest
|
||||
path: |
|
||||
ql/target/release/ql-autobuilder
|
||||
ql/target/release/ql-autobuilder.exe
|
||||
ql/target/release/ql-extractor
|
||||
ql/target/release/ql-extractor.exe
|
||||
retention-days: 1
|
||||
|
||||
### Package the queries and extractor ###
|
||||
- name: Package pack
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cp -r ql/codeql-extractor.yml ql/tools ql/ql/src/ql.dbscheme.stats ${PACK}/
|
||||
mkdir -p ${PACK}/tools/linux64
|
||||
cp ql/target/release/ql-autobuilder ${PACK}/tools/linux64/autobuilder
|
||||
cp ql/target/release/ql-extractor ${PACK}/tools/linux64/extractor
|
||||
chmod +x ${PACK}/tools/linux64/autobuilder
|
||||
chmod +x ${PACK}/tools/linux64/extractor
|
||||
env:
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: query-pack-zip
|
||||
path: query-pack-zip
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: extractor-ubuntu-latest
|
||||
path: linux64
|
||||
- run: |
|
||||
unzip query-pack-zip/*.zip -d pack
|
||||
cp -r ql/codeql-extractor.yml ql/tools ql/ql/src/ql.dbscheme.stats pack/
|
||||
mkdir -p pack/tools/linux64
|
||||
if [[ -f linux64/ql-autobuilder ]]; then
|
||||
cp linux64/ql-autobuilder pack/tools/linux64/autobuilder
|
||||
chmod +x pack/tools/linux64/autobuilder
|
||||
fi
|
||||
if [[ -f linux64/ql-extractor ]]; then
|
||||
cp linux64/ql-extractor pack/tools/linux64/extractor
|
||||
chmod +x pack/tools/linux64/extractor
|
||||
fi
|
||||
cd pack
|
||||
zip -rq ../codeql-ql.zip .
|
||||
rm -rf *
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: codeql-ql-pack
|
||||
path: codeql-ql.zip
|
||||
retention-days: 1
|
||||
|
||||
### Run the analysis ###
|
||||
- name: Download pack
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: codeql-ql-pack
|
||||
path: ${{ runner.temp }}/codeql-ql-pack-artifact
|
||||
|
||||
- name: Prepare pack
|
||||
run: |
|
||||
unzip "${PACK_ARTIFACT}/*.zip" -d "${PACK}"
|
||||
env:
|
||||
PACK_ARTIFACT: ${{ runner.temp }}/codeql-ql-pack-artifact
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
- name: Hack codeql-action options
|
||||
run: |
|
||||
JSON=$(jq -nc --arg pack "${PACK}" '.database."run-queries"=["--search-path", $pack] | .resolve.queries=["--search-path", $pack] | .resolve.extractor=["--search-path", $pack] | .database.init=["--search-path", $pack]')
|
||||
@@ -119,26 +151,21 @@ jobs:
|
||||
echo " - ql/ql/test" >> ${CONF}
|
||||
echo " - \"*/ql/lib/upgrades/\"" >> ${CONF}
|
||||
echo "disable-default-queries: true" >> ${CONF}
|
||||
echo "queries:" >> ${CONF}
|
||||
echo " - uses: ./ql/ql/src/codeql-suites/ql-code-scanning.qls" >> ${CONF}
|
||||
echo "packs:" >> ${CONF}
|
||||
echo " - codeql/ql" >> ${CONF}
|
||||
echo "Config file: "
|
||||
cat ${CONF}
|
||||
env:
|
||||
CONF: ./ql-for-ql-config.yml
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: ql
|
||||
db-location: ${{ runner.temp }}/db
|
||||
config-file: ./ql-for-ql-config.yml
|
||||
- name: Move pack cache
|
||||
run: |
|
||||
cp -r ${PACK}/.cache ql/ql/src/.cache
|
||||
env:
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
category: "ql-for-ql"
|
||||
- name: Copy sarif file to CWD
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
- name: Find codeql
|
||||
id: find-codeql
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
- uses: actions/cache@v3
|
||||
|
||||
2
.github/workflows/ql-for-ql-tests.yml
vendored
2
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Find codeql
|
||||
id: find-codeql
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
- uses: actions/cache@v3
|
||||
|
||||
@@ -1,21 +1,3 @@
|
||||
## 0.3.5
|
||||
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been
|
||||
deleted.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
5
cpp/ql/lib/change-notes/2022-08-22-xml-rename.md
Normal file
5
cpp/ql/lib/change-notes/2022-08-22-xml-rename.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* Classes/predicates that had upper-case acronym XML in their name have been renamed to Xml to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
@@ -1,15 +0,0 @@
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
@@ -1 +0,0 @@
|
||||
## 0.3.5
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.5
|
||||
lastReleaseVersion: 0.3.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.3.6-dev
|
||||
version: 0.3.4-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
20
cpp/ql/lib/semmle/code/cpp/XML.qll
Normal file → Executable file
20
cpp/ql/lib/semmle/code/cpp/XML.qll
Normal file → Executable file
@@ -132,10 +132,7 @@ class XmlFile extends XmlParent, File {
|
||||
XmlElement getARootElement() { result = this.getAChild() }
|
||||
|
||||
/** Gets a DTD associated with this XML file. */
|
||||
XmlDtd getADtd() { xmlDTDs(result, _, _, _, this) }
|
||||
|
||||
/** DEPRECATED: Alias for getADtd */
|
||||
deprecated XmlDtd getADTD() { result = this.getADtd() }
|
||||
XmlDTD getADTD() { xmlDTDs(result, _, _, _, this) }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlFile */
|
||||
@@ -152,7 +149,7 @@ deprecated class XMLFile = XmlFile;
|
||||
* <!ELEMENT lastName (#PCDATA)>
|
||||
* ```
|
||||
*/
|
||||
class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
class XmlDTD extends XmlLocatable, @xmldtd {
|
||||
/** Gets the name of the root element of this DTD. */
|
||||
string getRoot() { xmlDTDs(this, result, _, _, _) }
|
||||
|
||||
@@ -177,8 +174,8 @@ class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlDtd */
|
||||
deprecated class XMLDTD = XmlDtd;
|
||||
/** DEPRECATED: Alias for XmlDTD */
|
||||
deprecated class XMLDTD = XmlDTD;
|
||||
|
||||
/**
|
||||
* An XML element in an XML file.
|
||||
@@ -285,18 +282,15 @@ class XmlNamespace extends XmlLocatable, @xmlnamespace {
|
||||
string getPrefix() { xmlNs(this, result, _, _) }
|
||||
|
||||
/** Gets the URI of this namespace. */
|
||||
string getUri() { xmlNs(this, _, result, _) }
|
||||
|
||||
/** DEPRECATED: Alias for getUri */
|
||||
deprecated string getURI() { result = this.getUri() }
|
||||
string getURI() { xmlNs(this, _, result, _) }
|
||||
|
||||
/** Holds if this namespace has no prefix. */
|
||||
predicate isDefault() { this.getPrefix() = "" }
|
||||
|
||||
override string toString() {
|
||||
this.isDefault() and result = this.getUri()
|
||||
this.isDefault() and result = this.getURI()
|
||||
or
|
||||
not this.isDefault() and result = this.getPrefix() + ":" + this.getUri()
|
||||
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import semmle.code.cpp.ir.internal.Overlap
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
private import semmle.code.cpp.Print
|
||||
private import semmle.code.cpp.ir.implementation.unaliased_ssa.IR
|
||||
private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as OldSsa
|
||||
private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as OldSSA
|
||||
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
|
||||
private import semmle.code.cpp.ir.internal.IntegerInterval as Interval
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
@@ -572,7 +572,7 @@ private Overlap getVariableMemoryLocationOverlap(
|
||||
* Holds if the def/use information for the result of `instr` can be reused from the previous
|
||||
* iteration of the IR.
|
||||
*/
|
||||
predicate canReuseSsaForOldResult(Instruction instr) { OldSsa::canReuseSsaForMemoryResult(instr) }
|
||||
predicate canReuseSsaForOldResult(Instruction instr) { OldSSA::canReuseSsaForMemoryResult(instr) }
|
||||
|
||||
/** DEPRECATED: Alias for canReuseSsaForOldResult */
|
||||
deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1;
|
||||
|
||||
@@ -5,8 +5,8 @@ private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
private import Imports::TInstruction
|
||||
private import Imports::RawIR as RawIR
|
||||
private import SsaInstructions
|
||||
private import SsaOperands
|
||||
private import SSAInstructions
|
||||
private import SSAOperands
|
||||
private import NewIR
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
@@ -2,14 +2,7 @@ import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as OldIR
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.ReachableBlock as Reachability
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.Dominance as Dominance
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR as NewIR
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::AliasedSsaInstructions as SsaInstructions
|
||||
|
||||
/** DEPRECATED: Alias for SsaInstructions */
|
||||
deprecated module SSAInstructions = SsaInstructions;
|
||||
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::AliasedSsaInstructions as SSAInstructions
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import AliasedSSA as Alias
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands as SsaOperands
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands as SSAOperands
|
||||
|
||||
@@ -29,15 +29,15 @@ newtype TInstruction =
|
||||
UnaliasedSsa::SSA::hasUnreachedInstruction(irFunc)
|
||||
} or
|
||||
TAliasedSsaPhiInstruction(
|
||||
TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation
|
||||
TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation
|
||||
) {
|
||||
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||
AliasedSSA::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||
} or
|
||||
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
||||
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
||||
AliasedSSA::SSA::hasChiInstruction(primaryInstruction)
|
||||
} or
|
||||
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||
AliasedSsa::SSA::hasUnreachedInstruction(irFunc)
|
||||
AliasedSSA::SSA::hasUnreachedInstruction(irFunc)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ module AliasedSsaInstructions {
|
||||
class TPhiInstruction = TAliasedSsaPhiInstruction or TUnaliasedSsaPhiInstruction;
|
||||
|
||||
TPhiInstruction phiInstruction(
|
||||
TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation
|
||||
TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation
|
||||
) {
|
||||
result = TAliasedSsaPhiInstruction(blockStartInstr, memoryLocation)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as IRConstruction
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSsa
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as AliasedSsa
|
||||
|
||||
/** DEPRECATED: Alias for AliasedSsa */
|
||||
deprecated module AliasedSSA = AliasedSsa;
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as AliasedSSA
|
||||
|
||||
@@ -5,8 +5,8 @@ private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
private import Imports::TInstruction
|
||||
private import Imports::RawIR as RawIR
|
||||
private import SsaInstructions
|
||||
private import SsaOperands
|
||||
private import SSAInstructions
|
||||
private import SSAOperands
|
||||
private import NewIR
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
@@ -3,14 +3,7 @@ import semmle.code.cpp.ir.implementation.raw.internal.reachability.ReachableBloc
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.reachability.Dominance as Dominance
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as NewIR
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as RawStage
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::UnaliasedSsaInstructions as SsaInstructions
|
||||
|
||||
/** DEPRECATED: Alias for SsaInstructions */
|
||||
deprecated module SSAInstructions = SsaInstructions;
|
||||
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::UnaliasedSsaInstructions as SSAInstructions
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import SimpleSSA as Alias
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands as SsaOperands
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands as SSAOperands
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
## 0.3.4
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Cleartext storage of sensitive information in buffer" (`cpp/cleartext-storage-buffer`) query has been improved to produce fewer false positives.
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -163,46 +163,19 @@ TGlobalAddress globalAddress(Instruction instr) {
|
||||
result = globalAddress(instr.(PointerOffsetInstruction).getLeft())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a first `StoreInstruction` that writes to address `globalAddress` reachable
|
||||
* from `block`.
|
||||
*/
|
||||
StoreInstruction getFirstStore(IRBlock block, TGlobalAddress globalAddress) {
|
||||
1 = getStoreRank(result, block, globalAddress)
|
||||
or
|
||||
not exists(getStoreRank(_, block, globalAddress)) and
|
||||
result = getFirstStore(block.getASuccessor(), globalAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rank of `store` in block `block` (i.e., a rank of `1` means that it is the
|
||||
* first `store` to write to `globalAddress`, a rank of `2` means it's the second, etc.)
|
||||
*/
|
||||
int getStoreRank(StoreInstruction store, IRBlock block, TGlobalAddress globalAddress) {
|
||||
blockStoresToAddress(block, _, store, globalAddress) and
|
||||
store =
|
||||
rank[result](StoreInstruction anotherStore, int i |
|
||||
blockStoresToAddress(_, i, anotherStore, globalAddress)
|
||||
|
|
||||
anotherStore order by i
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a next subsequent `StoreInstruction` to write to `globalAddress`
|
||||
* after `store` has done so.
|
||||
*/
|
||||
StoreInstruction getANextStoreTo(StoreInstruction store, TGlobalAddress globalAddress) {
|
||||
exists(IRBlock block, int rnk |
|
||||
rnk = getStoreRank(store, block, globalAddress) and
|
||||
rnk + 1 = getStoreRank(result, block, globalAddress)
|
||||
/** Gets a `StoreInstruction` that may be executed after executing `store`. */
|
||||
pragma[inline]
|
||||
StoreInstruction getAStoreStrictlyAfter(StoreInstruction store) {
|
||||
exists(IRBlock block, int index1, int index2 |
|
||||
block.getInstruction(index1) = store and
|
||||
block.getInstruction(index2) = result and
|
||||
index2 > index1
|
||||
)
|
||||
or
|
||||
exists(IRBlock block, int rnk, IRBlock succ |
|
||||
rnk = getStoreRank(store, block, globalAddress) and
|
||||
not rnk + 1 = getStoreRank(_, block, globalAddress) and
|
||||
succ = block.getASuccessor() and
|
||||
result = getFirstStore(succ, globalAddress)
|
||||
exists(IRBlock block1, IRBlock block2 |
|
||||
store.getBlock() = block1 and
|
||||
result.getBlock() = block2 and
|
||||
block1.getASuccessor+() = block2
|
||||
)
|
||||
}
|
||||
|
||||
@@ -219,7 +192,7 @@ predicate stackAddressEscapes(
|
||||
stackPointerFlowsToUse(store.getSourceValue(), vai)
|
||||
) and
|
||||
// Ensure there's no subsequent store that overrides the global address.
|
||||
not exists(getANextStoreTo(store, globalAddress))
|
||||
not globalAddress = globalAddress(getAStoreStrictlyAfter(store).getDestinationAddress())
|
||||
}
|
||||
|
||||
predicate blockStoresToAddress(
|
||||
|
||||
@@ -21,9 +21,7 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode {
|
||||
/** DEPRECATED: Alias for UntrustedExternalApiDataNode */
|
||||
deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode;
|
||||
|
||||
/** An external API which is used with untrusted data. */
|
||||
private newtype TExternalApi =
|
||||
/** An untrusted API method `m` where untrusted data is passed at `index`. */
|
||||
TExternalApiParameter(Function f, int index) {
|
||||
exists(UntrustedExternalApiDataNode n |
|
||||
f = n.getExternalFunction() and
|
||||
|
||||
@@ -21,9 +21,7 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode {
|
||||
/** DEPRECATED: Alias for UntrustedExternalApiDataNode */
|
||||
deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode;
|
||||
|
||||
/** An external API which is used with untrusted data. */
|
||||
private newtype TExternalApi =
|
||||
/** An untrusted API method `m` where untrusted data is passed at `index`. */
|
||||
TExternalApiParameter(Function f, int index) {
|
||||
exists(UntrustedExternalApiDataNode n |
|
||||
f = n.getExternalFunction() and
|
||||
|
||||
@@ -17,8 +17,8 @@ import semmle.code.cpp.dataflow.DataFlow
|
||||
/**
|
||||
* A call to `SSL_get_verify_result`.
|
||||
*/
|
||||
class SslGetVerifyResultCall extends FunctionCall {
|
||||
SslGetVerifyResultCall() { getTarget().getName() = "SSL_get_verify_result" }
|
||||
class SSLGetVerifyResultCall extends FunctionCall {
|
||||
SSLGetVerifyResultCall() { getTarget().getName() = "SSL_get_verify_result" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@ class VerifyResultConfig extends DataFlow::Configuration {
|
||||
VerifyResultConfig() { this = "VerifyResultConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() instanceof SslGetVerifyResultCall
|
||||
source.asExpr() instanceof SSLGetVerifyResultCall
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
|
||||
@@ -17,33 +17,33 @@ import semmle.code.cpp.controlflow.IRGuards
|
||||
/**
|
||||
* A call to `SSL_get_peer_certificate`.
|
||||
*/
|
||||
class SslGetPeerCertificateCall extends FunctionCall {
|
||||
SslGetPeerCertificateCall() {
|
||||
class SSLGetPeerCertificateCall extends FunctionCall {
|
||||
SSLGetPeerCertificateCall() {
|
||||
getTarget().getName() = "SSL_get_peer_certificate" // SSL_get_peer_certificate(ssl)
|
||||
}
|
||||
|
||||
Expr getSslArgument() { result = getArgument(0) }
|
||||
Expr getSSLArgument() { result = getArgument(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `SSL_get_verify_result`.
|
||||
*/
|
||||
class SslGetVerifyResultCall extends FunctionCall {
|
||||
SslGetVerifyResultCall() {
|
||||
class SSLGetVerifyResultCall extends FunctionCall {
|
||||
SSLGetVerifyResultCall() {
|
||||
getTarget().getName() = "SSL_get_verify_result" // SSL_get_peer_certificate(ssl)
|
||||
}
|
||||
|
||||
Expr getSslArgument() { result = getArgument(0) }
|
||||
Expr getSSLArgument() { result = getArgument(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the SSL object passed into `SSL_get_peer_certificate` is checked with
|
||||
* `SSL_get_verify_result` entering `node`.
|
||||
*/
|
||||
predicate resultIsChecked(SslGetPeerCertificateCall getCertCall, ControlFlowNode node) {
|
||||
exists(Expr ssl, SslGetVerifyResultCall check |
|
||||
ssl = globalValueNumber(getCertCall.getSslArgument()).getAnExpr() and
|
||||
ssl = check.getSslArgument() and
|
||||
predicate resultIsChecked(SSLGetPeerCertificateCall getCertCall, ControlFlowNode node) {
|
||||
exists(Expr ssl, SSLGetVerifyResultCall check |
|
||||
ssl = globalValueNumber(getCertCall.getSSLArgument()).getAnExpr() and
|
||||
ssl = check.getSSLArgument() and
|
||||
node = check
|
||||
)
|
||||
}
|
||||
@@ -53,7 +53,7 @@ predicate resultIsChecked(SslGetPeerCertificateCall getCertCall, ControlFlowNode
|
||||
* `0` on the edge `node1` to `node2`.
|
||||
*/
|
||||
predicate certIsZero(
|
||||
SslGetPeerCertificateCall getCertCall, ControlFlowNode node1, ControlFlowNode node2
|
||||
SSLGetPeerCertificateCall getCertCall, ControlFlowNode node1, ControlFlowNode node2
|
||||
) {
|
||||
exists(Expr cert | cert = globalValueNumber(getCertCall).getAnExpr() |
|
||||
exists(GuardCondition guard, Expr zero |
|
||||
@@ -87,7 +87,7 @@ predicate certIsZero(
|
||||
* `SSL_get_verify_result` at `node`. Note that this is only computed at the call to
|
||||
* `SSL_get_peer_certificate` and at the start and end of `BasicBlock`s.
|
||||
*/
|
||||
predicate certNotChecked(SslGetPeerCertificateCall getCertCall, ControlFlowNode node) {
|
||||
predicate certNotChecked(SSLGetPeerCertificateCall getCertCall, ControlFlowNode node) {
|
||||
// cert is not checked at the call to `SSL_get_peer_certificate`
|
||||
node = getCertCall
|
||||
or
|
||||
@@ -112,7 +112,7 @@ predicate certNotChecked(SslGetPeerCertificateCall getCertCall, ControlFlowNode
|
||||
)
|
||||
}
|
||||
|
||||
from SslGetPeerCertificateCall getCertCall, ControlFlowNode node
|
||||
from SSLGetPeerCertificateCall getCertCall, ControlFlowNode node
|
||||
where
|
||||
certNotChecked(getCertCall, node) and
|
||||
node instanceof Function // (function exit)
|
||||
|
||||
@@ -26,10 +26,6 @@ class ToBufferConfiguration extends TaintTracking::Configuration {
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(BufferWrite::BufferWrite w | w.getASource() = sink.asExpr())
|
||||
}
|
||||
|
||||
@@ -47,17 +47,14 @@ class EnvData extends SystemData {
|
||||
/**
|
||||
* Data originating from a call to `mysql_get_client_info()`.
|
||||
*/
|
||||
class SqlClientInfo extends SystemData {
|
||||
SqlClientInfo() { this.(FunctionCall).getTarget().hasName("mysql_get_client_info") }
|
||||
class SQLClientInfo extends SystemData {
|
||||
SQLClientInfo() { this.(FunctionCall).getTarget().hasName("mysql_get_client_info") }
|
||||
|
||||
override DataFlow::Node getAnExpr() { result.asConvertedExpr() = this }
|
||||
|
||||
override predicate isSensitive() { any() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SqlClientInfo */
|
||||
deprecated class SQLClientInfo = SqlClientInfo;
|
||||
|
||||
private predicate sqlConnectInfo(FunctionCall source, Expr use) {
|
||||
(
|
||||
source.getTarget().hasName("mysql_connect") or
|
||||
@@ -69,17 +66,14 @@ private predicate sqlConnectInfo(FunctionCall source, Expr use) {
|
||||
/**
|
||||
* Data passed into an SQL connect function.
|
||||
*/
|
||||
class SqlConnectInfo extends SystemData {
|
||||
SqlConnectInfo() { sqlConnectInfo(this, _) }
|
||||
class SQLConnectInfo extends SystemData {
|
||||
SQLConnectInfo() { sqlConnectInfo(this, _) }
|
||||
|
||||
override DataFlow::Node getAnExpr() { sqlConnectInfo(this, result.asConvertedExpr()) }
|
||||
|
||||
override predicate isSensitive() { any() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SqlConnectInfo */
|
||||
deprecated class SQLConnectInfo = SqlConnectInfo;
|
||||
|
||||
private predicate posixSystemInfo(FunctionCall source, DataFlow::Node use) {
|
||||
// size_t confstr(int name, char *buf, size_t len)
|
||||
// - various OS / system strings, such as the libc version
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
## 0.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Cleartext storage of sensitive information in buffer" (`cpp/cleartext-storage-buffer`) query has been improved to produce fewer false positives.
|
||||
@@ -1 +0,0 @@
|
||||
## 0.3.4
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.4
|
||||
lastReleaseVersion: 0.3.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.3.5-dev
|
||||
version: 0.3.3-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
import cpp
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as IRDataFlow
|
||||
private import semmle.code.cpp.dataflow.DataFlow::DataFlow as AstDataFlow
|
||||
private import semmle.code.cpp.dataflow.DataFlow::DataFlow as ASTDataFlow
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class IRFlowTest extends InlineExpectationsTest {
|
||||
@@ -49,11 +49,11 @@ class AstFlowTest extends InlineExpectationsTest {
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(
|
||||
AstDataFlow::Node source, AstDataFlow::Node sink, AstDataFlow::Configuration conf, int n
|
||||
ASTDataFlow::Node source, ASTDataFlow::Node sink, ASTDataFlow::Configuration conf, int n
|
||||
|
|
||||
tag = "ast" and
|
||||
conf.hasFlow(source, sink) and
|
||||
n = strictcount(AstDataFlow::Node otherSource | conf.hasFlow(otherSource, sink)) and
|
||||
n = strictcount(ASTDataFlow::Node otherSource | conf.hasFlow(otherSource, sink)) and
|
||||
(
|
||||
n = 1 and value = ""
|
||||
or
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.TaintTrackingImpl as AstTaintTracking
|
||||
import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking
|
||||
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
|
||||
import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath
|
||||
import TaintedWithPath::Private
|
||||
@@ -17,7 +17,7 @@ predicate isSinkArgument(Element sink) {
|
||||
)
|
||||
}
|
||||
|
||||
predicate astTaint(Expr source, Element sink) { AstTaintTracking::tainted(source, sink) }
|
||||
predicate astTaint(Expr source, Element sink) { ASTTaintTracking::tainted(source, sink) }
|
||||
|
||||
class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration {
|
||||
override predicate isSink(Element e) { isSinkArgument(e) }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.TaintTrackingImpl as AstTaintTracking
|
||||
import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking
|
||||
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
|
||||
import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
@@ -18,7 +18,7 @@ predicate argToSinkCall(Element sink) {
|
||||
}
|
||||
|
||||
predicate astTaint(Expr source, Element sink) {
|
||||
AstTaintTracking::tainted(source, sink) and argToSinkCall(sink)
|
||||
ASTTaintTracking::tainted(source, sink) and argToSinkCall(sink)
|
||||
}
|
||||
|
||||
class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.security.TaintTrackingImpl as AstTaintTracking
|
||||
import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking
|
||||
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
predicate astTaint(Expr source, Element sink, string globalVar) {
|
||||
AstTaintTracking::taintedIncludingGlobalVars(source, sink, globalVar) and globalVar != ""
|
||||
ASTTaintTracking::taintedIncludingGlobalVars(source, sink, globalVar) and globalVar != ""
|
||||
}
|
||||
|
||||
predicate irTaint(Expr source, Element sink, string globalVar) {
|
||||
|
||||
@@ -64,10 +64,6 @@ edges
|
||||
| test.cpp:201:5:201:17 | EnterFunction: maybe_deref_p | test.cpp:201:5:201:17 | VariableAddress: maybe_deref_p |
|
||||
| test.cpp:210:3:210:9 | Call: call to escape1 | test.cpp:201:5:201:17 | EnterFunction: maybe_deref_p |
|
||||
| test.cpp:210:3:210:9 | Call: call to escape1 | test.cpp:201:5:201:17 | VariableAddress: maybe_deref_p |
|
||||
| test.cpp:234:3:234:13 | Store: ... = ... | test.cpp:238:3:238:9 | Call: call to escape2 |
|
||||
| test.cpp:238:3:238:9 | Call: call to escape2 | test.cpp:239:17:239:17 | Load: p |
|
||||
| test.cpp:263:3:263:13 | Store: ... = ... | test.cpp:267:3:267:9 | Call: call to escape3 |
|
||||
| test.cpp:267:3:267:9 | Call: call to escape3 | test.cpp:268:17:268:17 | Load: p |
|
||||
#select
|
||||
| test.cpp:15:16:15:16 | Load: p | test.cpp:10:3:10:13 | Store: ... = ... | test.cpp:15:16:15:16 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:9:7:9:7 | x | x | test.cpp:10:3:10:13 | Store: ... = ... | here |
|
||||
| test.cpp:24:16:24:16 | Load: p | test.cpp:10:3:10:13 | Store: ... = ... | test.cpp:24:16:24:16 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:9:7:9:7 | x | x | test.cpp:10:3:10:13 | Store: ... = ... | here |
|
||||
@@ -94,5 +90,3 @@ edges
|
||||
| test.cpp:180:14:180:19 | Load: * ... | test.cpp:154:3:154:22 | Store: ... = ... | test.cpp:180:14:180:19 | Load: * ... | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:154:3:154:22 | Store: ... = ... | here |
|
||||
| test.cpp:181:13:181:20 | Load: access to array | test.cpp:155:3:155:21 | Store: ... = ... | test.cpp:181:13:181:20 | Load: access to array | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:155:3:155:21 | Store: ... = ... | here |
|
||||
| test.cpp:182:14:182:19 | Load: * ... | test.cpp:156:3:156:25 | Store: ... = ... | test.cpp:182:14:182:19 | Load: * ... | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:156:3:156:25 | Store: ... = ... | here |
|
||||
| test.cpp:239:17:239:17 | Load: p | test.cpp:234:3:234:13 | Store: ... = ... | test.cpp:239:17:239:17 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:232:7:232:7 | x | x | test.cpp:234:3:234:13 | Store: ... = ... | here |
|
||||
| test.cpp:268:17:268:17 | Load: p | test.cpp:263:3:263:13 | Store: ... = ... | test.cpp:268:17:268:17 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:260:7:260:7 | x | x | test.cpp:263:3:263:13 | Store: ... = ... | here |
|
||||
|
||||
@@ -209,61 +209,4 @@ int maybe_deref_p(bool b) {
|
||||
int field_indirect_maybe_bad(bool b) {
|
||||
escape1();
|
||||
return maybe_deref_p(b);
|
||||
}
|
||||
|
||||
// These next tests cover subsequent stores to the same address in the same basic block.
|
||||
|
||||
static struct S100 s102;
|
||||
|
||||
void not_escape1() {
|
||||
int x;
|
||||
s102.p = &x;
|
||||
s102.p = nullptr;
|
||||
}
|
||||
|
||||
void calls_not_escape1() {
|
||||
not_escape1();
|
||||
int x = *s102.p; // GOOD
|
||||
}
|
||||
|
||||
static struct S100 s103;
|
||||
|
||||
void escape2() {
|
||||
int x;
|
||||
s103.p = nullptr;
|
||||
s103.p = &x;
|
||||
}
|
||||
|
||||
void calls_escape2() {
|
||||
escape2();
|
||||
int x = *s103.p; // BAD
|
||||
}
|
||||
|
||||
bool unknown();
|
||||
static struct S100 s104;
|
||||
|
||||
void not_escape2() {
|
||||
int x;
|
||||
s104.p = &x;
|
||||
if(unknown()) { }
|
||||
s104.p = nullptr;
|
||||
}
|
||||
|
||||
void calls_not_escape2() {
|
||||
not_escape2();
|
||||
int x = *s104.p; // GOOD
|
||||
}
|
||||
|
||||
static struct S100 s105;
|
||||
|
||||
void escape3() {
|
||||
int x;
|
||||
s105.p = nullptr;
|
||||
if(unknown()) { }
|
||||
s105.p = &x;
|
||||
}
|
||||
|
||||
void calls_escape3() {
|
||||
escape3();
|
||||
int x = *s105.p; // BAD
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.2.5
|
||||
|
||||
## 1.2.4
|
||||
|
||||
## 1.2.3
|
||||
|
||||
## 1.2.2
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
## 1.2.4
|
||||
@@ -1 +0,0 @@
|
||||
## 1.2.5
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.5
|
||||
lastReleaseVersion: 1.2.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.2.6-dev
|
||||
version: 1.2.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.2.5
|
||||
|
||||
## 1.2.4
|
||||
|
||||
## 1.2.3
|
||||
|
||||
## 1.2.2
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
## 1.2.4
|
||||
@@ -1 +0,0 @@
|
||||
## 1.2.5
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.5
|
||||
lastReleaseVersion: 1.2.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.2.6-dev
|
||||
version: 1.2.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
## 0.3.5
|
||||
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
|
||||
## 0.3.3
|
||||
|
||||
## 0.3.2
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been
|
||||
deleted.
|
||||
|
||||
5
csharp/ql/lib/change-notes/2022-08-22-xml-rename.md
Normal file
5
csharp/ql/lib/change-notes/2022-08-22-xml-rename.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* Classes/predicates that had upper-case acronym XML in their name have been renamed to Xml to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
@@ -1,10 +0,0 @@
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
@@ -1 +0,0 @@
|
||||
## 0.3.5
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.5
|
||||
lastReleaseVersion: 0.3.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.3.6-dev
|
||||
version: 0.3.4-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -94,20 +94,14 @@ class FormsElement extends XmlElement {
|
||||
/**
|
||||
* Gets attribute's `requireSSL` value.
|
||||
*/
|
||||
string getRequireSsl() {
|
||||
string getRequireSSL() {
|
||||
result = this.getAttribute("requireSSL").getValue().trim().toLowerCase()
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for getRequireSsl */
|
||||
deprecated string getRequireSSL() { result = this.getRequireSsl() }
|
||||
|
||||
/**
|
||||
* Holds if `requireSSL` value is true.
|
||||
*/
|
||||
predicate isRequireSsl() { this.getRequireSsl() = "true" }
|
||||
|
||||
/** DEPRECATED: Alias for isRequireSsl */
|
||||
deprecated predicate isRequireSSL() { this.isRequireSsl() }
|
||||
predicate isRequireSSL() { this.getRequireSSL() = "true" }
|
||||
}
|
||||
|
||||
/** A `<httpCookies>` tag in an ASP.NET configuration file. */
|
||||
@@ -129,23 +123,17 @@ class HttpCookiesElement extends XmlElement {
|
||||
/**
|
||||
* Gets attribute's `requireSSL` value.
|
||||
*/
|
||||
string getRequireSsl() {
|
||||
string getRequireSSL() {
|
||||
result = this.getAttribute("requireSSL").getValue().trim().toLowerCase()
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for getRequireSsl */
|
||||
deprecated string getRequireSSL() { result = this.getRequireSsl() }
|
||||
|
||||
/**
|
||||
* Holds if there is any chance that `requireSSL` is set to `true` either globally or for Forms.
|
||||
*/
|
||||
predicate isRequireSsl() {
|
||||
this.getRequireSsl() = "true"
|
||||
predicate isRequireSSL() {
|
||||
this.getRequireSSL() = "true"
|
||||
or
|
||||
not this.getRequireSsl() = "false" and // not set all, i.e. default
|
||||
exists(FormsElement forms | forms.getFile() = this.getFile() | forms.isRequireSsl())
|
||||
not this.getRequireSSL() = "false" and // not set all, i.e. default
|
||||
exists(FormsElement forms | forms.getFile() = this.getFile() | forms.isRequireSSL())
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for isRequireSsl */
|
||||
deprecated predicate isRequireSSL() { this.isRequireSsl() }
|
||||
}
|
||||
|
||||
20
csharp/ql/lib/semmle/code/csharp/XML.qll
Normal file → Executable file
20
csharp/ql/lib/semmle/code/csharp/XML.qll
Normal file → Executable file
@@ -132,10 +132,7 @@ class XmlFile extends XmlParent, File {
|
||||
XmlElement getARootElement() { result = this.getAChild() }
|
||||
|
||||
/** Gets a DTD associated with this XML file. */
|
||||
XmlDtd getADtd() { xmlDTDs(result, _, _, _, this) }
|
||||
|
||||
/** DEPRECATED: Alias for getADtd */
|
||||
deprecated XmlDtd getADTD() { result = this.getADtd() }
|
||||
XmlDTD getADTD() { xmlDTDs(result, _, _, _, this) }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlFile */
|
||||
@@ -152,7 +149,7 @@ deprecated class XMLFile = XmlFile;
|
||||
* <!ELEMENT lastName (#PCDATA)>
|
||||
* ```
|
||||
*/
|
||||
class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
class XmlDTD extends XmlLocatable, @xmldtd {
|
||||
/** Gets the name of the root element of this DTD. */
|
||||
string getRoot() { xmlDTDs(this, result, _, _, _) }
|
||||
|
||||
@@ -177,8 +174,8 @@ class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlDtd */
|
||||
deprecated class XMLDTD = XmlDtd;
|
||||
/** DEPRECATED: Alias for XmlDTD */
|
||||
deprecated class XMLDTD = XmlDTD;
|
||||
|
||||
/**
|
||||
* An XML element in an XML file.
|
||||
@@ -285,18 +282,15 @@ class XmlNamespace extends XmlLocatable, @xmlnamespace {
|
||||
string getPrefix() { xmlNs(this, result, _, _) }
|
||||
|
||||
/** Gets the URI of this namespace. */
|
||||
string getUri() { xmlNs(this, _, result, _) }
|
||||
|
||||
/** DEPRECATED: Alias for getUri */
|
||||
deprecated string getURI() { result = this.getUri() }
|
||||
string getURI() { xmlNs(this, _, result, _) }
|
||||
|
||||
/** Holds if this namespace has no prefix. */
|
||||
predicate isDefault() { this.getPrefix() = "" }
|
||||
|
||||
override string toString() {
|
||||
this.isDefault() and result = this.getUri()
|
||||
this.isDefault() and result = this.getURI()
|
||||
or
|
||||
not this.isDefault() and result = this.getPrefix() + ":" + this.getUri()
|
||||
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
*
|
||||
* The CSV specification has the following columns:
|
||||
* - Sources:
|
||||
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
|
||||
* `namespace; type; subtypes; name; signature; ext; output; kind`
|
||||
* - Sinks:
|
||||
* `namespace; type; subtypes; name; signature; ext; input; kind; provenance`
|
||||
* `namespace; type; subtypes; name; signature; ext; input; kind`
|
||||
* - Summaries:
|
||||
* `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
|
||||
* - Negative Summaries:
|
||||
* `namespace; type; name; signature; provenance`
|
||||
* `namespace; type; subtypes; name; signature; ext; input; output; kind`
|
||||
*
|
||||
* The interpretation of a row is similar to API-graphs with a left-to-right
|
||||
* reading.
|
||||
* 1. The `namespace` column selects a namespace.
|
||||
@@ -164,27 +163,11 @@ class SummaryModelCsv extends Unit {
|
||||
abstract predicate row(string row);
|
||||
}
|
||||
|
||||
/**
|
||||
* A unit class for adding negative summary model rows.
|
||||
*
|
||||
* Extend this class to add additional flow summary definitions.
|
||||
*/
|
||||
class NegativeSummaryModelCsv extends Unit {
|
||||
/** Holds if `row` specifies a negative summary definition. */
|
||||
abstract predicate row(string row);
|
||||
}
|
||||
private predicate sourceModel(string row) { any(SourceModelCsv s).row(row) }
|
||||
|
||||
/** Holds if `row` is a source model. */
|
||||
predicate sourceModel(string row) { any(SourceModelCsv s).row(row) }
|
||||
private predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
|
||||
|
||||
/** Holds if `row` is a sink model. */
|
||||
predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
|
||||
|
||||
/** Holds if `row` is a summary model. */
|
||||
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
||||
|
||||
/** Holds if `row` is a negative summary model. */
|
||||
predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) }
|
||||
private predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
||||
|
||||
/** Holds if a source model exists for the given parameters. */
|
||||
predicate sourceModel(
|
||||
@@ -247,20 +230,6 @@ predicate summaryModel(
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if a summary model exists indicating there is no flow for the given parameters. */
|
||||
predicate negativeSummaryModel(
|
||||
string namespace, string type, string name, string signature, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
negativeSummaryModel(row) and
|
||||
row.splitAt(";", 0) = namespace and
|
||||
row.splitAt(";", 1) = type and
|
||||
row.splitAt(";", 2) = name and
|
||||
row.splitAt(";", 3) = signature and
|
||||
row.splitAt(";", 4) = provenance
|
||||
)
|
||||
}
|
||||
|
||||
private predicate relevantNamespace(string namespace) {
|
||||
sourceModel(namespace, _, _, _, _, _, _, _, _) or
|
||||
sinkModel(namespace, _, _, _, _, _, _, _, _) or
|
||||
@@ -317,7 +286,38 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
|
||||
|
||||
/** Provides a query predicate to check the CSV data for validation errors. */
|
||||
module CsvValidation {
|
||||
private string getInvalidModelInput() {
|
||||
/** Holds if some row in a CSV-based flow model appears to contain typos. */
|
||||
query predicate invalidModelRow(string msg) {
|
||||
exists(
|
||||
string pred, string namespace, string type, string name, string signature, string ext,
|
||||
string provenance
|
||||
|
|
||||
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
|
||||
or
|
||||
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
|
||||
or
|
||||
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
|
||||
pred = "summary"
|
||||
|
|
||||
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
|
||||
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
|
||||
or
|
||||
not type.regexpMatch("[a-zA-Z0-9_<>,\\+]+") and
|
||||
msg = "Dubious type \"" + type + "\" in " + pred + " model."
|
||||
or
|
||||
not name.regexpMatch("[a-zA-Z0-9_<>,]*") and
|
||||
msg = "Dubious member name \"" + name + "\" in " + pred + " model."
|
||||
or
|
||||
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
|
||||
msg = "Dubious signature \"" + signature + "\" in " + pred + " model."
|
||||
or
|
||||
not ext.regexpMatch("|Attribute") and
|
||||
msg = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
|
||||
or
|
||||
not provenance = ["manual", "generated"] and
|
||||
msg = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
|
||||
)
|
||||
or
|
||||
exists(string pred, AccessPath input, string part |
|
||||
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
|
||||
or
|
||||
@@ -332,11 +332,9 @@ module CsvValidation {
|
||||
part = input.getToken(_) and
|
||||
parseParam(part, _)
|
||||
) and
|
||||
result = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
|
||||
msg = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelOutput() {
|
||||
or
|
||||
exists(string pred, string output, string part |
|
||||
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
|
||||
or
|
||||
@@ -345,123 +343,58 @@ module CsvValidation {
|
||||
invalidSpecComponent(output, part) and
|
||||
not part = "" and
|
||||
not (part = ["Argument", "Parameter"] and pred = "source") and
|
||||
result = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelKind() {
|
||||
exists(string row, string kind | summaryModel(row) |
|
||||
kind = row.splitAt(";", 8) and
|
||||
not kind = ["taint", "value"] and
|
||||
result = "Invalid kind \"" + kind + "\" in summary model."
|
||||
msg = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
|
||||
)
|
||||
or
|
||||
exists(string row, string kind | sinkModel(row) |
|
||||
kind = row.splitAt(";", 7) and
|
||||
not kind = ["code", "sql", "xss", "remote", "html"] and
|
||||
not kind.matches("encryption-%") and
|
||||
result = "Invalid kind \"" + kind + "\" in sink model."
|
||||
)
|
||||
or
|
||||
exists(string row, string kind | sourceModel(row) |
|
||||
kind = row.splitAt(";", 7) and
|
||||
not kind = ["local", "file"] and
|
||||
result = "Invalid kind \"" + kind + "\" in source model."
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelSubtype() {
|
||||
exists(string pred, string row |
|
||||
sourceModel(row) and pred = "source"
|
||||
or
|
||||
sinkModel(row) and pred = "sink"
|
||||
or
|
||||
summaryModel(row) and pred = "summary"
|
||||
|
|
||||
exists(string b |
|
||||
b = row.splitAt(";", 2) and
|
||||
not b = ["true", "false"] and
|
||||
result = "Invalid boolean \"" + b + "\" in " + pred + " model."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelColumnCount() {
|
||||
exists(string pred, string row, int expect |
|
||||
sourceModel(row) and expect = 9 and pred = "source"
|
||||
or
|
||||
sinkModel(row) and expect = 9 and pred = "sink"
|
||||
or
|
||||
summaryModel(row) and expect = 10 and pred = "summary"
|
||||
or
|
||||
negativeSummaryModel(row) and expect = 5 and pred = "negative summary"
|
||||
|
|
||||
exists(int cols |
|
||||
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
|
||||
cols != expect and
|
||||
result =
|
||||
msg =
|
||||
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
|
||||
" in " + row + "."
|
||||
)
|
||||
or
|
||||
exists(string b |
|
||||
b = row.splitAt(";", 2) and
|
||||
not b = ["true", "false"] and
|
||||
msg = "Invalid boolean \"" + b + "\" in " + pred + " model."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelSignature() {
|
||||
exists(
|
||||
string pred, string namespace, string type, string name, string signature, string ext,
|
||||
string provenance
|
||||
|
|
||||
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
|
||||
or
|
||||
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
|
||||
or
|
||||
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
|
||||
pred = "summary"
|
||||
or
|
||||
negativeSummaryModel(namespace, type, name, signature, provenance) and
|
||||
ext = "" and
|
||||
pred = "negative summary"
|
||||
|
|
||||
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
|
||||
result = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
|
||||
or
|
||||
not type.regexpMatch("[a-zA-Z0-9_<>,\\+]+") and
|
||||
result = "Dubious type \"" + type + "\" in " + pred + " model."
|
||||
or
|
||||
not name.regexpMatch("[a-zA-Z0-9_<>,]*") and
|
||||
result = "Dubious member name \"" + name + "\" in " + pred + " model."
|
||||
or
|
||||
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
|
||||
result = "Dubious signature \"" + signature + "\" in " + pred + " model."
|
||||
or
|
||||
not ext.regexpMatch("|Attribute") and
|
||||
result = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
|
||||
or
|
||||
not provenance = ["manual", "generated"] and
|
||||
result = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
|
||||
or
|
||||
exists(string row, string kind | summaryModel(row) |
|
||||
kind = row.splitAt(";", 8) and
|
||||
not kind = ["taint", "value"] and
|
||||
msg = "Invalid kind \"" + kind + "\" in summary model."
|
||||
)
|
||||
or
|
||||
exists(string row, string kind | sinkModel(row) |
|
||||
kind = row.splitAt(";", 7) and
|
||||
not kind = ["code", "sql", "xss", "remote", "html"] and
|
||||
not kind.matches("encryption-%") and
|
||||
msg = "Invalid kind \"" + kind + "\" in sink model."
|
||||
)
|
||||
or
|
||||
exists(string row, string kind | sourceModel(row) |
|
||||
kind = row.splitAt(";", 7) and
|
||||
not kind = ["local", "file"] and
|
||||
msg = "Invalid kind \"" + kind + "\" in source model."
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if some row in a CSV-based flow model appears to contain typos. */
|
||||
query predicate invalidModelRow(string msg) {
|
||||
msg =
|
||||
[
|
||||
getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(),
|
||||
getInvalidModelSubtype(), getInvalidModelColumnCount(), getInvalidModelKind()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private predicate elementSpec(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
) {
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _)
|
||||
or
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _)
|
||||
or
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
|
||||
or
|
||||
negativeSummaryModel(namespace, type, name, signature, _) and ext = "" and subtypes = false
|
||||
}
|
||||
|
||||
private predicate elementSpec(
|
||||
@@ -575,7 +508,7 @@ private Element interpretElement0(
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the source/sink/summary/negativesummary element corresponding to the supplied parameters. */
|
||||
/** Gets the source/sink/summary element corresponding to the supplied parameters. */
|
||||
Element interpretElement(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
) {
|
||||
|
||||
@@ -173,7 +173,7 @@ module Ssa {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this SSA definition is live at the end of basic block `bb`.
|
||||
* Holds is this SSA definition is live at the end of basic block `bb`.
|
||||
* That is, this definition reaches the end of basic block `bb`, at which
|
||||
* point it is still live, without crossing another SSA definition of the
|
||||
* same source variable.
|
||||
|
||||
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll
Normal file → Executable file
@@ -2129,37 +2129,18 @@ module Csv {
|
||||
if isBaseCallableOrPrototype(c) then result = "true" else result = "false"
|
||||
}
|
||||
|
||||
private predicate partialModel(
|
||||
DotNet::Callable c, string namespace, string type, string name, string parameters
|
||||
) {
|
||||
c.getDeclaringType().hasQualifiedName(namespace, type) and
|
||||
c.hasQualifiedName(_, name) and
|
||||
parameters = "(" + parameterQualifiedTypeNamesToString(c) + ")"
|
||||
}
|
||||
|
||||
/** Computes the first 6 columns for positive CSV rows of `c`. */
|
||||
/** Computes the first 6 columns for CSV rows of `c`. */
|
||||
string asPartialModel(DotNet::Callable c) {
|
||||
exists(string namespace, string type, string name, string parameters |
|
||||
partialModel(c, namespace, type, name, parameters) and
|
||||
exists(string namespace, string type, string name |
|
||||
c.getDeclaringType().hasQualifiedName(namespace, type) and
|
||||
c.hasQualifiedName(_, name) and
|
||||
result =
|
||||
namespace + ";" //
|
||||
+ type + ";" //
|
||||
+ getCallableOverride(c) + ";" //
|
||||
+ name + ";" //
|
||||
+ parameters + ";" //
|
||||
+ "(" + parameterQualifiedTypeNamesToString(c) + ")" + ";" //
|
||||
+ /* ext + */ ";" //
|
||||
)
|
||||
}
|
||||
|
||||
/** Computes the first 4 columns for negative CSV rows of `c`. */
|
||||
string asPartialNegativeModel(DotNet::Callable c) {
|
||||
exists(string namespace, string type, string name, string parameters |
|
||||
partialModel(c, namespace, type, name, parameters) and
|
||||
result =
|
||||
namespace + ";" //
|
||||
+ type + ";" //
|
||||
+ name + ";" //
|
||||
+ parameters + ";" //
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,16 +240,6 @@ module Public {
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
}
|
||||
|
||||
/** A callable with a flow summary stating there is no flow via the callable. */
|
||||
class NegativeSummarizedCallable extends SummarizedCallableBase {
|
||||
NegativeSummarizedCallable() { negativeSummaryElement(this, _) }
|
||||
|
||||
/**
|
||||
* Holds if the negative summary is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { negativeSummaryElement(this, true) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1104,7 +1094,7 @@ module Private {
|
||||
|
||||
/** Provides a query predicate for outputting a set of relevant flow summaries. */
|
||||
module TestOutput {
|
||||
/** A flow summary to include in the `summary/1` query predicate. */
|
||||
/** A flow summary to include in the `summary/3` query predicate. */
|
||||
abstract class RelevantSummarizedCallable instanceof SummarizedCallable {
|
||||
/** Gets the string representation of this callable used by `summary/1`. */
|
||||
abstract string getCallableCsv();
|
||||
@@ -1119,14 +1109,6 @@ module Private {
|
||||
string toString() { result = super.toString() }
|
||||
}
|
||||
|
||||
/** A flow summary to include in the `negativeSummary/1` query predicate. */
|
||||
abstract class RelevantNegativeSummarizedCallable instanceof NegativeSummarizedCallable {
|
||||
/** Gets the string representation of this callable used by `summary/1`. */
|
||||
abstract string getCallableCsv();
|
||||
|
||||
string toString() { result = super.toString() }
|
||||
}
|
||||
|
||||
/** Render the kind in the format used in flow summaries. */
|
||||
private string renderKind(boolean preservesValue) {
|
||||
preservesValue = true and result = "value"
|
||||
@@ -1134,12 +1116,8 @@ module Private {
|
||||
preservesValue = false and result = "taint"
|
||||
}
|
||||
|
||||
private string renderProvenance(SummarizedCallable c) {
|
||||
if c.isAutoGenerated() then result = "generated" else result = "manual"
|
||||
}
|
||||
|
||||
private string renderProvenanceNegative(NegativeSummarizedCallable c) {
|
||||
if c.isAutoGenerated() then result = "generated" else result = "manual"
|
||||
private string renderProvenance(RelevantSummarizedCallable c) {
|
||||
if c.(SummarizedCallable).isAutoGenerated() then result = "generated" else result = "manual"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1154,23 +1132,8 @@ module Private {
|
||||
|
|
||||
c.relevantSummary(input, output, preservesValue) and
|
||||
csv =
|
||||
c.getCallableCsv() // Callable information
|
||||
+ getComponentStackCsv(input) + ";" // input
|
||||
+ getComponentStackCsv(output) + ";" // output
|
||||
+ renderKind(preservesValue) + ";" // kind
|
||||
+ renderProvenance(c) // provenance
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a negative flow summary `csv` exists (semi-colon separated format). Used for testing purposes.
|
||||
* The syntax is: "namespace;type;name;signature;provenance"",
|
||||
*/
|
||||
query predicate negativeSummary(string csv) {
|
||||
exists(RelevantNegativeSummarizedCallable c |
|
||||
csv =
|
||||
c.getCallableCsv() // Callable information
|
||||
+ renderProvenanceNegative(c) // provenance
|
||||
c.getCallableCsv() + getComponentStackCsv(input) + ";" + getComponentStackCsv(output) +
|
||||
";" + renderKind(preservesValue) + ";" + renderProvenance(c)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,18 +114,6 @@ predicate summaryElement(Callable c, string input, string output, string kind, b
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a negative flow summary exists for `c`, which means that there is no
|
||||
* flow through `c`. The flag `generated` states whether the summary is autogenerated.
|
||||
*/
|
||||
predicate negativeSummaryElement(Callable c, boolean generated) {
|
||||
exists(string namespace, string type, string name, string signature, string provenance |
|
||||
negativeSummaryModel(namespace, type, name, signature, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
c = interpretElement(namespace, type, false, name, signature, "")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an external source specification exists for `e` with output specification
|
||||
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/** Provides modules for importing negative summaries. */
|
||||
|
||||
/**
|
||||
* A module importing the frameworks that provide external flow data,
|
||||
* ensuring that they are visible to the taint tracking / data flow library.
|
||||
*/
|
||||
private module Frameworks {
|
||||
private import semmle.code.csharp.frameworks.GeneratedNegative
|
||||
}
|
||||
0
csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPublic.qll
Normal file → Executable file
0
csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPublic.qll
Normal file → Executable file
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* A module importing all generated negative Models as Data models.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
private module GeneratedFrameworks {
|
||||
private import generated.dotnet.NegativeRuntime
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -119,13 +119,10 @@ class MicrosoftOwinIOwinRequestClass extends Class {
|
||||
}
|
||||
|
||||
/** Gets the `URI` property. */
|
||||
Property getUriProperty() {
|
||||
Property getURIProperty() {
|
||||
result = this.getAProperty() and
|
||||
result.hasName("URI")
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for getUriProperty */
|
||||
deprecated Property getURIProperty() { result = this.getUriProperty() }
|
||||
}
|
||||
|
||||
/** A `Microsoft.Owin.*String` class. */
|
||||
|
||||
@@ -102,9 +102,7 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode {
|
||||
/** DEPRECATED: Alias for UntrustedExternalApiDataNode */
|
||||
deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode;
|
||||
|
||||
/** An external API which is used with untrusted data. */
|
||||
private newtype TExternalApi =
|
||||
/** An untrusted API method `m` where untrusted data is passed at `index`. */
|
||||
TExternalApiParameter(Callable m, int index) {
|
||||
exists(UntrustedExternalApiDataNode n |
|
||||
m = n.getCallable().getUnboundDeclaration() and
|
||||
|
||||
@@ -146,7 +146,7 @@ class MicrosoftOwinRequestRemoteFlowSource extends RemoteFlowSource, DataFlow::E
|
||||
p = owinRequest.getQueryStringProperty() or
|
||||
p = owinRequest.getRemoteIpAddressProperty() or
|
||||
p = owinRequest.getSchemeProperty() or
|
||||
p = owinRequest.getUriProperty()
|
||||
p = owinRequest.getURIProperty()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
## 0.3.4
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Parameters of delegates passed to routing endpoint calls like `MapGet` in ASP.NET Core are now considered remote flow sources.
|
||||
* The query `cs/unsafe-deserialization-untrusted-input` is not reporting on all calls of `JsonConvert.DeserializeObject` any longer, it only covers cases that explicitly use unsafe serialization settings.
|
||||
* Added better support for the SQLite framework in the SQL injection query.
|
||||
* File streams are now considered stored flow sources. For example, reading query elements from a file can lead to a Second Order SQL injection alert.
|
||||
|
||||
## 0.3.2
|
||||
|
||||
## 0.3.1
|
||||
|
||||
0
csharp/ql/src/Concurrency/FutileSyncOnField.cs
Normal file → Executable file
0
csharp/ql/src/Concurrency/FutileSyncOnField.cs
Normal file → Executable file
0
csharp/ql/src/Concurrency/FutileSyncOnField.ql
Normal file → Executable file
0
csharp/ql/src/Concurrency/FutileSyncOnField.ql
Normal file → Executable file
0
csharp/ql/src/Concurrency/FutileSyncOnFieldFix.cs
Normal file → Executable file
0
csharp/ql/src/Concurrency/FutileSyncOnFieldFix.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/BadCheckOdd.ql
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/BadCheckOdd.ql
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Collections/ReadOnlyContainer.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Collections/ReadOnlyContainer.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Collections/ReadOnlyContainerFix.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Collections/ReadOnlyContainerFix.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/RandomUsedOnce.ql
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/RandomUsedOnce.ql
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Statements/UseBraces.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Statements/UseBraces.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Statements/UseBraces.ql
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Statements/UseBraces.ql
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Statements/UseBracesFix.cs
Normal file → Executable file
0
csharp/ql/src/Likely Bugs/Statements/UseBracesFix.cs
Normal file → Executable file
@@ -22,9 +22,9 @@ import semmle.code.csharp.frameworks.system.Web
|
||||
from XmlElement element
|
||||
where
|
||||
element instanceof FormsElement and
|
||||
not element.(FormsElement).isRequireSsl()
|
||||
not element.(FormsElement).isRequireSSL()
|
||||
or
|
||||
element instanceof HttpCookiesElement and
|
||||
not element.(HttpCookiesElement).isRequireSsl() and
|
||||
not element.(HttpCookiesElement).isRequireSSL() and
|
||||
not any(SystemWebHttpCookie c).getSecureProperty().getAnAssignedValue().getValue() = "true"
|
||||
select element, "The 'requireSSL' attribute is not set to 'true'."
|
||||
|
||||
@@ -8,14 +8,11 @@
|
||||
|
||||
private import csharp
|
||||
private import semmle.code.csharp.dispatch.Dispatch
|
||||
private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import semmle.code.csharp.dataflow.internal.NegativeSummary
|
||||
private import ExternalApi
|
||||
|
||||
private predicate getRelevantUsages(ExternalApi api, int usages) {
|
||||
not api.isUninteresting() and
|
||||
not api.isSupported() and
|
||||
not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable and
|
||||
usages = strictcount(DispatchCall c | c = api.getACall())
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added better support for the SQLite framework in the SQL injection query.
|
||||
* File streams are now considered stored flow sources. Eg. reading query elements from a file can lead to a Second Order SQL injection alert.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query `cs/unsafe-deserialization-untrusted-input` is not reporting on all calls of `JsonConvert.DeserializeObject` any longer, it only covers cases that explicitly use unsafe serialization settings.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Parameters of delegates passed to routing endpoint calls like `MapGet` in ASP.NET Core are now considered remote flow sources.
|
||||
@@ -1,8 +0,0 @@
|
||||
## 0.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Parameters of delegates passed to routing endpoint calls like `MapGet` in ASP.NET Core are now considered remote flow sources.
|
||||
* The query `cs/unsafe-deserialization-untrusted-input` is not reporting on all calls of `JsonConvert.DeserializeObject` any longer, it only covers cases that explicitly use unsafe serialization settings.
|
||||
* Added better support for the SQLite framework in the SQL injection query.
|
||||
* File streams are now considered stored flow sources. For example, reading query elements from a file can lead to a Second Order SQL injection alert.
|
||||
@@ -1 +0,0 @@
|
||||
## 0.3.4
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.4
|
||||
lastReleaseVersion: 0.3.2
|
||||
|
||||
@@ -66,10 +66,10 @@ where
|
||||
// the `exists` below covers the `cs/web/requiressl-not-set`
|
||||
not exists(XmlElement element |
|
||||
element instanceof FormsElement and
|
||||
element.(FormsElement).isRequireSsl()
|
||||
element.(FormsElement).isRequireSSL()
|
||||
or
|
||||
element instanceof HttpCookiesElement and
|
||||
element.(HttpCookiesElement).isRequireSsl()
|
||||
element.(HttpCookiesElement).isRequireSSL()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -29,15 +29,15 @@ newtype TInstruction =
|
||||
UnaliasedSsa::SSA::hasUnreachedInstruction(irFunc)
|
||||
} or
|
||||
TAliasedSsaPhiInstruction(
|
||||
TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation
|
||||
TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation
|
||||
) {
|
||||
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||
AliasedSSA::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||
} or
|
||||
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
||||
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
||||
AliasedSSA::SSA::hasChiInstruction(primaryInstruction)
|
||||
} or
|
||||
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||
AliasedSsa::SSA::hasUnreachedInstruction(irFunc)
|
||||
AliasedSSA::SSA::hasUnreachedInstruction(irFunc)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ module AliasedSsaInstructions {
|
||||
class TPhiInstruction = TAliasedSsaPhiInstruction or TUnaliasedSsaPhiInstruction;
|
||||
|
||||
TPhiInstruction phiInstruction(
|
||||
TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation
|
||||
TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation
|
||||
) {
|
||||
result = TAliasedSsaPhiInstruction(blockStartInstr, memoryLocation)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import experimental.ir.internal.IRCSharpLanguage as Language
|
||||
import experimental.ir.implementation.raw.internal.IRConstruction as IRConstruction
|
||||
import experimental.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSsa
|
||||
import AliasedSSAStub as AliasedSsa
|
||||
|
||||
/** DEPRECATED: Alias for AliasedSsa */
|
||||
deprecated module AliasedSSA = AliasedSsa;
|
||||
import AliasedSSAStub as AliasedSSA
|
||||
|
||||
@@ -5,8 +5,8 @@ private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
private import Imports::TInstruction
|
||||
private import Imports::RawIR as RawIR
|
||||
private import SsaInstructions
|
||||
private import SsaOperands
|
||||
private import SSAInstructions
|
||||
private import SSAOperands
|
||||
private import NewIR
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user