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

@@ -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);
}