Compare commits

...

4 Commits

Author SHA1 Message Date
KaraZajac 1663df69d1 release v0.9.7: kernel_range drift fix + CI Node 24 readiness
release / build (arm64) (push) Has been cancelled
release / build (x86_64) (push) Has been cancelled
release / build (x86_64-static / musl) (push) Has been cancelled
release / build (arm64-static / musl) (push) Has been cancelled
release / release (push) Has been cancelled
Tags the maintenance work landed since v0.9.6. The fragnesia drift fix (35c33df) and checkout v4->v6 bump (6c148e2) are already on main; this commit adds the remaining CI Node-24 bumps + version strings.

release.yml: upload-artifact v4->v7, download-artifact v4->v8, softprops/action-gh-release v2->v3 (last of the Node-20-era actions; GitHub forces node24 on 2026-06-16). Reviewed each changelog — our default-zip/unique-name upload + full-set download is unaffected by the major-version breaking changes (opt-in direct uploads, download-by-ID path).

Version bumped to 0.9.7 (skeletonkey.c, README, docs/index.html) + v0.9.7 RELEASE_NOTES entry. Tagging this commit fires release.yml — the end-to-end test of the new artifact actions, incl. the Alpine/musl static job under node24.
2026-06-01 11:55:31 -04:00
KaraZajac 6c148e276a ci: bump actions/checkout v4 -> v6 (Node 24 readiness)
GitHub forces the Node 24 runtime on 2026-06-16; checkout@v4 runs on the deprecated Node 20. checkout v6.0.2 declares runs.using: node24. All 9 usages (5 in build.yml, 4 in release.yml) are bare checkouts with no inputs, so the major bump is a drop-in.

Still on Node-20-era majors in release.yml, deferred (multi-major jumps with breaking changes, and release.yml only runs on tag push): upload-artifact v4->v7, download-artifact v4->v8, softprops/action-gh-release v2->v3.
2026-06-01 11:40:05 -04:00
KaraZajac 35c33df16f fragnesia: add 5.10.257 kernel_range entry (Debian bullseye backport)
Weekly drift-check (build.yml schedule cron) went red 2026-06-01: Debian's security tracker now lists CVE-2026-46300 as fixed on the 5.10 branch (bullseye 5.10.257), a branch fragnesia's kernel_patched_from table didn't model. detect() would false-positive VULNERABLE on a patched bullseye 5.10.257+ host.

Adding {5,10,257} clears the only MISSING finding; refresh-kernel-ranges.py now exits 0. The 10 remaining drifted modules are INFO-only 'more permissive' entries the check tolerates.
2026-06-01 11:05:05 -04:00
KaraZajac 25c2afc3e9 release v0.9.6: --auto no longer prompts for sudo password
release / build (arm64) (push) Has been cancelled
release / build (x86_64) (push) Has been cancelled
release / build (x86_64-static / musl) (push) Has been cancelled
release / build (arm64-static / musl) (push) Has been cancelled
release / release (push) Has been cancelled
sudo_runas_neg1 and sudoedit_editor's detect() bodies invoked
'sudo -ln' (intending list + non-interactive). Some sudoers / PAM
configurations have been observed prompting for a password anyway
when the flags are bundled. That meant skeletonkey --auto --i-know
could hang on a sudo password prompt during the corpus scan — bad
ergonomics for an LPE tool whose whole point is to get root without
already having it.

