Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion adapters/semgrep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,12 @@ nothing in this table, and no wave since has — including C's, which exercises
only nine of the thirteen rows because the other four templates are
inapplicable to the language and therefore never selected at all.

Challenge Amendment A2 prospectively adds a fourteenth row for v0.8.0.
`chal-interprocedural-exception-persistence` is likewise `unsupported`: it
requires an interprocedural heap side effect to survive exceptional return,
while the pinned CE profile has no interprocedural taint. This addition does
not change any v0.7.0-or-earlier partition or result.

The decision is implemented as `CHALLENGE_SEMGREP_PARTITION` in `src/adapters/semgrep.rs`,
keyed by `template_id` and consulted *before* the `feature_tags` rule. Keying it
by template rather than by tags is deliberate: it means no fixture author's tag
Expand Down Expand Up @@ -251,6 +257,7 @@ single-function challenge templates too.
| D | `chal-deep-relay-chain` | `unsupported` | A six-hop interprocedural relay. `docs/challenge-tier.md` already records stratum D as beyond CE's documented scope. |
| D | `chal-recursive-carry` | `unsupported` | A recursive summary is interprocedural; CE has no interprocedural taint. |
| D | `chal-context-pair-depth2` | `unsupported` | Two-level context sensitivity; CE has no interprocedural taint and therefore no calling context to be sensitive to. |
| D | `chal-interprocedural-exception-persistence` | `unsupported` | Requires a heap side effect to survive an exceptional callee exit and then return normally through the caller; CE has no interprocedural taint. |

