mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge pull request #14006 from MathiasVP/promote-invalid-pointer-deref-out-of-experimental
C++: Promote `cpp/invalid-pointer-deref` out of experimental
This commit is contained in:
@@ -20,28 +20,10 @@ import semmle.code.cpp.models.interfaces.Allocation
|
||||
import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
|
||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
||||
import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
import StringSizeFlow::PathGraph1
|
||||
import codeql.util.Unit
|
||||
|
||||
pragma[nomagic]
|
||||
Instruction getABoundIn(SemBound b, IRFunction func) {
|
||||
getSemanticExpr(result) = b.getExpr(0) and
|
||||
result.getEnclosingIRFunction() = func
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `i <= b + delta`.
|
||||
*/
|
||||
bindingset[i]
|
||||
pragma[inline_late]
|
||||
predicate bounded(Instruction i, Instruction b, int delta) {
|
||||
exists(SemBound bound, IRFunction func |
|
||||
semBounded(getSemanticExpr(i), bound, delta, true, _) and
|
||||
b = getABoundIn(bound, func) and
|
||||
i.getEnclosingIRFunction() = func
|
||||
)
|
||||
}
|
||||
|
||||
VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>The program performs an out-of-bounds read or write operation. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.</p>
|
||||
<p>The program performs an out-of-bounds read or write operation, which can cause program instability. In addition, attackers may take advantage of the situation, and implement techniques to use this vulnerability to execute arbitrary code.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
@@ -13,7 +13,7 @@
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The first example allocates a buffer of size <code>size</code> and creates a local variable that stores the location that is one byte past the end of the allocation.
|
||||
This local variable is then dereferenced which results in an out-of-bounds write.
|
||||
This local variable is then dereferenced, which results in an out-of-bounds write.
|
||||
The second example subtracts one from the <code>end</code> variable before dereferencing it. This subtraction ensures that the write correctly updates the final byte of the allocation.</p>
|
||||
<sample src="InvalidPointerDeref.cpp" />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @name Invalid pointer dereference
|
||||
* @description Dereferencing a pointer that points past it allocation is undefined behavior
|
||||
* and may lead to security vulnerabilities.
|
||||
* @description Dereferencing an out-of-bounds pointer is undefined behavior and may lead to security vulnerabilities.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @security-severity 9.3
|
||||
* @precision medium
|
||||
* @id cpp/invalid-pointer-deref
|
||||
* @tags reliability
|
||||
* security
|
||||
@@ -94,6 +94,12 @@ module FinalConfig implements DataFlow::StateConfigSig {
|
||||
)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() {
|
||||
result =
|
||||
allocationToInvalidPointerFieldFlowBranchLimit()
|
||||
.maximum(invalidPointerToDereferenceFieldFlowBranchLimit())
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
|
||||
) {
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes.
|
||||
Reference in New Issue
Block a user