Files
SKELETONKEY/.github/workflows/build.yml
T
KaraZajac bb5ca48fe1 ci: enable workflow_dispatch on build workflow
The drift-check job's if-gate already honors workflow_dispatch but
the trigger itself was never added to the on: block. Without it,
'gh workflow run build.yml' fails with 422. Found while validating
the v0.9.4 drift fix — wanted to confirm drift-check now passes
without waiting for next Monday's cron.
2026-05-28 13:37:35 -04:00

200 lines
7.7 KiB
YAML

name: build
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Weekly drift check against CISA KEV + Debian security tracker.
# Runs Monday 06:00 UTC; reports any new backports / KEV additions
# that haven't propagated into the corpus yet.
- cron: '0 6 * * 1'
workflow_dispatch:
# Lets us trigger the drift-check job on demand (e.g. after a
# metadata refresh) without waiting for the weekly cron. The
# drift-check job's `if:` gate honors this trigger.
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
cc: [gcc, clang]
flavor: [default, debug]
name: build (${{ matrix.cc }} / ${{ matrix.flavor }})
steps:
- uses: actions/checkout@v4
- name: install build deps
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
build-essential clang make linux-libc-dev \
libglib2.0-dev pkg-config
- name: show compiler
run: ${{ matrix.cc }} --version
- name: build
env:
CC: ${{ matrix.cc }}
run: |
if [ "${{ matrix.flavor }}" = "debug" ]; then
make debug
else
make
fi
- name: sanity — skeletonkey --version
run: ./skeletonkey --version
- name: sanity — skeletonkey --list
run: ./skeletonkey --list
- name: sanity — skeletonkey --scan (no exploit; just detect)
run: ./skeletonkey --scan --no-color || true
# exit code may be nonzero (vulnerable host = exit 2, missing
# precond = exit 4) — that's diagnostic data, not CI failure
- name: sanity — --detect-rules auditd
run: ./skeletonkey --detect-rules --format=auditd | head -50
- name: sanity — --detect-rules sigma
run: ./skeletonkey --detect-rules --format=sigma | head -50
- name: tests — detect() unit suite
env:
CC: ${{ matrix.cc }}
run: |
# Run as a non-root user so modules' "already root" gates do
# not short-circuit before the synthetic host-fingerprint
# checks fire. The test binary itself is platform-agnostic;
# the assertions are #ifdef __linux__ guarded.
sudo useradd -m -s /bin/bash skeletonkeyci 2>/dev/null || true
sudo chown -R skeletonkeyci .
sudo -u skeletonkeyci make test
# ASan + UBSan run. clang-only; catches memory bugs and undefined
# behaviour the regular test suite can't see. Runs on the same 88
# tests as the main matrix; failures here are real bugs even if
# the assertions all pass.
sanitizers:
runs-on: ubuntu-latest
name: sanitizers (ASan + UBSan)
steps:
- uses: actions/checkout@v4
- name: install deps
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
build-essential clang make linux-libc-dev \
libglib2.0-dev pkg-config sudo
- name: build + test under sanitizers
env:
CC: clang
# AddressSanitizer + UndefinedBehaviorSanitizer. -O1 keeps
# backtraces meaningful while still exercising optimizer paths;
# -fno-omit-frame-pointer for ASan stack traces; halt-on-error
# so the first finding fails CI loudly rather than scrolling
# past silently.
CFLAGS: "-O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize-recover=all -Wall -Wextra -Wno-unused-parameter -Wno-pointer-arith -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
LDFLAGS: "-fsanitize=address,undefined"
run: |
sudo useradd -m -s /bin/bash skeletonkeyci 2>/dev/null || true
sudo chown -R skeletonkeyci .
sudo -u skeletonkeyci -E make test
# clang-tidy lint. Runs against core/ + skeletonkey.c (the files we
# control most tightly). Non-blocking for now — sets a baseline we
# can tighten incrementally. Module sources are excluded; many
# bundle published PoC code that we keep close to upstream style.
clang-tidy:
runs-on: ubuntu-latest
name: clang-tidy
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: install deps
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
clang clang-tidy linux-libc-dev libglib2.0-dev pkg-config
- name: lint core + dispatcher
run: |
clang-tidy core/*.c skeletonkey.c \
--warnings-as-errors='' \
-- -Icore -Imodules/copy_fail_family/src \
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
# Drift check — runs the two refresh scripts in --check / drift mode
# against authoritative federal sources. Catches:
# - New CISA KEV additions touching CVEs in our corpus
# - New Debian security-tracker backport-version updates that move
# the kernel_patched_from table thresholds
# Network-required (fetches kev.csv + Debian tracker JSON). Runs on
# the weekly cron + on-demand via workflow_dispatch. NOT gated on
# PRs because random PRs shouldn't fail on upstream feed drift.
drift-check:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
name: drift-check (CISA KEV + Debian tracker)
steps:
- uses: actions/checkout@v4
- name: cve_metadata drift
run: |
# Exits 1 if the federal data has drifted from our committed
# JSON. Open a PR with `tools/refresh-cve-metadata.py` output
# if this fires.
python3 tools/refresh-cve-metadata.py --check || {
echo "::warning::cve_metadata drift detected — run tools/refresh-cve-metadata.py and commit the result"
exit 1
}
- name: kernel_range drift
run: |
# Exits 1 if any module's kernel_patched_from table is
# MISSING or TOO_TIGHT versus Debian's tracker. INFO-only
# findings are fine.
python3 tools/refresh-kernel-ranges.py || {
echo "::warning::kernel_range drift detected — see tools/refresh-kernel-ranges.py output"
exit 1
}
# Static build job: ensures the project links cleanly when -static is
# requested. Useful for deployment to minimal containers / fleet scans
# where shared-libc availability isn't guaranteed.
static-build:
runs-on: ubuntu-latest
name: static-build
steps:
- uses: actions/checkout@v4
- name: install build deps
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
build-essential make linux-libc-dev libc6-dev \
libglib2.0-dev pkg-config
- name: make static
# Glibc static linking pulls in NSS at runtime which breaks
# getpwnam; the legacy DIRTYFAIL Makefile noted this. For now,
# we allow this job to fail loudly so we know if a regression
# makes the regular dynamic build also break, but we don't
# gate the merge on it. Migrate to musl-gcc when we want a
# truly portable static binary.
continue-on-error: true
run: make static && ls -la skeletonkey
# Phase 4 followup (placeholder): kernel-VM matrix. Each entry runs
# the binary against a VM running a specific (vulnerable or patched)
# kernel and asserts the correct detect() verdict + exploit behavior.
# Requires self-hosted runners or a paid VM service; not enabled yet.
#
# kernel-vm-matrix:
# strategy:
# matrix:
# distro: [ubuntu-22.04, debian-11, alma-9, fedora-40]
# kernel: [5.10.50, 5.13.0, 5.15.30, 6.1.x, 6.12.x]
# runs-on: [self-hosted, kvm-host]
# ...