feat: Implement BerkeleyDB reader for RPM databases
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
console-runner-image / build-runner-image (push) Has been cancelled
wine-csp-build / Build Wine CSP Image (push) Has been cancelled
wine-csp-build / Integration Tests (push) Has been cancelled
wine-csp-build / Security Scan (push) Has been cancelled
wine-csp-build / Generate SBOM (push) Has been cancelled
wine-csp-build / Publish Image (push) Has been cancelled
wine-csp-build / Air-Gap Bundle (push) Has been cancelled
wine-csp-build / Test Summary (push) Has been cancelled

- Added BerkeleyDbReader class to read and extract RPM header blobs from BerkeleyDB hash databases.
- Implemented methods to detect BerkeleyDB format and extract values, including handling of page sizes and magic numbers.
- Added tests for BerkeleyDbReader to ensure correct functionality and header extraction.

feat: Add Yarn PnP data tests

- Created YarnPnpDataTests to validate package resolution and data loading from Yarn PnP cache.
- Implemented tests for resolved keys, package presence, and loading from cache structure.

test: Add egg-info package fixtures for Python tests

- Created egg-info package fixtures for testing Python analyzers.
- Included PKG-INFO, entry_points.txt, and installed-files.txt for comprehensive coverage.

test: Enhance RPM database reader tests

- Added tests for RpmDatabaseReader to validate fallback to legacy packages when SQLite is missing.
- Implemented helper methods to create legacy package files and RPM headers for testing.

test: Implement dual signing tests

- Added DualSignTests to validate secondary signature addition when configured.
- Created stub implementations for crypto providers and key resolvers to facilitate testing.

chore: Update CI script for Playwright Chromium installation

- Modified ci-console-exports.sh to ensure deterministic Chromium binary installation for console exports tests.
- Added checks for Windows compatibility and environment variable setups for Playwright browsers.
This commit is contained in:
StellaOps Bot
2025-12-07 16:24:45 +02:00
parent e3f28a21ab
commit 11597679ed
199 changed files with 9809 additions and 4404 deletions

View File

@@ -45,6 +45,93 @@ public class BinaryReachabilityLifterTests
Assert.Equal(expectedCodeId, richNode.CodeId);
}
[Fact]
public async Task EmitsEntryPointForElfWithNonZeroEntryAddress()
{
using var temp = new TempDir();
var binaryPath = System.IO.Path.Combine(temp.Path, "sample.so");
var bytes = CreateElfWithEntryPoint(0x401000);
await System.IO.File.WriteAllBytesAsync(binaryPath, bytes);
var context = new ReachabilityLifterContext
{
RootPath = temp.Path,
AnalysisId = "analysis-entry"
};
var builder = new ReachabilityGraphBuilder();
var lifter = new BinaryReachabilityLifter();
await lifter.LiftAsync(context, builder, CancellationToken.None);
var graph = builder.ToUnionGraph(SymbolId.Lang.Binary);
// Should have binary node + entry point node
Assert.Equal(2, graph.Nodes.Count);
var entryNode = graph.Nodes.FirstOrDefault(n =>
n.Kind == "entry_point" &&
n.Attributes?.ContainsKey("is_synthetic_root") == true);
Assert.NotNull(entryNode);
Assert.Equal("_start", entryNode!.Display);
// Should have edge from entry point to binary
var entryEdge = graph.Edges.FirstOrDefault(e =>
e.EdgeType == EdgeTypes.Call &&
e.To == graph.Nodes.First(n => n.Kind == "binary").SymbolId);
Assert.NotNull(entryEdge);
}
[Fact]
public async Task EmitsPurlForLibrary()
{
using var temp = new TempDir();
var binaryPath = System.IO.Path.Combine(temp.Path, "libssl.so.3");
var bytes = CreateMinimalElf();
await System.IO.File.WriteAllBytesAsync(binaryPath, bytes);
var context = new ReachabilityLifterContext
{
RootPath = temp.Path,
AnalysisId = "analysis-purl"
};
var builder = new ReachabilityGraphBuilder();
var lifter = new BinaryReachabilityLifter();
await lifter.LiftAsync(context, builder, CancellationToken.None);
var graph = builder.ToUnionGraph(SymbolId.Lang.Binary);
var node = Assert.Single(graph.Nodes);
Assert.NotNull(node.Attributes);
Assert.True(node.Attributes!.ContainsKey("purl"));
Assert.Equal("pkg:generic/libssl@3", node.Attributes["purl"]);
}
[Fact]
public async Task DoesNotEmitEntryPointForElfWithZeroEntry()
{
using var temp = new TempDir();
var binaryPath = System.IO.Path.Combine(temp.Path, "noop.so");
var bytes = CreateMinimalElf(); // Entry is 0x0
await System.IO.File.WriteAllBytesAsync(binaryPath, bytes);
var context = new ReachabilityLifterContext
{
RootPath = temp.Path,
AnalysisId = "analysis-noentry"
};
var builder = new ReachabilityGraphBuilder();
var lifter = new BinaryReachabilityLifter();
await lifter.LiftAsync(context, builder, CancellationToken.None);
var graph = builder.ToUnionGraph(SymbolId.Lang.Binary);
// Should only have the binary node, no entry point
Assert.Single(graph.Nodes);
Assert.DoesNotContain(graph.Nodes, n => n.Kind == "entry_point");
}
private static byte[] CreateMinimalElf()
{
var data = new byte[64];
@@ -57,6 +144,25 @@ public class BinaryReachabilityLifterTests
data[7] = 0; // System V ABI
data[18] = 0x3E; // EM_X86_64
data[19] = 0x00;
// Entry point at offset 24 is 0 (default)
return data;
}
private static byte[] CreateElfWithEntryPoint(ulong entryAddr)
{
var data = new byte[64];
data[0] = 0x7F;
data[1] = (byte)'E';
data[2] = (byte)'L';
data[3] = (byte)'F';
data[4] = 2; // 64-bit
data[5] = 1; // little endian
data[7] = 0; // System V ABI
data[18] = 0x3E; // EM_X86_64
data[19] = 0x00;
// Set e_entry at offset 24 (little endian 64-bit)
BitConverter.TryWriteBytes(data.AsSpan(24, 8), entryAddr);
return data;
}
}