diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 76a1299cb536..7d05306f6d6a 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -685,6 +685,12 @@ class IRGuardCondition extends Instruction { unary_compares_eq(valueNumber(this), op, k, areEqual, value) } + bindingset[value] + pragma[inline_late] + private predicate ensuresEqvalueControls(IRBlock block, AbstractValue value) { + this.valueControls(block, value) + } + /** * Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`. * If `areEqual = false` then this implies `left != right + k`. @@ -693,7 +699,7 @@ class IRGuardCondition extends Instruction { predicate ensuresEq(Operand left, Operand right, int k, IRBlock block, boolean areEqual) { exists(AbstractValue value | compares_eq(valueNumber(this), left, right, k, areEqual, value) and - this.valueControls(block, value) + this.ensuresEqvalueControls(block, value) ) } diff --git a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql index 93494987360d..6ccea7cd8966 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql @@ -46,10 +46,13 @@ predicate hasUpperBoundsCheck(Variable var) { ) } -predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) { - exists(Instruction instr | instr = node.asOperand().getDef() | - readsVariable(instr, checkedVar) and - any(IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true) +predicate nodeHasBarrierEquality(DataFlow::Node node) { + exists(Variable checkedVar, Operand access | + readsVariable(access.getDef(), checkedVar) and + exists(Instruction instr | instr = node.asOperand().getDef() | + readsVariable(pragma[only_bind_into](instr), pragma[only_bind_into](checkedVar)) and + any(IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true) + ) ) } @@ -76,10 +79,7 @@ module TaintedAllocationSizeConfig implements DataFlow::ConfigSig { hasUpperBoundsCheck(checkedVar) ) or - exists(Variable checkedVar, Operand access | - readsVariable(access.getDef(), checkedVar) and - nodeIsBarrierEqualityCandidate(node, access, checkedVar) - ) + nodeHasBarrierEquality(node) or // block flow to inside of identified allocation functions (this flow leads // to duplicate results)