partly or unimplemented features - now implemented

This commit is contained in:
master
2026-02-09 08:53:51 +02:00
parent 1bf6bbf395
commit 4bdc298ec1
674 changed files with 90194 additions and 2271 deletions

View File

@@ -35,6 +35,9 @@ public static class GoldenSetServiceCollectionExtensions
services.TryAddSingleton<ISinkRegistry, SinkRegistry>();
services.TryAddSingleton<IGoldenSetValidator, GoldenSetValidator>();
// Cross-distro coverage matrix for backport validation
services.TryAddSingleton<ICrossDistroCoverageService, CrossDistroCoverageService>();
// Memory cache (if not already registered)
services.AddMemoryCache();

View File

@@ -0,0 +1,191 @@
// -----------------------------------------------------------------------------
// CrossDistroCoverageModels.cs
// Sprint: SPRINT_20260208_027_BinaryIndex_cross_distro_golden_set_for_backport_validation
// Task: T1 — Cross-distro coverage matrix models for backport validation
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
namespace StellaOps.BinaryIndex.GoldenSet;
/// <summary>
/// Supported Linux distributions for cross-distro backport validation.
/// </summary>
public enum DistroFamily
{
/// <summary>Alpine Linux (musl libc, APK).</summary>
Alpine = 0,
/// <summary>Debian / Ubuntu (glibc, DEB).</summary>
Debian = 1,
/// <summary>RHEL / CentOS / Fedora (glibc, RPM).</summary>
Rhel = 2
}
/// <summary>
/// Backport status for a given CVE on a specific distribution version.
/// </summary>
public enum BackportStatus
{
/// <summary>Fix has not been applied (still vulnerable).</summary>
NotPatched = 0,
/// <summary>Fix has been backported to the package version.</summary>
Backported = 1,
/// <summary>The component was removed or is not applicable.</summary>
NotApplicable = 2,
/// <summary>Backport status is unknown or not yet validated.</summary>
Unknown = 3
}
/// <summary>
/// A single distro-version coverage entry in the cross-distro matrix.
/// Tracks whether a given CVE's fix has been backported to a specific distro version.
/// </summary>
public sealed record DistroCoverageEntry
{
/// <summary>Distribution family (Alpine, Debian, RHEL).</summary>
public required DistroFamily Distro { get; init; }
/// <summary>Distro release version (e.g., "3.18", "bookworm", "9").</summary>
public required string Version { get; init; }
/// <summary>Package name in the distro's packaging system.</summary>
public required string PackageName { get; init; }
/// <summary>Package version string in the distro's format.</summary>
public required string PackageVersion { get; init; }
/// <summary>Backport status for this entry.</summary>
public required BackportStatus Status { get; init; }
/// <summary>
/// Whether the golden set definition has been validated against
/// a real binary from this distro version.
/// </summary>
public bool Validated { get; init; }
/// <summary>When this entry was last validated (null if never).</summary>
public DateTimeOffset? ValidatedAt { get; init; }
/// <summary>Optional notes (e.g., patch commit hash, advisory URL).</summary>
public string? Notes { get; init; }
}
/// <summary>
/// A curated high-impact CVE entry with cross-distro coverage information.
/// Represents one row in the "golden set" of curated cross-distro test cases.
/// </summary>
public sealed record CuratedCveEntry
{
/// <summary>CVE identifier (e.g., "CVE-2014-0160").</summary>
public required string CveId { get; init; }
/// <summary>Affected component (e.g., "openssl", "sudo").</summary>
public required string Component { get; init; }
/// <summary>Human-readable vulnerability name (e.g., "Heartbleed").</summary>
public string? CommonName { get; init; }
/// <summary>CVSS score (0.0 10.0).</summary>
public double? CvssScore { get; init; }
/// <summary>CWE identifiers associated with this CVE.</summary>
public ImmutableArray<string> CweIds { get; init; } = [];
/// <summary>
/// Per-distro coverage entries showing backport status.
/// Keyed by (Distro, Version) for efficient lookup.
/// </summary>
public required ImmutableArray<DistroCoverageEntry> Coverage { get; init; }
/// <summary>
/// Reference to the golden set definition for this CVE.
/// Null if not yet linked to a validated golden set.
/// </summary>
public string? GoldenSetId { get; init; }
/// <summary>When this curated entry was created.</summary>
public required DateTimeOffset CreatedAt { get; init; }
/// <summary>When this curated entry was last updated.</summary>
public DateTimeOffset? UpdatedAt { get; init; }
/// <summary>Number of distro-version entries that have been validated.</summary>
public int ValidatedCount => Coverage.IsDefaultOrEmpty ? 0 : Coverage.Count(c => c.Validated);
/// <summary>Total number of distro-version entries.</summary>
public int TotalEntries => Coverage.IsDefaultOrEmpty ? 0 : Coverage.Length;
/// <summary>Coverage ratio [0.0, 1.0].</summary>
public double CoverageRatio => TotalEntries == 0 ? 0.0 : (double)ValidatedCount / TotalEntries;
}
/// <summary>
/// Aggregated coverage summary across all curated CVEs.
/// </summary>
public sealed record CrossDistroCoverageSummary
{
/// <summary>Total curated CVEs in the matrix.</summary>
public required int TotalCves { get; init; }
/// <summary>Total distro-version entries across all CVEs.</summary>
public required int TotalEntries { get; init; }
/// <summary>Number of validated entries.</summary>
public required int ValidatedEntries { get; init; }
/// <summary>Number of entries where the fix is backported.</summary>
public required int BackportedCount { get; init; }
/// <summary>Number of entries where the component is not patched.</summary>
public required int NotPatchedCount { get; init; }
/// <summary>Per-distro breakdown.</summary>
public required ImmutableDictionary<DistroFamily, DistroBreakdown> ByDistro { get; init; }
/// <summary>Overall validation coverage ratio [0.0, 1.0].</summary>
public double OverallCoverage => TotalEntries == 0 ? 0.0 : (double)ValidatedEntries / TotalEntries;
}
/// <summary>
/// Per-distro breakdown within the coverage summary.
/// </summary>
public sealed record DistroBreakdown
{
/// <summary>Number of entries for this distro family.</summary>
public required int EntryCount { get; init; }
/// <summary>Number of validated entries for this distro.</summary>
public required int ValidatedCount { get; init; }
/// <summary>Number of backported entries for this distro.</summary>
public required int BackportedCount { get; init; }
}
/// <summary>
/// Query parameters for filtering curated CVE entries.
/// </summary>
public sealed record CuratedCveQuery
{
/// <summary>Filter by component name (case-insensitive substring).</summary>
public string? Component { get; init; }
/// <summary>Filter by distro family.</summary>
public DistroFamily? Distro { get; init; }
/// <summary>Filter by backport status.</summary>
public BackportStatus? Status { get; init; }
/// <summary>Only return entries that haven't been validated yet.</summary>
public bool OnlyUnvalidated { get; init; }
/// <summary>Maximum results to return.</summary>
public int Limit { get; init; } = 100;
/// <summary>Offset for paging.</summary>
public int Offset { get; init; }
}

