From 7a1fab2f53cfba2b84d3578a5628f11d3ab3f99a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 11 Sep 2026 13:42:22 +0000 Subject: [PATCH 1/2] Document that unpinned libc6 means a snap rebuild picks up USN-8737-2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Snap Store scan flagged staged libc6 against USN-8737-2 (noble 2.39-0ubuntu8.9). snapcraft.yaml does not pin libc6 or freeze apt sources, so no recipe change is required — rebuilding pulls the patched archive package. Comment and tests lock that contract in. Co-authored-by: Dominic Letz --- snap/snapcraft.yaml | 2 ++ test/snap/snapcraft_test.exs | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 test/snap/snapcraft_test.exs diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 339e4b8..6b9c4f2 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -56,6 +56,8 @@ parts: # WireGuardNat (MASQUERADE/FORWARD) calls iptables + `ip route`; firewall-control plug required at runtime. - iptables - iproute2 + # Unpinned: Snapcraft stages the Ubuntu archive libc used at build time. + # Rebuilds pick up USNs (e.g. USN-8737-2 / libc6 2.39-0ubuntu8.9); do not pin. - libc6 - libncurses6 - libsigsegv2 diff --git a/test/snap/snapcraft_test.exs b/test/snap/snapcraft_test.exs new file mode 100644 index 0000000..46c8e58 --- /dev/null +++ b/test/snap/snapcraft_test.exs @@ -0,0 +1,58 @@ +# Diode Server +# Copyright 2021-2024 Diode +# Licensed under the Diode License, Version 1.1 + +# Snap Store USN scans (e.g. USN-8737-2) are resolved by rebuilding when +# libc6 is staged from the Ubuntu archive without a version pin. +defmodule Snap.SnapcraftTest do + use ExUnit.Case, async: true + + @snapcraft Path.expand("../../snap/snapcraft.yaml", __DIR__) + + setup_all do + {:ok, yaml: File.read!(@snapcraft)} + end + + test "uses core24 so staged debs come from Ubuntu 24.04 (noble)", %{yaml: yaml} do + assert yaml =~ ~r/^base:\s*core24\s*$/m + end + + test "does not pin apt sources that would freeze libc6 away from USNs", %{yaml: yaml} do + refute yaml =~ ~r/^package-repositories:/m + end + + test "libc6 is listed unpinned in build-packages and stage-packages", %{yaml: yaml} do + for section <- ["build-packages", "stage-packages"] do + packages = listed_packages(yaml, section) + libc6 = Enum.filter(packages, &String.starts_with?(&1, "libc6")) + + assert libc6 == ["libc6"], + "#{section} must list unpinned libc6 so a snap rebuild pulls archive security updates (USN-8737-2); got: #{inspect(libc6)}" + end + end + + defp listed_packages(yaml, section) do + lines = String.split(yaml, "\n") + + start = + Enum.find_index(lines, fn line -> + String.match?(line, ~r/^\s{2,4}#{Regex.escape(section)}:\s*$/) + end) + + assert is_integer(start), "missing #{section} in snap/snapcraft.yaml" + + lines + |> Enum.drop(start + 1) + |> Enum.take_while(&list_continuation?/1) + |> Enum.flat_map(fn line -> + case Regex.run(~r/^\s+-\s+(\S+)\s*$/, line) do + [_, pkg] -> [pkg] + _ -> [] + end + end) + end + + defp list_continuation?(line) do + String.match?(line, ~r/^\s*(?:#|$|- )/) + end +end From 04f1bbd7d7ad4d7d230d5e0cebba73aa2e0b1e09 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 11 Sep 2026 13:43:55 +0000 Subject: [PATCH 2/2] ci: run snapcraft recipe tests without anvil Keep the libc6 USN rebuild contract covered on every PR. Co-authored-by: Dominic Letz --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e15a651..c048c1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,3 +71,5 @@ jobs: # Wiring all of that up is tracked separately. mix test.turn mix test.nat + # Snapcraft recipe contract (unpinned libc6 / USN rebuilds); no anvil. + DIODE_MINIMAL_TEST=1 mix test --no-start test/snap/snapcraft_test.exs