From d63b73406caa1f1158236ca1da66ce8b296d742c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 13 Jan 2025 18:33:18 +0000 Subject: [PATCH 1/5] C++: Add dataflow skeleton for barrier guards on indirect instruction/operand nodes. --- .../semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 6 ++++++ 1 file changed, 6 insertions(+) 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 5a5607dbf3bf..8b5e3f028650 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 @@ -2494,6 +2494,12 @@ module InstructionBarrierGuard Date: Mon, 13 Jan 2025 18:33:52 +0000 Subject: [PATCH 2/5] C++: Add a testcase that needs indirect instruction/operand nodes. --- .../dataflow/ir-barrier-guards/test.cpp | 9 ++++ .../dataflow/ir-barrier-guards/test.expected | 0 .../dataflow/ir-barrier-guards/test.ql | 42 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp create mode 100644 cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.expected create mode 100644 cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql diff --git a/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp new file mode 100644 index 000000000000..beff1fc5aacc --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp @@ -0,0 +1,9 @@ +bool checkArgument(int* x); + +void sink(int); + +void testCheckArgument(int* p) { + if (checkArgument(p)) { + sink(*p); // $ barrier MISSING:barrier=1 + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.expected b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql new file mode 100644 index 000000000000..15b165a7de11 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql @@ -0,0 +1,42 @@ +import cpp +import semmle.code.cpp.dataflow.new.DataFlow +import semmle.code.cpp.controlflow.IRGuards +import utils.test.InlineExpectationsTest + +predicate instructionGuardChecks(IRGuardCondition gc, Instruction checked, boolean branch) { + exists(CallInstruction call | + call.getStaticCallTarget().hasName("checkArgument") and + checked = call.getAnArgument() and + gc.comparesEq(call.getAUse(), 0, false, any(BooleanValue bv | bv.getValue() = branch)) + ) +} + +module BarrierGuard = DataFlow::InstructionBarrierGuard; + +predicate indirectBarrierGuard(DataFlow::Node node, int indirectionIndex) { + node = BarrierGuard::getAnIndirectBarrierNode(indirectionIndex) +} + +predicate barrierGuard(DataFlow::Node node) { node = BarrierGuard::getABarrierNode() } + +module Test implements TestSig { + string getARelevantTag() { result = "barrier" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node node | + barrierGuard(node) and + value = "" + or + exists(int indirectionIndex | + indirectBarrierGuard(node, indirectionIndex) and + value = indirectionIndex.toString() + ) + | + tag = "barrier" and + element = node.toString() and + location = node.getLocation() + ) + } +} + +import MakeTest From 6f3a2c41b3d31f8bc5482b1458d4a9058e528b8a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 13 Jan 2025 18:34:32 +0000 Subject: [PATCH 3/5] C++: Fill in skeleton for indirect instruction/operand barrier nodes. --- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) 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 8b5e3f028650..4dabd917b3d3 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 @@ -2495,11 +2495,35 @@ module InstructionBarrierGuard Date: Mon, 13 Jan 2025 18:34:42 +0000 Subject: [PATCH 4/5] C++: Accept test changes. --- cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp index beff1fc5aacc..acbe0223dac5 100644 --- a/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp @@ -4,6 +4,6 @@ void sink(int); void testCheckArgument(int* p) { if (checkArgument(p)) { - sink(*p); // $ barrier MISSING:barrier=1 + sink(*p); // $ barrier barrier=1 } } \ No newline at end of file From d9d0d9348cdd8bdd3546a7f97b8ac469d2af4594 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 13 Jan 2025 18:53:59 +0000 Subject: [PATCH 5/5] C++: Add change note. --- .../2025-01-13-indirect-instruction-barrier-guard.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2025-01-13-indirect-instruction-barrier-guard.md diff --git a/cpp/ql/lib/change-notes/2025-01-13-indirect-instruction-barrier-guard.md b/cpp/ql/lib/change-notes/2025-01-13-indirect-instruction-barrier-guard.md new file mode 100644 index 000000000000..61f406a8179e --- /dev/null +++ b/cpp/ql/lib/change-notes/2025-01-13-indirect-instruction-barrier-guard.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Add a new predicate `getAnIndirectBarrier` to the parameterized module `InstructionBarrierGuard` in `semmle.code.cpp.dataflow.new.DataFlow` for computing indirect dataflow nodes that are guarded by a given instruction. This predicate is similar to the `getAnIndirectBarrier` predicate on the parameterized module `BarrierGuard`. \ No newline at end of file