C++: Add QLDoc.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-07-18 16:53:50 +01:00
parent 576f021c25
commit 3e1b4d97fe
3 changed files with 52 additions and 5 deletions

View File

@@ -1,3 +1,8 @@
/**
* This file provides the first phase of the `cpp/invalid-pointer-deref` query that identifies flow
* an allocation to a pointer-arithmetic instruction that constructs a pointer that's out of bounds.
*/
private import cpp
private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
private import semmle.code.cpp.ir.ValueNumbering
@@ -85,6 +90,10 @@ module Barrier2 {
)
}
/**
* Gets an instruction that is guarded by a guard condition which ensures that
* the value of the instruction is upper-bounded by size of some allocation.
*/
Instruction getABarrierInstruction(FlowState2 state) {
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge |
use = value.getAUse() and
@@ -95,16 +104,24 @@ module Barrier2 {
)
}
/**
* Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that
* the value of the node is upper-bounded by size of some allocation.
*/
DataFlow::Node getABarrierNode(FlowState2 state) {
result.asOperand() = getABarrierInstruction(state).getAUse()
}
/**
* Gets the block of a node that is guarded (see `getABarrierInstruction` or
* `getABarrierNode` for the definition of what it means to be guarded).
*/
IRBlock getABarrierBlock(FlowState2 state) {
result.getAnInstruction() = getABarrierInstruction(state)
}
}
module InterestingPointerAddInstruction {
private module InterestingPointerAddInstruction {
private module PointerAddInstructionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// The sources is the same as in the sources for the second
@@ -119,6 +136,12 @@ module InterestingPointerAddInstruction {
private import DataFlow::Global<PointerAddInstructionConfig>
/**
* Holds if `pai` is a pointer-arithmetic instruction such that the
* result of an allocation flows to the left-hand side of `pai`.
*
* This predicate is used to reduce the set of tuples in `isSinkPair`.
*/
predicate isInteresting(PointerAddInstruction pai) {
exists(DataFlow::Node n |
n.asInstruction() = pai.getLeft() and
@@ -210,12 +233,18 @@ private predicate pointerAddInstructionHasBounds0(
pai.getRight() = right and
pai.getLeft() = sink1.asInstruction() and
instr2 = sink2.asInstruction() and
// pai.getRight() <= sink2 + delta
bounded1(right, instr2, delta) and
not right = Barrier2::getABarrierInstruction(delta) and
not instr2 = Barrier2::getABarrierInstruction(delta)
)
}
/**
* Holds if `allocation` flows to `sink1` and `sink1` represents the left-hand
* side of the pointer-arithmetic instruction `pai`, and the right-hand side of `pai`
* is non-strictly upper bounded by the size of `alllocation` + `delta`.
*/
pragma[nomagic]
predicate pointerAddInstructionHasBounds(
DataFlow::Node allocation, PointerAddInstruction pai, DataFlow::Node sink1, int delta

View File

@@ -1,3 +1,9 @@
/**
* This file provides the second phase of the `cpp/invalid-pointer-deref` query that identifies flow
* from the out-of-bounds pointer identified by the `AllocationToInvalidPointer.qll` library to
* a dereference of the out-of-bounds pointer.
*/
private import cpp
private import semmle.code.cpp.dataflow.new.DataFlow
private import semmle.code.cpp.ir.ValueNumbering

View File

@@ -1,11 +1,12 @@
/**
* This file contains the range-analysis specific parts of the `cpp/invalid-pointer-deref` query
* that is used by both `AllocationToInvalidPointer.qll` and `InvalidPointerToDereference.qll`.
*/
private import cpp
private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.ir.IR
private import codeql.util.Unit
pragma[nomagic]
private Instruction getABoundIn(SemBound b, IRFunction func) {
@@ -25,12 +26,23 @@ private predicate boundedImpl(Instruction i, Instruction b, int delta) {
)
}
/**
* Holds if `i <= b + delta`.
*
* This predicate enforces a join-order that ensures that `i` has already been bound.
*/
bindingset[i]
pragma[inline_late]
predicate bounded1(Instruction i, Instruction b, int delta) { boundedImpl(i, b, delta) }
/**
* Holds if `i <= b + delta`.
*
* This predicate enforces a join-order that ensures that `b` has already been bound.
*/
bindingset[b]
pragma[inline_late]
predicate bounded2(Instruction i, Instruction b, int delta) { boundedImpl(i, b, delta) }
/** Holds if `i <= b + delta`. */
predicate bounded = boundedImpl/3;