From bfdf262d49e733f11909a194393146293d101bd2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 25 Jul 2025 17:35:26 +0100 Subject: [PATCH 1/2] C++: Block flow into thread-specific storage creating functions (i.e., *almost* the sources of the query) to remove false negatives. --- .../CON30-C/CleanUpThreadSpecificStorage.ql | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql b/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql index afa664448..50ed7f0ff 100644 --- a/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql +++ b/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql @@ -22,15 +22,28 @@ import codingstandards.c.cert import codingstandards.cpp.ConcurrencyNew import semmle.code.cpp.dataflow.new.DataFlow +newtype Direction = + Incoming() or + Outgoing() + +predicate isSource(DataFlow::Node node, Direction d) { + exists(TSSCreateFunctionCall tsc, Expr e | + // the only requirement of the source is that at some point + // it refers to the key of a create statement + e.getParent*() = tsc.getKey() + | + d = Outgoing() and + e = [node.asExpr(), node.asDefiningArgument()] + or + d = Incoming() and + e = [node.asExpr(), node.asIndirectArgument()] + ) +} + module TssCreateToTssDeleteConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node node) { - exists(TSSCreateFunctionCall tsc, Expr e | - // the only requirement of the source is that at some point - // it refers to the key of a create statement - e.getParent*() = tsc.getKey() and - (e = node.asDefiningArgument() or e = node.asExpr()) - ) - } + predicate isSource(DataFlow::Node node) { isSource(node, Outgoing()) } + + predicate isBarrierIn(DataFlow::Node node) { isSource(node, Incoming()) } predicate isSink(DataFlow::Node node) { exists(TSSDeleteFunctionCall tsd, Expr e | From 086a4ed76a5122eef27f982f2233469169e56d46 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 25 Jul 2025 17:36:05 +0100 Subject: [PATCH 2/2] C++: Accept test changes to another query. --- ...TimedlockOnInappropriateMutexType.expected | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/c/misra/test/rules/RULE-21-26/TimedlockOnInappropriateMutexType.expected b/c/misra/test/rules/RULE-21-26/TimedlockOnInappropriateMutexType.expected index 0a4c0a496..34b92fee9 100644 --- a/c/misra/test/rules/RULE-21-26/TimedlockOnInappropriateMutexType.expected +++ b/c/misra/test/rules/RULE-21-26/TimedlockOnInappropriateMutexType.expected @@ -1,11 +1,25 @@ edges +| test.c:3:7:3:8 | *g1 | test.c:3:7:3:8 | *g1 | provenance | | +| test.c:3:7:3:8 | *g1 | test.c:14:17:14:19 | *& ... | provenance | | +| test.c:3:7:3:8 | *g1 | test.c:15:14:15:16 | *& ... | provenance | | +| test.c:4:7:4:8 | *g2 | test.c:4:7:4:8 | *g2 | provenance | | +| test.c:4:7:4:8 | *g2 | test.c:18:17:18:19 | *& ... | provenance | | +| test.c:4:7:4:8 | *g2 | test.c:19:14:19:16 | *& ... | provenance | | +| test.c:10:24:10:24 | *m | test.c:10:24:10:24 | *m | provenance | | | test.c:10:24:10:24 | *m | test.c:10:43:10:43 | *m | provenance | | +| test.c:10:24:10:24 | *m | test.c:10:43:10:43 | *m | provenance | | +| test.c:13:12:13:14 | mtx_init output argument | test.c:3:7:3:8 | *g1 | provenance | | | test.c:13:12:13:14 | mtx_init output argument | test.c:14:17:14:19 | *& ... | provenance | | | test.c:13:12:13:14 | mtx_init output argument | test.c:15:14:15:16 | *& ... | provenance | | | test.c:15:14:15:16 | *& ... | test.c:10:24:10:24 | *m | provenance | | +| test.c:15:14:15:16 | *& ... | test.c:15:14:15:16 | doTimeLock output argument | provenance | | +| test.c:15:14:15:16 | doTimeLock output argument | test.c:3:7:3:8 | *g1 | provenance | | +| test.c:17:12:17:14 | mtx_init output argument | test.c:4:7:4:8 | *g2 | provenance | | | test.c:17:12:17:14 | mtx_init output argument | test.c:18:17:18:19 | *& ... | provenance | | | test.c:17:12:17:14 | mtx_init output argument | test.c:19:14:19:16 | *& ... | provenance | | | test.c:19:14:19:16 | *& ... | test.c:10:24:10:24 | *m | provenance | | +| test.c:19:14:19:16 | *& ... | test.c:19:14:19:16 | doTimeLock output argument | provenance | | +| test.c:19:14:19:16 | doTimeLock output argument | test.c:4:7:4:8 | *g2 | provenance | | | test.c:30:12:30:14 | mtx_init output argument | test.c:31:17:31:19 | *& ... | provenance | | | test.c:30:12:30:14 | mtx_init output argument | test.c:32:14:32:16 | *& ... | provenance | | | test.c:32:14:32:16 | *& ... | test.c:10:24:10:24 | *m | provenance | | @@ -16,14 +30,20 @@ edges | test.c:44:14:44:18 | *& ... | test.c:10:24:10:24 | *m | provenance | | | test.c:44:15:44:16 | *l3 [m] | test.c:44:14:44:18 | *& ... | provenance | | nodes +| test.c:3:7:3:8 | *g1 | semmle.label | *g1 | +| test.c:4:7:4:8 | *g2 | semmle.label | *g2 | +| test.c:10:24:10:24 | *m | semmle.label | *m | +| test.c:10:24:10:24 | *m | semmle.label | *m | | test.c:10:24:10:24 | *m | semmle.label | *m | | test.c:10:43:10:43 | *m | semmle.label | *m | | test.c:13:12:13:14 | mtx_init output argument | semmle.label | mtx_init output argument | | test.c:14:17:14:19 | *& ... | semmle.label | *& ... | | test.c:15:14:15:16 | *& ... | semmle.label | *& ... | +| test.c:15:14:15:16 | doTimeLock output argument | semmle.label | doTimeLock output argument | | test.c:17:12:17:14 | mtx_init output argument | semmle.label | mtx_init output argument | | test.c:18:17:18:19 | *& ... | semmle.label | *& ... | | test.c:19:14:19:16 | *& ... | semmle.label | *& ... | +| test.c:19:14:19:16 | doTimeLock output argument | semmle.label | doTimeLock output argument | | test.c:30:12:30:14 | mtx_init output argument | semmle.label | mtx_init output argument | | test.c:31:17:31:19 | *& ... | semmle.label | *& ... | | test.c:32:14:32:16 | *& ... | semmle.label | *& ... | @@ -34,6 +54,8 @@ nodes | test.c:44:14:44:18 | *& ... | semmle.label | *& ... | | test.c:44:15:44:16 | *l3 [m] | semmle.label | *l3 [m] | subpaths +| test.c:15:14:15:16 | *& ... | test.c:10:24:10:24 | *m | test.c:10:24:10:24 | *m | test.c:15:14:15:16 | doTimeLock output argument | +| test.c:19:14:19:16 | *& ... | test.c:10:24:10:24 | *m | test.c:10:24:10:24 | *m | test.c:19:14:19:16 | doTimeLock output argument | #select | test.c:10:43:10:43 | *m | test.c:13:12:13:14 | mtx_init output argument | test.c:10:43:10:43 | *m | Call to mtx_timedlock with mutex which is $@ without flag 'mtx_timed'. | test.c:13:12:13:14 | mtx_init output argument | initialized | | test.c:10:43:10:43 | *m | test.c:17:12:17:14 | mtx_init output argument | test.c:10:43:10:43 | *m | Call to mtx_timedlock with mutex which is $@ without flag 'mtx_timed'. | test.c:17:12:17:14 | mtx_init output argument | initialized |