Fix: write '-n -l' as separate flags, redirect stdin from /dev/null
so sudo cannot fall back to reading the tty even if PAM tries to
coerce one. Belt-and-suspenders against any tty prompt during --auto.
2026-05-28 21:50:26 -04:00
9 changed files with 79 additions and 21 deletions
+5 -5
View File
@@ -25,7 +25,7 @@ jobs:
flavor: [default, debug] flavor: [default, debug]
name: build (${{ matrix.cc }} / ${{ matrix.flavor }}) name: build (${{ matrix.cc }} / ${{ matrix.flavor }})
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: install build deps - name: install build deps
run: | run: |
@@ -84,7 +84,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: sanitizers (ASan + UBSan) name: sanitizers (ASan + UBSan)
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: install deps - name: install deps
run: | run: |
sudo apt-get update -qq sudo apt-get update -qq
@@ -115,7 +115,7 @@ jobs:
name: clang-tidy name: clang-tidy
continue-on-error: true continue-on-error: true
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: install deps - name: install deps
run: | run: |
sudo apt-get update -qq sudo apt-get update -qq
@@ -141,7 +141,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: drift-check (CISA KEV + Debian tracker) name: drift-check (CISA KEV + Debian tracker)
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: cve_metadata drift - name: cve_metadata drift
run: | run: |
# Exits 1 if the federal data has drifted from our committed # Exits 1 if the federal data has drifted from our committed
@@ -168,7 +168,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: static-build name: static-build
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: install build deps - name: install build deps
run: | run: |
sudo apt-get update -qq sudo apt-get update -qq
+9 -9
View File
@@ -32,7 +32,7 @@ jobs:
name: build (${{ matrix.target }}) name: build (${{ matrix.target }})
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: install build deps - name: install build deps
run: | run: |
@@ -52,7 +52,7 @@ jobs:
mv skeletonkey skeletonkey-${{ matrix.target }} mv skeletonkey skeletonkey-${{ matrix.target }}
sha256sum skeletonkey-${{ matrix.target }} > skeletonkey-${{ matrix.target }}.sha256 sha256sum skeletonkey-${{ matrix.target }} > skeletonkey-${{ matrix.target }}.sha256
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v7
with: with:
name: skeletonkey-${{ matrix.target }} name: skeletonkey-${{ matrix.target }}
path: | path: |
@@ -71,7 +71,7 @@ jobs:
container: container:
image: alpine:latest image: alpine:latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: install build deps - name: install build deps
run: apk add --no-cache build-base linux-headers tar run: apk add --no-cache build-base linux-headers tar
- name: build static (musl) - name: build static (musl)
@@ -87,7 +87,7 @@ jobs:
run: | run: |
mv skeletonkey skeletonkey-x86_64-static mv skeletonkey skeletonkey-x86_64-static
sha256sum skeletonkey-x86_64-static > skeletonkey-x86_64-static.sha256 sha256sum skeletonkey-x86_64-static > skeletonkey-x86_64-static.sha256
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v7
with: with:
name: skeletonkey-x86_64-static name: skeletonkey-x86_64-static
path: | path: |
@@ -111,7 +111,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: build (arm64-static / musl) name: build (arm64-static / musl)
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: run dockcross arm64-musl build - name: run dockcross arm64-musl build
run: | run: |
# Fetch the dockcross wrapper script (handles UID/GID, # Fetch the dockcross wrapper script (handles UID/GID,
@@ -130,7 +130,7 @@ jobs:
run: | run: |
mv skeletonkey skeletonkey-arm64-static mv skeletonkey skeletonkey-arm64-static
sha256sum skeletonkey-arm64-static > skeletonkey-arm64-static.sha256 sha256sum skeletonkey-arm64-static > skeletonkey-arm64-static.sha256
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v7
with: with:
name: skeletonkey-arm64-static name: skeletonkey-arm64-static
path: | path: |
@@ -141,9 +141,9 @@ jobs:
needs: [build, build-static-x86_64, build-static-arm64] needs: [build, build-static-x86_64, build-static-arm64]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v8
with: with:
path: dist path: dist
@@ -181,7 +181,7 @@ jobs:
fi fi
- name: publish release - name: publish release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v3
with: with:
tag_name: ${{ steps.notes.outputs.tag }} tag_name: ${{ steps.notes.outputs.tag }}
name: SKELETONKEY ${{ steps.notes.outputs.tag }} name: SKELETONKEY ${{ steps.notes.outputs.tag }}
+1 -1
View File
@@ -202,7 +202,7 @@ also compile (modules with Linux-only headers stub out gracefully).
## Status ## Status
**v0.9.5 cut 2026-05-28.** 39 modules across 34 CVEs — **every **v0.9.7 cut 2026-06-01.** 39 modules across 34 CVEs — **every
year 2016 → 2026 now covered**. v0.9.0 added 5 gap-fillers year 2016 → 2026 now covered**. v0.9.0 added 5 gap-fillers
(`mutagen_astronomy` / `sudo_runas_neg1` / `tioscpgrp` / `vsock_uaf` / (`mutagen_astronomy` / `sudo_runas_neg1` / `tioscpgrp` / `vsock_uaf` /
`nft_pipapo`); v0.8.0 added 3 (`sudo_chwoot` / `udisks_libblockdev` / `nft_pipapo`); v0.8.0 added 3 (`sudo_chwoot` / `udisks_libblockdev` /
+50
View File
@@ -1,3 +1,53 @@
## SKELETONKEY v0.9.7 — kernel_range drift fix + CI Node 24 readiness
Two maintenance fixes, no new modules.
**`fragnesia` kernel_range drift.** Debian backported CVE-2026-46300 to
the 5.10 oldstable branch (bullseye 5.10.257), a branch the module's
`kernel_patched_from` table didn't model — on a patched bullseye host
`detect()` would have false-positived VULNERABLE. Added the `{5,10,257}`
entry; the weekly `refresh-kernel-ranges.py` drift gate is green again.
(The other flagged modules are INFO-only "more permissive" thresholds
the check tolerates by design.)
**CI Node 24 readiness.** GitHub forces the Node 24 Actions runtime on
2026-06-16 and removes Node 20. Bumped every workflow action off its
Node-20 line:
- `actions/checkout` v4 → v6
- `actions/upload-artifact` v4 → v7
- `actions/download-artifact` v4 → v8
- `softprops/action-gh-release` v2 → v3
Each was reviewed against its changelog: the artifact flow uploads
default-zipped, uniquely-named artifacts and downloads the full set, so
none of the major-version breaking changes (opt-in direct uploads,
download-by-ID path changes) apply. This release is itself the
end-to-end test of the new artifact actions.
## SKELETONKEY v0.9.6 — `--auto` no longer prompts for sudo password
Two sudo modules' `detect()` bodies invoked `sudo -ln` to read the
user's allowed-commands list. The intent was non-interactive — `-ln`
should parse as `-l -n` (list + non-interactive). But some sudoers /
PAM configurations have been observed prompting for a password
anyway when the flags are bundled, defeating the point.
That meant `skeletonkey --auto --i-know` could hang on a sudo
password prompt during the corpus scan, even though the whole point
of an LPE tool is to *get* root without already having it.
Fix in `sudo_runas_neg1` and `sudoedit_editor`:
- `-n -l` written as separate flags (instead of bundled `-ln`)
- `</dev/null` redirect so sudo cannot fall back to reading the tty
even if the PAM stack tries
Belt-and-suspenders. `--auto` is now guaranteed never to block on
tty input.
---
## SKELETONKEY v0.9.5 — kernel_range drift cleanup (the other half) ## SKELETONKEY v0.9.5 — kernel_range drift cleanup (the other half)
v0.9.4 fixed the `cve_metadata` drift but exposed a *second* drift v0.9.4 fixed the `cve_metadata` drift but exposed a *second* drift
+2 -2
View File
@@ -56,7 +56,7 @@
<div class="container hero-inner"> <div class="container hero-inner">
<div class="hero-eyebrow"> <div class="hero-eyebrow">
<span class="dot dot-pulse"></span> <span class="dot dot-pulse"></span>
v0.9.5 — released 2026-05-28 v0.9.7 — released 2026-06-01
</div> </div>
<h1 class="hero-title"> <h1 class="hero-title">
<span class="display-wordmark">SKELETONKEY</span> <span class="display-wordmark">SKELETONKEY</span>
@@ -598,7 +598,7 @@ uid=0(root) gid=0(root)</pre>
who found the bugs. who found the bugs.
</p> </p>
<p class="footer-meta"> <p class="footer-meta">
v0.9.5 · MIT · <a href="https://github.com/KaraZajac/SKELETONKEY">github.com/KaraZajac/SKELETONKEY</a> v0.9.7 · MIT · <a href="https://github.com/KaraZajac/SKELETONKEY">github.com/KaraZajac/SKELETONKEY</a>
</p> </p>
</div> </div>
</footer> </footer>
@@ -916,6 +916,7 @@ static int fg_active_probe(void)
* 7.1-rcN: still vulnerable (rc1..rc4 at time of writing) * 7.1-rcN: still vulnerable (rc1..rc4 at time of writing)
*/ */
static const struct kernel_patched_from fragnesia_patched_branches[] = { static const struct kernel_patched_from fragnesia_patched_branches[] = {
{5, 10, 257}, /* 5.10-LTS backport (Debian bullseye ships .257 with fix) */
{5, 15, 208}, /* 5.15-LTS backport */ {5, 15, 208}, /* 5.15-LTS backport */
{6, 1, 174}, /* 6.1-LTS backport */ {6, 1, 174}, /* 6.1-LTS backport */
{6, 6, 141}, /* 6.6-LTS backport */ {6, 6, 141}, /* 6.6-LTS backport */
@@ -106,7 +106,9 @@ static bool get_sudo_version(const char *sudo_path, char *out, size_t outsz)
static bool find_runas_blacklist_grant(const char *sudo_path, char *cmd_out, size_t cap) static bool find_runas_blacklist_grant(const char *sudo_path, char *cmd_out, size_t cap)
{ {
char cmd[512]; char cmd[512];
snprintf(cmd, sizeof cmd, "%s -ln 2>/dev/null", sudo_path); /* -n -l separated + stdin closed: see sudoedit_editor for the same
* pattern + rationale. `--auto` must never block on a tty prompt. */
snprintf(cmd, sizeof cmd, "%s -n -l </dev/null 2>/dev/null", sudo_path);
FILE *p = popen(cmd, "r"); FILE *p = popen(cmd, "r");
if (!p) return false; if (!p) return false;
char line[512]; char line[512];
@@ -149,8 +149,13 @@ static bool get_sudo_version(const char *sudo_path, char *out, size_t outsz)
static bool find_sudoedit_target(const char *sudo_path, char *out, size_t outsz) static bool find_sudoedit_target(const char *sudo_path, char *out, size_t outsz)
{ {
char cmd[512]; char cmd[512];
/* -n: non-interactive (no password prompt); -l: list. */ /* -n: non-interactive (no password prompt); -l: list. The two flags
snprintf(cmd, sizeof cmd, "%s -ln 2>&1", sudo_path); * are written separately and stdin is redirected from /dev/null so
* sudo cannot fall back to a tty prompt even if the local PAM stack
* tries to coerce one (some sudoers + pam_unix configurations have
* been observed prompting despite `-n` when the flags are bundled
* as `-ln`). Belt-and-suspenders so `--auto` never blocks on input. */
snprintf(cmd, sizeof cmd, "%s -n -l </dev/null 2>&1", sudo_path);
FILE *p = popen(cmd, "r"); FILE *p = popen(cmd, "r");
if (!p) return false; if (!p) return false;
+1 -1
View File
@@ -35,7 +35,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#define SKELETONKEY_VERSION "0.9.5" #define SKELETONKEY_VERSION "0.9.7"
static const char BANNER[] = static const char BANNER[] =
"\n" "\n"