Compare commits

..
Author SHA1 Message Date
Stéphane Lesimple dcaed638f1 chore: release workflow: use a PR to sync source-build to master 2026-07-30 16:37:00 +02:00
github-actions[bot] 8f3f295a14 release: sync v26.36.0730501 from source-build
built from source-build commit ed7f348f83
 dated 2026-07-30 12:04:02 +0000
2026-07-30 12:35:24 +00:00
Stéphane Lesimple 85e5daad8f fix: release.yml: yaml syntax 2026-07-30 14:31:04 +02:00
Stéphane Lesimple a441987adb ci: add manual path-scoped release workflow (master-only)
Add .github/workflows/release.yml, triggered manually via workflow_dispatch,
with two independent actions:

  - sync-from-source-build: copy every top-level file from source-build
    except .github/ onto master as a single commit
  - draft-github-release: create a draft GitHub release from master's current
    script, with an auto-drafted changelog assembled from source-build.

This replaces merging source-build into master that caused modify/delete
conflict of the master-only workflows.
2026-07-30 14:09:32 +02:00
Stéphane Lesimple c1aee44717 chore: udpate stale github workflow 2026-06-06 19:00:05 +02:00
Stéphane Lesimple 4031b0f3bd chore: bump gh actions modules 2026-06-06 15:06:31 +02:00
Stéphane Lesimple d6624c30af v26.36.0602723 (#577)
* fix: arm64: collapse per-core CPU info lists to a single line (#576)

 built from commit 7d9345a32f
 dated 2026-06-02 17:21:31 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)

 Store the per-core implementer/part/arch/variant/revision lists
space-separated (no embedded newlines, which also cleans up JSON and
prometheus output) and dedup them for the human-readable display, so
homogeneous systems show e.g. "0x41" instead of repeating it per core.
2026-06-02 18:05:47 +00:00
Stéphane Lesimpleandfoo 26cf31b282 Merge source-build for v26.36.0601873 (#575)
* chore: add stalebot in dryrun

 built from commit afadf53f7f
 dated 2026-04-02 13:13:19 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

* Merge branch 'test' into source

 built from commit 952fe6a87f
 dated 2026-04-02 18:40:05 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

* Merge pull request #530 from speed47/test

 built from commit d3c0f1a24d
 dated 2026-04-02 16:49:41 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)

 chore: workflows revamp

* Merge pull request #532 from speed47/test

 built from commit 6fac2d8ff1
 dated 2026-04-02 21:32:39 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)

 Retbleed / Downfall overhald / doc updates

* enh: add known fixed ucode versions for CVE-2023-23583 (Reptar) and CVE-2024-45332 (BPI)

 built from commit cccb3c0081
 dated 2026-04-04 17:50:04 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

* fix: add rebleet to --variant

 built from commit 7a7408d124
 dated 2026-04-04 18:17:35 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)

* Merge pull request #566 from speed47/test

 built from commit 3e2b6cc734
 dated 2026-04-20 11:02:38 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)

 Prepare release v26.33.0420xxx

* Merge pull request #571 from speed47/test

 built from commit 0045d237fa
 dated 2026-06-01 20:44:44 +0000
 by Stéphane Lesimple (speed47_github@speed47.net)

 Prepare next release

