mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
113 lines
3.6 KiB
Plaintext
113 lines
3.6 KiB
Plaintext
private import cpp as Language
|
|
import semmle.code.cpp.dataflow.new.TaintTracking
|
|
import codeql.quantum.experimental.Model
|
|
private import OpenSSL.GenericSourceCandidateLiteral
|
|
|
|
module CryptoInput implements InputSig<Language::Location> {
|
|
class DataFlowNode = DataFlow::Node;
|
|
|
|
class LocatableElement = Language::Locatable;
|
|
|
|
class UnknownLocation = Language::UnknownLocation;
|
|
|
|
LocatableElement dfn_to_element(DataFlow::Node node) {
|
|
result = node.asExpr() or
|
|
result = node.asParameter() or
|
|
result = node.asVariable() or
|
|
result = node.asDefiningArgument() or
|
|
result = node.asIndirectExpr()
|
|
}
|
|
|
|
string locationToFileBaseNameAndLineNumberString(Location location) {
|
|
result = location.getFile().getBaseName() + ":" + location.getStartLine()
|
|
}
|
|
|
|
predicate artifactOutputFlowsToGenericInput(
|
|
DataFlow::Node artifactOutput, DataFlow::Node otherInput
|
|
) {
|
|
ArtifactFlow::flow(artifactOutput, otherInput)
|
|
}
|
|
}
|
|
|
|
module Crypto = CryptographyBase<Language::Location, CryptoInput>;
|
|
|
|
module ArtifactFlowConfig implements DataFlow::ConfigSig {
|
|
predicate isSource(DataFlow::Node source) {
|
|
source = any(Crypto::ArtifactInstance artifact).getOutputNode()
|
|
}
|
|
|
|
predicate isSink(DataFlow::Node sink) {
|
|
sink = any(Crypto::FlowAwareElement other).getInputNode()
|
|
}
|
|
|
|
predicate isBarrierOut(DataFlow::Node node) {
|
|
node = any(Crypto::FlowAwareElement element).getInputNode()
|
|
}
|
|
|
|
predicate isBarrierIn(DataFlow::Node node) {
|
|
node = any(Crypto::FlowAwareElement element).getOutputNode()
|
|
}
|
|
|
|
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
node1.(AdditionalFlowInputStep).getOutput() = node2
|
|
}
|
|
}
|
|
|
|
module ArtifactFlow = TaintTracking::Global<ArtifactFlowConfig>;
|
|
|
|
/**
|
|
* An artifact output to node input configuration
|
|
*/
|
|
abstract class AdditionalFlowInputStep extends DataFlow::Node {
|
|
abstract DataFlow::Node getOutput();
|
|
|
|
final DataFlow::Node getInput() { result = this }
|
|
}
|
|
|
|
/**
|
|
* Generic data source to node input configuration
|
|
*/
|
|
module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
|
|
predicate isSource(DataFlow::Node source) {
|
|
source = any(Crypto::GenericSourceInstance i).getOutputNode()
|
|
}
|
|
|
|
predicate isSink(DataFlow::Node sink) {
|
|
sink = any(Crypto::FlowAwareElement other).getInputNode()
|
|
}
|
|
|
|
predicate isBarrierOut(DataFlow::Node node) {
|
|
node = any(Crypto::FlowAwareElement element).getInputNode()
|
|
}
|
|
|
|
predicate isBarrierIn(DataFlow::Node node) {
|
|
node = any(Crypto::FlowAwareElement element).getOutputNode()
|
|
}
|
|
|
|
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
node1.(AdditionalFlowInputStep).getOutput() = node2
|
|
}
|
|
}
|
|
|
|
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
|
|
|
|
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof OpenSslGenericSourceCandidateLiteral
|
|
{
|
|
override DataFlow::Node getOutputNode() {
|
|
// OpenSSL algorithms may be referenced either by string name or by numeric ID:
|
|
// String names (e.g. "AES-256-CBC") appear in the AST as character pointer
|
|
// literals. For these we must use `asIndirectExpr`. Numeric IDs (e.g. NID_aes_256_cbc)
|
|
// appear as integer literals. For these, we must use `asExpr` to get the "value" node.
|
|
[result.asIndirectExpr(), result.asExpr()] = this
|
|
}
|
|
|
|
override predicate flowsTo(Crypto::FlowAwareElement other) {
|
|
// TODO: separate config to avoid blowing up data-flow analysis
|
|
GenericDataSourceFlow::flow(this.getOutputNode(), other.getInputNode())
|
|
}
|
|
|
|
override string getAdditionalDescription() { result = this.toString() }
|
|
}
|
|
|
|
import OpenSSL.OpenSSL
|