View File

@@ -0,0 +1,337 @@
// -----------------------------------------------------------------------------
// CrossDistroCoverageService.cs
// Sprint: SPRINT_20260208_027_BinaryIndex_cross_distro_golden_set_for_backport_validation
// Task: T1 — Cross-distro coverage matrix service implementation
// -----------------------------------------------------------------------------
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Diagnostics.Metrics;
namespace StellaOps.BinaryIndex.GoldenSet;
/// <summary>
/// In-memory implementation of the cross-distro coverage matrix.
/// Manages curated CVE entries with per-distro backport validation status.
/// </summary>
public sealed class CrossDistroCoverageService : ICrossDistroCoverageService
{
private readonly ConcurrentDictionary<string, CuratedCveEntry> _entries = new(StringComparer.OrdinalIgnoreCase);
private readonly TimeProvider _timeProvider;
private readonly Counter<long> _upsertCounter;
private readonly Counter<long> _queryCounter;
private readonly Counter<long> _seedCounter;
private readonly Counter<long> _validatedCounter;
/// <summary>
/// Creates a new cross-distro coverage service with OTel instrumentation.
/// </summary>
public CrossDistroCoverageService(IMeterFactory meterFactory, TimeProvider? timeProvider = null)
{
ArgumentNullException.ThrowIfNull(meterFactory);
_timeProvider = timeProvider ?? TimeProvider.System;
var meter = meterFactory.Create("StellaOps.BinaryIndex.GoldenSet.CrossDistro");
_upsertCounter = meter.CreateCounter<long>("crossdistro.upsert.total", description: "CVE entries upserted");
_queryCounter = meter.CreateCounter<long>("crossdistro.query.total", description: "Coverage queries executed");
_seedCounter = meter.CreateCounter<long>("crossdistro.seed.total", description: "Built-in entries seeded");
_validatedCounter = meter.CreateCounter<long>("crossdistro.validated.total", description: "Entries marked as validated");
}
/// <inheritdoc/>
public Task<CuratedCveEntry> UpsertAsync(CuratedCveEntry entry, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entry);
ArgumentException.ThrowIfNullOrWhiteSpace(entry.CveId);
cancellationToken.ThrowIfCancellationRequested();
var now = _timeProvider.GetUtcNow();
var updated = entry with { UpdatedAt = now };
_entries[entry.CveId] = updated;
_upsertCounter.Add(1);
return Task.FromResult(updated);
}
/// <inheritdoc/>
public Task<CuratedCveEntry?> GetByCveIdAsync(string cveId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(cveId);
_entries.TryGetValue(cveId, out var entry);
return Task.FromResult(entry);
}
/// <inheritdoc/>
public Task<ImmutableArray<CuratedCveEntry>> QueryAsync(CuratedCveQuery query, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(query);
cancellationToken.ThrowIfCancellationRequested();
_queryCounter.Add(1);
IEnumerable<CuratedCveEntry> results = _entries.Values;
if (!string.IsNullOrWhiteSpace(query.Component))
{
results = results.Where(e =>
e.Component.Contains(query.Component, StringComparison.OrdinalIgnoreCase));
}
if (query.Distro is { } distro)
{
results = results.Where(e =>
!e.Coverage.IsDefaultOrEmpty &&
e.Coverage.Any(c => c.Distro == distro));
}
if (query.Status is { } status)
{
results = results.Where(e =>
!e.Coverage.IsDefaultOrEmpty &&
e.Coverage.Any(c => c.Status == status));
}
if (query.OnlyUnvalidated)
{
results = results.Where(e =>
!e.Coverage.IsDefaultOrEmpty &&
e.Coverage.Any(c => !c.Validated));
}
var ordered = results
.OrderBy(e => e.CveId, StringComparer.OrdinalIgnoreCase)
.Skip(query.Offset)
.Take(query.Limit)
.ToImmutableArray();
return Task.FromResult(ordered);
}
/// <inheritdoc/>
public Task<CrossDistroCoverageSummary> GetSummaryAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var allEntries = _entries.Values.ToList();
var allCoverage = allEntries
.Where(e => !e.Coverage.IsDefaultOrEmpty)
.SelectMany(e => e.Coverage)
.ToList();
var byDistro = new Dictionary<DistroFamily, DistroBreakdown>();
foreach (var distro in Enum.GetValues<DistroFamily>())
{
var distroEntries = allCoverage.Where(c => c.Distro == distro).ToList();
byDistro[distro] = new DistroBreakdown
{
EntryCount = distroEntries.Count,
ValidatedCount = distroEntries.Count(c => c.Validated),
BackportedCount = distroEntries.Count(c => c.Status == BackportStatus.Backported)
};
}
var summary = new CrossDistroCoverageSummary
{
TotalCves = allEntries.Count,
TotalEntries = allCoverage.Count,
ValidatedEntries = allCoverage.Count(c => c.Validated),
BackportedCount = allCoverage.Count(c => c.Status == BackportStatus.Backported),
NotPatchedCount = allCoverage.Count(c => c.Status == BackportStatus.NotPatched),
ByDistro = byDistro.ToImmutableDictionary()
};
return Task.FromResult(summary);
}
/// <inheritdoc/>
public Task<bool> SetValidatedAsync(
string cveId,
DistroFamily distro,
string version,
bool validated,
CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(cveId);
ArgumentException.ThrowIfNullOrWhiteSpace(version);
if (!_entries.TryGetValue(cveId, out var entry))
return Task.FromResult(false);
if (entry.Coverage.IsDefaultOrEmpty)
return Task.FromResult(false);
var index = -1;
for (var i = 0; i < entry.Coverage.Length; i++)
{
var candidate = entry.Coverage[i];
if (candidate.Distro == distro &&
candidate.Version.Equals(version, StringComparison.OrdinalIgnoreCase))
{
index = i;
break;
}
}
if (index < 0)
return Task.FromResult(false);
var now = _timeProvider.GetUtcNow();
var updated = entry.Coverage[index] with
{
Validated = validated,
ValidatedAt = validated ? now : null
};
var newCoverage = entry.Coverage.SetItem(index, updated);
_entries[cveId] = entry with { Coverage = newCoverage, UpdatedAt = now };
_validatedCounter.Add(1);
return Task.FromResult(true);
}
/// <inheritdoc/>
public Task<int> SeedBuiltInEntriesAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var now = _timeProvider.GetUtcNow();
var seeded = 0;
foreach (var entry in CreateBuiltInEntries(now))
{
if (_entries.TryAdd(entry.CveId, entry))
seeded++;
}
_seedCounter.Add(seeded);
return Task.FromResult(seeded);
}
// ── Built-in curated CVEs for cross-distro backport validation ─────
internal static ImmutableArray<CuratedCveEntry> CreateBuiltInEntries(DateTimeOffset createdAt)
{
return
[
// OpenSSL Heartbleed — buffer over-read in TLS heartbeat extension
new CuratedCveEntry
{
CveId = "CVE-2014-0160",
Component = "openssl",
CommonName = "Heartbleed",
CvssScore = 7.5,
CweIds = ["CWE-126"],
GoldenSetId = "CVE-2014-0160",
CreatedAt = createdAt,
Coverage =
[
Entry(DistroFamily.Alpine, "3.9", "openssl", "1.0.2k-r0", BackportStatus.NotPatched),
Entry(DistroFamily.Alpine, "3.18", "openssl", "3.1.1-r0", BackportStatus.Backported),
Entry(DistroFamily.Debian, "wheezy", "openssl", "1.0.1e-2+deb7u7", BackportStatus.Backported),
Entry(DistroFamily.Debian, "bookworm", "openssl", "3.0.11-1~deb12u1", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "6", "openssl", "1.0.1e-16.el6_5.7", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "9", "openssl", "3.0.7-17.el9", BackportStatus.Backported),
]
},
// sudo Baron Samedit — heap-based buffer overflow in sudoers parsing
new CuratedCveEntry
{
CveId = "CVE-2021-3156",
Component = "sudo",
CommonName = "Baron Samedit",
CvssScore = 7.8,
CweIds = ["CWE-122"],
GoldenSetId = "CVE-2021-3156",
CreatedAt = createdAt,
Coverage =
[
Entry(DistroFamily.Alpine, "3.12", "sudo", "1.9.5p2-r0", BackportStatus.Backported),
Entry(DistroFamily.Alpine, "3.18", "sudo", "1.9.13p3-r0", BackportStatus.Backported),
Entry(DistroFamily.Debian, "buster", "sudo", "1.8.27-1+deb10u3", BackportStatus.Backported),
Entry(DistroFamily.Debian, "bookworm", "sudo", "1.9.13p3-1+deb12u1", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "7", "sudo", "1.8.23-10.el7_9.3", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "9", "sudo", "1.9.5p2-9.el9", BackportStatus.Backported),
]
},
// glibc — stack buffer overflow in __nss_hostname_digits_dots
new CuratedCveEntry
{
CveId = "CVE-2015-0235",
Component = "glibc",
CommonName = "GHOST",
CvssScore = 10.0,
CweIds = ["CWE-787"],
GoldenSetId = "CVE-2015-0235",
CreatedAt = createdAt,
Coverage =
[
Entry(DistroFamily.Alpine, "3.18", "musl", "1.2.4-r0", BackportStatus.NotApplicable),
Entry(DistroFamily.Debian, "wheezy", "eglibc", "2.13-38+deb7u8", BackportStatus.Backported),
Entry(DistroFamily.Debian, "bookworm", "glibc", "2.36-9+deb12u3", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "6", "glibc", "2.12-1.149.el6_6.5", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "9", "glibc", "2.34-60.el9", BackportStatus.Backported),
]
},
// curl — SOCKS5 heap-based buffer overflow
new CuratedCveEntry
{
CveId = "CVE-2023-38545",
Component = "curl",
CommonName = "SOCKS5 heap overflow",
CvssScore = 9.8,
CweIds = ["CWE-787"],
GoldenSetId = "CVE-2023-38545",
CreatedAt = createdAt,
Coverage =
[
Entry(DistroFamily.Alpine, "3.18", "curl", "8.4.0-r0", BackportStatus.Backported),
Entry(DistroFamily.Debian, "bookworm", "curl", "7.88.1-10+deb12u4", BackportStatus.Backported),
Entry(DistroFamily.Debian, "bullseye", "curl", "7.74.0-1.3+deb11u10", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "8", "curl", "7.61.1-30.el8_8.4", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "9", "curl", "8.0.1-1.el9", BackportStatus.Backported),
]
},
// OpenSSH — regreSSHion (signal handler race condition)
new CuratedCveEntry
{
CveId = "CVE-2024-6387",
Component = "openssh",
CommonName = "regreSSHion",
CvssScore = 8.1,
CweIds = ["CWE-362"],
GoldenSetId = "CVE-2024-6387",
CreatedAt = createdAt,
Coverage =
[
Entry(DistroFamily.Alpine, "3.18", "openssh", "9.3_p2-r0", BackportStatus.Backported),
Entry(DistroFamily.Alpine, "3.20", "openssh", "9.7_p1-r4", BackportStatus.Backported),
Entry(DistroFamily.Debian, "bookworm", "openssh", "1:9.2p1-2+deb12u3", BackportStatus.Backported),
Entry(DistroFamily.Rhel, "8", "openssh", "8.0p1-19.el8_8", BackportStatus.NotPatched),
Entry(DistroFamily.Rhel, "9", "openssh", "8.7p1-38.el9_4.1", BackportStatus.Backported),
]
},
];
}
private static DistroCoverageEntry Entry(
DistroFamily distro,
string version,
string package,
string packageVersion,
BackportStatus status) => new()
{
Distro = distro,
Version = version,
PackageName = package,
PackageVersion = packageVersion,
Status = status
};
}