The consequence, stated in advance: when a language's challenge fixtures land,
its Semgrep kernel's selected population grows with its rollout row while its
Expand Down Expand Up @@ -947,4 +954,3 @@ store read whatever key is subscripted.
This is coverage, not accuracy, and it is never pooled with the
benchmark-controlled Python row above. See
[the Python tool-native probe set](../../docs/python-native.md).

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"schema_version": 2,
"id": "dfb-taint-cpp-interprocedural-exception-persistence-negative",
"template_id": "dfb-template-chal-interprocedural-exception-persistence",
"polarity": "negative",
"negative_mechanism": "overwrite-kill",
"score_tier": "core",
"track": "taint",
"language": "cpp",
"semantic_dimensions": [
"interprocedural-flow",
"heap-field-sensitivity",
"flow-sensitivity",
"exceptional-flow"
],
"feature_tags": [
"interprocedural-one-hop",
"heap-access-path",
"exceptional"
],
"model_profile": "benchmark-controlled",
"fixture_files": [
"interprocedural_exception_persistence_negative.cpp"
],
"source_anchors": [
{
"marker": "DFB-SOURCE: exception-persistence-input",
"file": "interprocedural_exception_persistence_negative.cpp"
}
],
"sink_anchors": [
{
"marker": "DFB-SINK: exception-persistence-sink",
"file": "interprocedural_exception_persistence_negative.cpp"
}
],
"expected_flows": [],
"expected_nonflows": [
{
"source": "DFB-SOURCE: exception-persistence-input",
"sink": "DFB-SINK: exception-persistence-sink"
}
],
"witness_checkpoints": [],
"expected_analysis_capability": {
"kind": "exception-sensitive-interprocedural-heap-taint"
},
"execution_budget": {
"wall_clock_seconds": 60,
"peak_memory_mb": 512
},
"fixture_provenance": {
"kind": "authored",
"origin": "DataFlowBench",
"revision": "v0.8.0",
"license": "MIT"
},
"tool_model_references": {
"bifrost": {
"policy": "adapters/bifrost/policies/core-cpp-kernel.rqlp"
},
"codeql": {
"query": "adapters/codeql/cpp/queries/CppKernel.ql"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
struct FlowException {};

struct FlowBox {
int value = 0;
};

int dfb_source() { // DFB-SOURCE: exception-persistence-input
return 1;
}

void dfb_sink(int value) {} // DFB-SINK: exception-persistence-sink

[[noreturn]] void store_and_throw(FlowBox &box, int value) {
box.value = value; // DFB-WITNESS: exception-persistence-store
box.value = 0; // DFB-WITNESS: exception-persistence-kill
throw FlowException{}; // DFB-WITNESS: exception-persistence-throw
}

int recover(FlowBox &box, int value) {
try {
store_and_throw(box, value);
} catch (const FlowException &) {
return box.value; // DFB-WITNESS: exception-persistence-recovery
}
return -1;
}

void run() {
FlowBox box;
dfb_sink(recover(box, dfb_source()));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"schema_version": 2,
"id": "dfb-taint-cpp-interprocedural-exception-persistence-positive",
"template_id": "dfb-template-chal-interprocedural-exception-persistence",
"polarity": "positive",
"score_tier": "core",
"track": "taint",
"language": "cpp",
"semantic_dimensions": [
"interprocedural-flow",
"heap-field-sensitivity",
"flow-sensitivity",
"exceptional-flow"
],
"feature_tags": [
"interprocedural-one-hop",
"heap-access-path",
"exceptional"
],
"model_profile": "benchmark-controlled",
"fixture_files": [
"interprocedural_exception_persistence_positive.cpp"
],
"source_anchors": [
{
"marker": "DFB-SOURCE: exception-persistence-input",
"file": "interprocedural_exception_persistence_positive.cpp"
}
],
"sink_anchors": [
{
"marker": "DFB-SINK: exception-persistence-sink",
"file": "interprocedural_exception_persistence_positive.cpp"
}
],
"expected_flows": [
{
"source": "DFB-SOURCE: exception-persistence-input",
"sink": "DFB-SINK: exception-persistence-sink"
}
],
"expected_nonflows": [],
"witness_checkpoints": [
"DFB-SOURCE: exception-persistence-input",
"DFB-WITNESS: exception-persistence-store",
"DFB-WITNESS: exception-persistence-throw",
"DFB-WITNESS: exception-persistence-recovery",
"DFB-SINK: exception-persistence-sink"
],
"expected_analysis_capability": {
"kind": "exception-sensitive-interprocedural-heap-taint"
},
"execution_budget": {
"wall_clock_seconds": 60,
"peak_memory_mb": 512
},
"fixture_provenance": {
"kind": "authored",
"origin": "DataFlowBench",
"revision": "v0.8.0",
"license": "MIT"
},
"tool_model_references": {
"bifrost": {
"policy": "adapters/bifrost/policies/core-cpp-kernel.rqlp"
},
"codeql": {
"query": "adapters/codeql/cpp/queries/CppKernel.ql"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
struct FlowException {};

struct FlowBox {
int value = 0;
};

int dfb_source() { // DFB-SOURCE: exception-persistence-input
return 1;
}

void dfb_sink(int value) {} // DFB-SINK: exception-persistence-sink

[[noreturn]] void store_and_throw(FlowBox &box, int value) {
box.value = value; // DFB-WITNESS: exception-persistence-store
throw FlowException{}; // DFB-WITNESS: exception-persistence-throw
}

int recover(FlowBox &box, int value) {
try {
store_and_throw(box, value);
} catch (const FlowException &) {
return box.value; // DFB-WITNESS: exception-persistence-recovery
}
return -1;
}

void run() {
FlowBox box;
dfb_sink(recover(box, dfb_source()));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;

namespace DataFlowBench;

static class InterproceduralExceptionNegative
{
sealed class Box
{
public int Value;
}

sealed class FlowException : Exception
{
}

static int dfb_source() // DFB-SOURCE: interprocedural-exception-input
{
return 1;
}

static void dfb_sink(int value) { } // DFB-SINK: interprocedural-exception-sink

static void Store(Box box, int value)
{
box.Value = value; // DFB-WITNESS: interprocedural-exception-store
box.Value = 0; // DFB-KILL: interprocedural-exception-clobber
throw new FlowException(); // DFB-WITNESS: interprocedural-exception-throw
}

static int Recover(Box box, int value)
{
try
{
Store(box, value);
}
catch (FlowException) // DFB-WITNESS: interprocedural-exception-recovery
{
return box.Value;
}

return -1;
}

static void Run()
{
Box box = new Box();
dfb_sink(Recover(box, dfb_source()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"schema_version": 2,
"id": "dfb-taint-csharp-interprocedural-exception-persistence-negative",
"template_id": "dfb-template-chal-interprocedural-exception-persistence",
"polarity": "negative",
"negative_mechanism": "overwrite-kill",
"score_tier": "core",
"track": "taint",
"language": "csharp",
"semantic_dimensions": [
"interprocedural-flow",
"heap-field-sensitivity",
"flow-sensitivity",
"exceptional-flow"
],
"feature_tags": [
"interprocedural-one-hop",
"heap-access-path",
"exceptional"
],
"model_profile": "benchmark-controlled",
"fixture_files": [
"InterproceduralExceptionNegative.cs"
],
"source_anchors": [
{
"marker": "DFB-SOURCE: interprocedural-exception-input",
"file": "InterproceduralExceptionNegative.cs",
"line_hint": 16
}
],
"sink_anchors": [
{
"marker": "DFB-SINK: interprocedural-exception-sink",
"file": "InterproceduralExceptionNegative.cs",
"line_hint": 21
}
],
"expected_flows": [],
"expected_nonflows": [
{
"source": "DFB-SOURCE: interprocedural-exception-input",
"sink": "DFB-SINK: interprocedural-exception-sink"
}
],
"witness_checkpoints": [],
"expected_analysis_capability": {
"kind": "exception-sensitive-interprocedural-heap-taint"
},
"execution_budget": {
"wall_clock_seconds": 60,
"peak_memory_mb": 512
},
"fixture_provenance": {
"kind": "authored",
"origin": "DataFlowBench",
"revision": "v0.8.0-challenge-csharp",
"license": "MIT"
},
"tool_model_references": {
"bifrost": {
"policy": "adapters/bifrost/policies/core-csharp-kernel.rqlp"
},
"codeql": {
"query": "adapters/codeql/csharp/queries/CSharpKernel.ql"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;

namespace DataFlowBench;

static class InterproceduralExceptionPositive
{
sealed class Box
{
public int Value;
}

sealed class FlowException : Exception
{
}

static int dfb_source() // DFB-SOURCE: interprocedural-exception-input
{
return 1;
}

static void dfb_sink(int value) { } // DFB-SINK: interprocedural-exception-sink

static void Store(Box box, int value)
{
box.Value = value; // DFB-WITNESS: interprocedural-exception-store
throw new FlowException(); // DFB-WITNESS: interprocedural-exception-throw
}

static int Recover(Box box, int value)
{
try
{
Store(box, value);
}
catch (FlowException) // DFB-WITNESS: interprocedural-exception-recovery
{
return box.Value;
}

return -1;
}

static void Run()
{
Box box = new Box();
dfb_sink(Recover(box, dfb_source()));
}
}
Loading
Loading