* update: fwdb from v349+i20260227+615b to v349+i20260512+1cce, 19 microcode changes

 built from commit 645a79846b
 dated 2026-06-01 20:56:45 +0000
 by github-actions[bot] (41898282+github-actions[bot]@users.noreply.github.com)

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-02 16:57:51 +00:00
Stéphane Lesimple 3f4801e6a7 autoupdate workflow: add missing pkg 2026-06-01 20:55:08 +00:00
Stéphane Lesimple 9a3688b6fd chore: use scripts in autoupdate workflow (#572) 2026-06-01 20:52:54 +00:00
Stéphane Lesimple 0c89d162a3 chore: fix autoupdate workflow 2026-05-31 14:50:31 +02:00
9 changed files with 1005 additions and 153 deletions
+7 -5
View File
@@ -13,18 +13,20 @@ jobs:
autoupdate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
ref: source
- name: Install prerequisites
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends iucode-tool sqlite3 unzip
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends iucode-tool sqlite3 unzip shfmt
- name: Update microcode versions
run: ./spectre-meltdown-checker.sh --update-builtin-fwdb
run: ./scripts/update_mcedb.sh
- name: Update Intel models
run: ./scripts/update_intel_models.sh
- name: Check git diff
id: diff
run: |
echo change="$(git diff spectre-meltdown-checker.sh | awk '/MCEDB/ { if(V) { print V" to "$4; exit } else { V=$4 } }')" >> "$GITHUB_OUTPUT"
echo nbdiff="$(git diff spectre-meltdown-checker.sh | grep -cE -- '^\+# [AI],')" >> "$GITHUB_OUTPUT"
echo change="$(git diff | awk '/MCEDB/ { if(V) { print V" to "$4; exit } else { V=$4 } }')" >> "$GITHUB_OUTPUT"
echo nbdiff="$(git diff | grep -cE -- '^\+# [AI],')" >> "$GITHUB_OUTPUT"
git diff
cat "$GITHUB_OUTPUT"
- name: Create Pull Request if needed
+75 -4
View File
@@ -25,21 +25,81 @@ jobs:
mv spectre-meltdown-checker.sh dist/
- name: check direct execution
run: |
set -x
expected=$(cat .github/workflows/expected_cve_count)
cd dist
nb=$(sudo ./spectre-meltdown-checker.sh --batch json | jq '.[]|.CVE' | wc -l)
json=$(sudo ./spectre-meltdown-checker.sh --batch json || true)
# Validate JSON is well-formed (and show it if not)
echo "$json" | jq . >/dev/null || {
echo "Invalid JSON produced by spectre-meltdown-checker.sh"
echo "$json"
exit 1
}
# Validate required keys exist
for key in meta system cpu cpu_microcode vulnerabilities; do
echo "$json" | jq -e ".$key" >/dev/null || {
echo "Missing top-level key: $key"
echo "$json" | jq .
exit 1
}
done
# Use -r to get raw scalars (no quotes)
fmtver=$(echo "$json" | jq -r '.meta.format_version // empty')
if [ "$fmtver" != "1" ]; then
echo "Unexpected format_version: $fmtver"
echo "$json" | jq .
exit 1
fi
run_as_root=$(echo "$json" | jq -r '.meta.run_as_root // empty')
if [ "$run_as_root" != "true" ]; then
echo "Expected run_as_root=true, got: $run_as_root"
echo "$json" | jq .
exit 1
fi
mocked=$(echo "$json" | jq -r '.meta.mocked // "false"')
if [ "$mocked" = "true" ]; then
echo "mocked=true must never appear in production"
echo "$json" | jq .
exit 1
fi
# Count CVEs robustly (as a number)
nb=$(echo "$json" | jq -r '[.vulnerabilities[].cve] | length')
if [ "$nb" -ne "$expected" ]; then
echo "Invalid number of CVEs reported: $nb instead of $expected"
echo "$json" | jq '.vulnerabilities[].cve'
exit 1
else
echo "OK $nb CVEs reported"
fi
# Validate json-terse backward compatibility
nb_terse=$(sudo ./spectre-meltdown-checker.sh --batch json-terse | jq -r 'map(.CVE) | length')
if [ "$nb_terse" -ne "$expected" ]; then
echo "json-terse backward compat broken: $nb_terse CVEs instead of $expected"
exit 1
else
echo "OK json-terse backward compat: $nb_terse CVEs"
fi
- name: check docker compose run execution
run: |
expected=$(cat .github/workflows/expected_cve_count)
cd dist
docker compose build
nb=$(docker compose run --rm spectre-meltdown-checker --batch json | jq '.[]|.CVE' | wc -l)
json=$(docker compose run --rm spectre-meltdown-checker --batch json || true)
echo "$json" | jq . > /dev/null
fmtver=$(echo "$json" | jq '.meta.format_version')
if [ "$fmtver" != "1" ]; then
echo "Unexpected format_version: $fmtver"
exit 1
fi
nb=$(echo "$json" | jq '.vulnerabilities[].cve' | wc -l)
if [ "$nb" -ne "$expected" ]; then
echo "Invalid number of CVEs reported: $nb instead of $expected"
exit 1
@@ -51,7 +111,14 @@ jobs:
expected=$(cat .github/workflows/expected_cve_count)
cd dist
docker build -t spectre-meltdown-checker .
nb=$(docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/modules:/lib/modules:ro spectre-meltdown-checker --batch json | jq '.[]|.CVE' | wc -l)
json=$(docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/modules:/lib/modules:ro spectre-meltdown-checker --batch json || true)
echo "$json" | jq . > /dev/null
fmtver=$(echo "$json" | jq '.meta.format_version')
if [ "$fmtver" != "1" ]; then
echo "Unexpected format_version: $fmtver"
exit 1
fi
nb=$(echo "$json" | jq '.vulnerabilities[].cve' | wc -l)
if [ "$nb" -ne "$expected" ]; then
echo "Invalid number of CVEs reported: $nb instead of $expected"
exit 1
@@ -92,15 +159,19 @@ jobs:
fi
- name: create a pull request to ${{ github.ref_name }}-build
run: |
# all the files in dist/* and .github/* must be moved as is to the -build branch root, move them out for now:
tmpdir=$(mktemp -d)
mv ./dist/* .github $tmpdir/
rm -rf ./dist
git fetch origin ${{ github.ref_name }}-build
git checkout -f ${{ github.ref_name }}-build
rm -rf doc/
mv $tmpdir/* .
rm -rf src/
rm -rf src/ scripts/ img/
mkdir -p .github
rsync -vaP --delete $tmpdir/.github/ .github/
git add --all
echo =#=#= DIFF CACHED
git diff --cached
+1 -1
View File
@@ -1 +1 @@
26
32
+181
View File
@@ -0,0 +1,181 @@
name: release
# Manual, path-scoped release helper for master.
#
# `master` is BOTH the distribution branch (users download the script here)
# AND the default branch that hosts the scheduled CI workflows
# (autoupdate / stale / vuln-watch). `source-build` is a build-OUTPUT branch.
#
# We therefore never merge source-build into master: that would drag source-build's
# whole tree, including the *absence* of the master-only workflows.
# Instead we copy only the assembled artifact files across, and cut GitHub
# releases from master directly.
#
# Two independent manual actions to run against the `master` branch:
#
# 1. sync-from-source-build : open a PR against master carrying the assembled
# files (everything on source-build EXCEPT
# .github/). Nothing lands on master until the PR
# is reviewed and merged.
# 2. draft-github-release : create a DRAFT GitHub release from the script
# currently on master, with an auto-drafted
# changelog.
on:
workflow_dispatch:
inputs:
action:
description: What to do
type: choice
required: true
default: sync-from-source-build
options:
- sync-from-source-build
- draft-github-release
permissions:
contents: write
pull-requests: write
concurrency:
group: release-master
cancel-in-progress: false
jobs:
# ---------------------------------------------------------------------------
# 1. Copy assembled files from source-build onto master (no .github/),
# as a pull request.
# ---------------------------------------------------------------------------
sync-from-source-build:
if: inputs.action == 'sync-from-source-build'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: master
fetch-depth: 0
persist-credentials: true
- name: sync assembled files from source-build
id: sync
run: |
set -eu
git fetch --no-tags origin source-build
# Every top-level entry on source-build EXCEPT .github/ (master keeps
# its own CI). Computed dynamically so any new top-level artifact is
# picked up automatically.
readarray -t paths < <(git ls-tree --name-only origin/source-build | grep -vxF '.github')
echo "Syncing: ${paths[*]}"
# Mirror source-build exactly for those paths, removing first so that
# deletions/renames inside doc/ etc. propagate too.
for p in "${paths[@]}"; do rm -rf -- "$p"; done
git checkout origin/source-build -- "${paths[@]}"
git add --all -- "${paths[@]}"
if git diff --cached --quiet; then
echo "master already up to date with source-build; nothing to sync."
echo "changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
{
echo "changed=true"
echo "version=$(grep -m1 "^VERSION=" spectre-meltdown-checker.sh | cut -d"'" -f2)"
echo "sb=$(git rev-parse origin/source-build)"
echo "sbdate=$(git log -1 --format=%ai origin/source-build)"
} >> "$GITHUB_OUTPUT"
# Note: the repo must have "Allow GitHub Actions to create and approve
# pull requests" enabled for this to work.
- name: open the sync pull request
if: steps.sync.outputs.changed == 'true'
uses: peter-evans/create-pull-request@v7
with:
base: master
branch: release/sync-from-source-build
delete-branch: true
committer: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
title: "release: sync v${{ steps.sync.outputs.version }} from source-build"
commit-message: |
release: sync v${{ steps.sync.outputs.version }} from source-build
built from source-build commit ${{ steps.sync.outputs.sb }}
dated ${{ steps.sync.outputs.sbdate }}
body: |
Assembled files copied from `source-build` onto `master` (everything
except `.github/`, which stays master-only).
- version: `${{ steps.sync.outputs.version }}`
- built from source-build commit: ${{ steps.sync.outputs.sb }}
- dated: ${{ steps.sync.outputs.sbdate }}
Once merged, run this workflow again with the `draft-github-release`
action to cut the release, if required.
# ---------------------------------------------------------------------------
# 2. Draft a GitHub release from the script currently on master.
# ---------------------------------------------------------------------------
draft-github-release:
if: inputs.action == 'draft-github-release'
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v6
with:
ref: master
fetch-depth: 0
persist-credentials: true
- name: draft a release from the current master script
run: |
set -eu
ver=$(grep -m1 "^VERSION=" spectre-meltdown-checker.sh | cut -d"'" -f2)
tag="v${ver}"
if gh release view "$tag" >/dev/null 2>&1; then
echo "A release for $tag already exists; refusing to recreate." >&2
echo "Delete it first if needed." >&2
exit 1
fi
# Draft the changelog from the source-build commits assembled since the
# previous published release. We locate the source-build commit whose
# built VERSION equals the last release tag, then list what came after.
git fetch --no-tags origin source-build
last_tag=$(gh release list --exclude-drafts --limit 1 --json tagName --jq '.[0].tagName // empty')
old_ver="${last_tag#v}"
base=""
if [ -n "$old_ver" ]; then
while read -r h; do
v=$(git show "$h:spectre-meltdown-checker.sh" 2>/dev/null | grep -m1 "^VERSION=" | cut -d"'" -f2 || true)
if [ "$v" = "$old_ver" ]; then base="$h"; break; fi
done < <(git rev-list --max-count=500 origin/source-build)
fi
{
echo "## ${tag}"
echo
if [ -n "$base" ]; then
git log --no-merges --format='- %s' "${base}..origin/source-build"
else
echo "_Could not determine the previous release point automatically — please fill in the changelog. Last 30 assembled commits below as a starting point:_"
echo
git log --no-merges --format='- %s' --max-count=30 origin/source-build
fi
} > notes.md
echo "----- draft notes -----"; cat notes.md; echo "-----------------------"
gh release create "$tag" \
--draft \
--target "$GITHUB_SHA" \
--title "$tag" \
--notes-file notes.md \
spectre-meltdown-checker.sh
echo "Draft release $tag created."
+4 -1
View File
@@ -8,7 +8,7 @@ on:
action:
description: "dry-run"
required: true
default: "dryrun"
default: "apply"
type: choice
options:
- dryrun
@@ -30,4 +30,7 @@ jobs:
days-before-close: 7
stale-issue-label: stale
remove-stale-when-updated: true
close-issue-reason: completed
stale-issue-message: "If there are no further comments or activity on this issue, it'll be closed automatically in 7 days."
close-issue-message: "Automatically closing this issue due to inactivity, don't hesitate to open a new issue if needed."
debug-only: ${{ case(inputs.action == 'dryrun', true, false) }}
+7 -7
View File
@@ -45,14 +45,14 @@ jobs:
# workflow file itself MUST stay on the default branch, as GitHub only
# honors `schedule:` triggers on the default branch.
- name: Checkout vuln-watch branch (scripts + prompt)
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
ref: vuln-watch
fetch-depth: 1
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
@@ -84,7 +84,7 @@ jobs:
- name: Download previous state artifact
if: steps.prev.outputs.run_id != ''
uses: actions/download-artifact@v5
uses: actions/download-artifact@v8
continue-on-error: true # tolerate retention expiry
with:
name: vuln-watch-state
@@ -115,7 +115,7 @@ jobs:
# implemented?". Only fetched on days with something to classify.
- name: Checkout checker code (test branch) for coverage grep
if: steps.diff.outputs.new_count != '0' || steps.diff.outputs.reconsider_count != '0'
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
ref: test
path: checker
@@ -150,7 +150,7 @@ jobs:
- name: Upload Claude execution log
if: ${{ always() && steps.classify.outputs.execution_file != '' }}
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: claude-execution-log-${{ github.run_id }}
path: ${{ steps.classify.outputs.execution_file }}
@@ -168,7 +168,7 @@ jobs:
- name: Upload new state artifact
if: always()
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: vuln-watch-state
path: state/seen.json
@@ -177,7 +177,7 @@ jobs:
- name: Upload daily report
if: always()
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: vuln-watch-report-${{ github.run_id }}
path: |
+8
View File
@@ -40,6 +40,14 @@ CVE | Name | Aliases
[CVE-2024-45332](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-45332) | Branch Privilege Injection | BPI
[CVE-2025-54505](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-54505) | AMD Zen1 Floating-Point Divider Stale Data Leak | FPDSS
The following entries are ARM64 silicon errata that the kernel actively works around. They have no assigned CVE; they are tracked only by ARM's erratum numbers. Select them with `--errata <number>` or the associated `--variant` mnemonic.
ID | Name | Affected cores
-- | ---- | --------------
CVE-0001-0001 | Speculative AT TLB corruption (errata 1165522, 1319367, 1319537, 1530923) | Cortex-A55/A57/A72/A76
CVE-0001-0002 | Speculative unprivileged load (errata 2966298, 3117295) | Cortex-A510/A520
CVE-0001-0003 | MSR SSBS not self-synchronizing (erratum 3194386 + siblings) | Cortex-A76/A77/A78/A78C/A710/A715/A720/A720AE/A725, X1/X1C/X2/X3/X4/X925, Neoverse-N1/N2/N3/V1/V2/V3/V3AE
## Am I at risk?
Depending on your situation, the table below answers whether an attacker in a given position can extract data from a given target.
+10
View File
@@ -307,3 +307,13 @@ A weakness in AMD's microcode signature verification (AES-CMAC hash) allows load
Exploits a synchronization failure in the AMD stack engine via an undocumented MSR bit, targeting AMD SEV-SNP confidential VMs. Requires hypervisor-level (ring 0) access.
**Why out of scope:** Not a transient/speculative execution side channel. This is an architectural attack on AMD SEV-SNP confidential computing that requires hypervisor access, which is outside the threat model of this tool.
## No CVE — Jump Conditional Code (JCC) Erratum
- **Issue:** [#329](https://github.com/speed47/spectre-meltdown-checker/issues/329)
- **Intel whitepaper:** [Mitigations for Jump Conditional Code Erratum](https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf)
- **Affected CPUs:** Intel 6th through 10th generation Core and Xeon processors (Skylake through Cascade Lake)
A microarchitectural correctness erratum where a conditional jump instruction that straddles or ends at a 64-byte instruction fetch boundary can corrupt the branch predictor state, potentially causing incorrect execution. Intel addressed this in a November 2019 microcode update. Compilers and assemblers (GCC, LLVM, binutils) also introduced alignment options (`-mbranch-alignment`, `-x86-branches-within-32B-boundaries`) to pad jump instructions away from boundary conditions, preserving performance on CPUs with updated microcode.
**Why out of scope:** The JCC erratum is a microarchitectural correctness bug, not a transient or speculative execution side-channel vulnerability. No CVE was ever assigned. Red Hat noted that privilege escalation "has not been ruled out" but made no definitive security finding, and no exploit has been demonstrated. There is no Linux sysfs entry, no CPUID bit, and no MSR flag exposing the mitigation status. The microcode fix introduces no detectable hardware indicator, so checking for it would require maintaining a per-CPU-stepping minimum microcode version table (the design principle 3 exception) — costly to maintain without a CVE anchor or confirmed exploitability to justify the ongoing work. The kernel compiler mitigation is a build-time-only change (instruction alignment) with no observable runtime state.
File diff suppressed because it is too large Load Diff