diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 2e6daad1f84..49f61eb0aed 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -323,7 +323,7 @@ private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode override predicate argumentOf(DataFlowCall dfCall, ArgumentPosition pos) { this.getCallInstruction() = dfCall and pos.(IndirectionPosition).getArgumentIndex() = this.getArgumentIndex() and - pos.(IndirectionPosition).getIndirectionIndex() = super.getIndirectionIndex() + super.hasAddressOperandAndIndirectionIndex(_, pos.(IndirectionPosition).getIndirectionIndex()) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 9a3fd679f23..63e49c20c28 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -274,7 +274,7 @@ class Node extends TIRDataFlowNode { * represents the value of `**x` going into `f`. */ Expr asIndirectArgument(int index) { - this.(SideEffectOperandNode).getIndirectionIndex() = index and + this.(SideEffectOperandNode).hasAddressOperandAndIndirectionIndex(_, index) and result = this.(SideEffectOperandNode).getArgument() } @@ -317,7 +317,7 @@ class Node extends TIRDataFlowNode { index = 0 and result = this.(ExplicitParameterNode).getParameter() or - this.(IndirectParameterNode).getIndirectionIndex() = index and + this.(IndirectParameterNode).hasInstructionAndIndirectionIndex(_, index) and result = this.(IndirectParameterNode).getParameter() } @@ -577,15 +577,19 @@ class SsaPhiNode extends Node, TSsaPhiNode { * * A node representing a value after leaving a function. */ -class SideEffectOperandNode extends Node, IndirectOperand { +class SideEffectOperandNode extends Node instanceof IndirectOperand { CallInstruction call; int argumentIndex; - SideEffectOperandNode() { operand = call.getArgumentOperand(argumentIndex) } + SideEffectOperandNode() { + IndirectOperand.super.hasOperandAndIndirectionIndex(call.getArgumentOperand(argumentIndex), _) + } CallInstruction getCallInstruction() { result = call } - Operand getAddressOperand() { result = operand } + predicate hasAddressOperandAndIndirectionIndex(Operand operand, int indirectionIndex) { + IndirectOperand.super.hasOperandAndIndirectionIndex(operand, indirectionIndex) + } int getArgumentIndex() { result = argumentIndex } @@ -665,10 +669,10 @@ class InitialGlobalValue extends Node, TInitialGlobalValue { * * A node representing an indirection of a parameter. */ -class IndirectParameterNode extends Node, IndirectInstruction { +class IndirectParameterNode extends Node instanceof IndirectInstruction { InitializeParameterInstruction init; - IndirectParameterNode() { this.getInstruction() = init } + IndirectParameterNode() { IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _) } int getArgumentIndex() { init.hasIndex(result) } @@ -677,7 +681,12 @@ class IndirectParameterNode extends Node, IndirectInstruction { override Declaration getEnclosingCallable() { result = this.getFunction() } - override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() } + override Declaration getFunction() { result = init.getEnclosingFunction() } + + /** Gets the underlying instruction. */ + predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) { + IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index) + } override Location getLocationImpl() { result = this.getParameter().getLocation() } @@ -699,7 +708,8 @@ class IndirectReturnNode extends Node { IndirectReturnNode() { this instanceof FinalParameterNode or - this.(IndirectOperand).getOperand() = any(ReturnValueInstruction ret).getReturnAddressOperand() + this.(IndirectOperand) + .hasOperandAndIndirectionIndex(any(ReturnValueInstruction ret).getReturnAddressOperand(), _) } override Declaration getEnclosingCallable() { result = this.getFunction() } @@ -722,7 +732,7 @@ class IndirectReturnNode extends Node { int getIndirectionIndex() { result = this.(FinalParameterNode).getIndirectionIndex() or - result = this.(IndirectOperand).getIndirectionIndex() + this.(IndirectOperand).hasOperandAndIndirectionIndex(_, result) } } @@ -1106,7 +1116,8 @@ predicate exprNodeShouldBeInstruction(Node node, Expr e) { /** Holds if `node` should be an `IndirectInstruction` that maps `node.asIndirectExpr()` to `e`. */ predicate indirectExprNodeShouldBeIndirectInstruction(IndirectInstruction node, Expr e) { exists(Instruction instr | - instr = node.getInstruction() and not indirectExprNodeShouldBeIndirectOperand(_, e) + node.hasInstructionAndIndirectionIndex(instr, _) and + not indirectExprNodeShouldBeIndirectOperand(_, e) | e = instr.(VariableAddressInstruction).getAst().(Expr).getFullyConverted() or @@ -1307,8 +1318,8 @@ pragma[noinline] private predicate indirectParameterNodeHasArgumentIndexAndIndex( IndirectParameterNode node, int argumentIndex, int indirectionIndex ) { - node.getArgumentIndex() = argumentIndex and - node.getIndirectionIndex() = indirectionIndex + node.hasInstructionAndIndirectionIndex(_, indirectionIndex) and + node.getArgumentIndex() = argumentIndex } /** A synthetic parameter to model the pointed-to object of a pointer parameter. */ @@ -1479,18 +1490,14 @@ VariableNode variableNode(Variable v) { */ Node uninitializedNode(LocalVariable v) { none() } -pragma[noinline] predicate hasOperandAndIndex(IndirectOperand indirectOperand, Operand operand, int indirectionIndex) { - indirectOperand.getOperand() = operand and - indirectOperand.getIndirectionIndex() = indirectionIndex + indirectOperand.hasOperandAndIndirectionIndex(operand, indirectionIndex) } -pragma[noinline] predicate hasInstructionAndIndex( IndirectInstruction indirectInstr, Instruction instr, int indirectionIndex ) { - indirectInstr.getInstruction() = instr and - indirectInstr.getIndirectionIndex() = indirectionIndex + indirectInstr.hasInstructionAndIndirectionIndex(instr, indirectionIndex) } cached @@ -1656,8 +1663,7 @@ module ExprFlowCached { private predicate isIndirectBaseOfArrayAccess(IndirectOperand n, Expr e) { exists(LoadInstruction load, PointerArithmeticInstruction pai | pai = load.getSourceAddress() and - pai.getLeftOperand() = n.getOperand() and - n.getIndirectionIndex() = 1 and + n.hasOperandAndIndirectionIndex(pai.getLeftOperand(), 1) and e = load.getConvertedResultExpression() ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 55135e180d8..b0e092eda62 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -263,7 +263,7 @@ private module IteratorIndirections { // Taint through `operator+=` and `operator-=` on iterators. call.getStaticCallTarget() instanceof Iterator::IteratorAssignArithmeticOperator and node2.(IndirectArgumentOutNode).getPreUpdateNode() = node1 and - node1.(IndirectOperand).getOperand() = call.getArgumentOperand(0) and + node1.(IndirectOperand).hasOperandAndIndirectionIndex(call.getArgumentOperand(0), _) and node1.getType().getUnspecifiedType() = this ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index c3b8765a72a..028f5bad9da 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -160,7 +160,7 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut) { FunctionInput modelIn, FunctionOutput modelOut | indirectArgument = callInput(call, modelIn) and - indirectArgument.getAddressOperand() = nodeIn.asOperand() and + indirectArgument.hasAddressOperandAndIndirectionIndex(nodeIn.asOperand(), _) and call.getStaticCallTarget() = func and ( func.(DataFlowFunction).hasDataFlow(modelIn, modelOut)