package unit; import java.util.*; /** * CiliumTest — CWE-407 benchmark for cilium-0001 * * cilium-0001: Requirement.hasValue() slices.Contains(r.strValues, value) * called per identity in selectorcache selections() loop → O(I × R × V) * * Model: * I = number of security identities in the cache * R = number of requirements in the selector * V = number of values per requirement (e.g. In [ns1, ns2, ..., nsV]) * * SLOW: for each identity, for each requirement, slices.Contains(strValues) → O(I × R × V) * FAST: strValues as map[string]struct{}, O(1) lookup → O(I × R) */ public class CiliumTest { // ------------------------------------------------------------------------- // Data model // ------------------------------------------------------------------------- static class Identity { final Map labels; Identity(String key, String value) { this.labels = new HashMap<>(); this.labels.put(key, value); } } static class RequirementSlow { final String key; final List strValues; // ← slice, O(n) membership RequirementSlow(String key, List values) { this.key = key; this.strValues = values; } boolean matches(Identity id) { String val = id.labels.get(key); if (val == null) return false; // hasValue: slices.Contains — O(V) scan return strValues.contains(val); } } static class RequirementFast { final String key; final Set strValues; // ← map, O(1) membership RequirementFast(String key, List values) { this.key = key; this.strValues = new HashSet<>(values); } boolean matches(Identity id) { String val = id.labels.get(key); if (val == null) return false; // hasValue: map.contains — O(1) return strValues.contains(val); } } // ------------------------------------------------------------------------- // SLOW: selector cache selections() using slice-based requirements // ------------------------------------------------------------------------- static long selectIdentities_slow(List identities, List requirements) { long ops = 0; for (Identity id : identities) { boolean allMatch = true; for (RequirementSlow req : requirements) { String val = id.labels.get(req.key); if (val == null) { allMatch = false; break; } // slices.Contains simulation: scan strValues boolean found = false; for (String sv : req.strValues) { ops++; if (sv.equals(val)) { found = true; break; } } if (!found) { allMatch = false; break; } } } return ops; } // ------------------------------------------------------------------------- // FAST: selector cache selections() using map-based requirements // ------------------------------------------------------------------------- static long selectIdentities_fast(List identities, List requirements) { long ops = 0; for (Identity id : identities) { for (RequirementFast req : requirements) { String val = id.labels.get(req.key); if (val == null) break; ops++; // O(1) map lookup req.strValues.contains(val); } } return ops; } // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- static List makeValues(int count, String prefix) { List vals = new ArrayList<>(count); for (int i = 0; i < count; i++) vals.add(prefix + i); return vals; } static List makeIdentities(int count, String key, int valueRange) { List ids = new ArrayList<>(count); for (int i = 0; i < count; i++) { ids.add(new Identity(key, "ns" + (i % valueRange))); } return ids; } static void bench(String label, long sOps, long fOps) { System.out.printf(" %-55s slow=%9d fast=%7d ratio=%5.1fx%n", label, sOps, fOps, (double) sOps / Math.max(fOps, 1)); } // ------------------------------------------------------------------------- // Main // ------------------------------------------------------------------------- public static void main(String[] args) { System.out.println("CiliumTest — CWE-407 cilium-0001 Requirement.hasValue linear scan"); System.out.println(); // --- I=1000, R=2, V=20 --- { int I = 1000, V = 20; String key = "k8s:io.kubernetes.pod.namespace"; List values = makeValues(V, "ns"); List ids = makeIdentities(I, key, V); List slowReqs = List.of(new RequirementSlow(key, values)); List fastReqs = List.of(new RequirementFast(key, values)); long sOps = selectIdentities_slow(ids, slowReqs); long fOps = selectIdentities_fast(ids, fastReqs); bench("I=1000 R=1 V=20", sOps, fOps); assert sOps > fOps * 5 : "Expected slow >> fast, got slow=" + sOps + " fast=" + fOps; } // --- I=5000, R=2, V=50 --- { int I = 5000, V = 50; String key = "k8s:io.kubernetes.pod.namespace"; List values = makeValues(V, "ns"); List ids = makeIdentities(I, key, V); List slowReqs = List.of(new RequirementSlow(key, values)); List fastReqs = List.of(new RequirementFast(key, values)); long sOps = selectIdentities_slow(ids, slowReqs); long fOps = selectIdentities_fast(ids, fastReqs); bench("I=5000 R=1 V=50", sOps, fOps); assert sOps > fOps * 10 : "Expected slow >> fast, got slow=" + sOps + " fast=" + fOps; } // --- I=10000, R=3, V=50 (large cluster) --- { int I = 10000, V = 50; String key = "k8s:io.kubernetes.pod.namespace"; List values = makeValues(V, "ns"); List ids = makeIdentities(I, key, V); List slowReqs = new ArrayList<>(); List fastReqs = new ArrayList<>(); for (int r = 0; r < 3; r++) { slowReqs.add(new RequirementSlow(key, values)); fastReqs.add(new RequirementFast(key, values)); } long sOps = selectIdentities_slow(ids, slowReqs); long fOps = selectIdentities_fast(ids, fastReqs); bench("I=10000 R=3 V=50 (large cluster)", sOps, fOps); assert sOps > fOps * 20 : "Expected slow >> fast, got slow=" + sOps + " fast=" + fOps; } // --- I=10000, R=1, V=200 (wide In selector — worst case) --- { int I = 10000, V = 200; String key = "k8s:io.kubernetes.pod.namespace"; List values = makeValues(V, "ns"); List ids = makeIdentities(I, key, V); List slowReqs = List.of(new RequirementSlow(key, values)); List fastReqs = List.of(new RequirementFast(key, values)); long sOps = selectIdentities_slow(ids, slowReqs); long fOps = selectIdentities_fast(ids, fastReqs); bench("I=10000 R=1 V=200 (wide In — worst case)", sOps, fOps); assert sOps > fOps * 50 : "Expected slow >> fast, got slow=" + sOps + " fast=" + fOps; } System.out.println(); System.out.println("All assertions passed."); } }