View File

@@ -0,0 +1,52 @@
// -----------------------------------------------------------------------------
// ICrossDistroCoverageService.cs
// Sprint: SPRINT_20260208_027_BinaryIndex_cross_distro_golden_set_for_backport_validation
// Task: T1 — Interface for cross-distro coverage matrix management
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
namespace StellaOps.BinaryIndex.GoldenSet;
/// <summary>
/// Manages the cross-distro coverage matrix for curated CVEs,
/// enabling backport validation across Alpine, Debian, and RHEL.
/// </summary>
public interface ICrossDistroCoverageService
{
/// <summary>
/// Adds or updates a curated CVE entry with its cross-distro coverage data.
/// </summary>
Task<CuratedCveEntry> UpsertAsync(CuratedCveEntry entry, CancellationToken cancellationToken = default);
/// <summary>
/// Gets a curated CVE entry by its CVE ID.
/// </summary>
Task<CuratedCveEntry?> GetByCveIdAsync(string cveId, CancellationToken cancellationToken = default);
/// <summary>
/// Queries curated CVE entries with filtering.
/// </summary>
Task<ImmutableArray<CuratedCveEntry>> QueryAsync(CuratedCveQuery query, CancellationToken cancellationToken = default);
/// <summary>
/// Computes a summary of cross-distro coverage across all curated CVEs.
/// </summary>
Task<CrossDistroCoverageSummary> GetSummaryAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Marks a specific distro coverage entry as validated (or not).
/// </summary>
Task<bool> SetValidatedAsync(
string cveId,
DistroFamily distro,
string version,
bool validated,
CancellationToken cancellationToken = default);
/// <summary>
/// Seeds the coverage matrix with built-in high-impact CVE entries.
/// Idempotent: only adds entries that don't already exist.
/// </summary>
Task<int> SeedBuiltInEntriesAsync(CancellationToken cancellationToken = default);
}