System Graft v0.1.0
First release.
Inject out-of-tree kernel modules into a SquashFS initrd, hook them into the image's init
scripts, and write the result to bootable removable media. You supply the image and the
modules — this ships neither.
Install
No packaging step: it's Python 3 with the standard library only.
git clone https://github.com/allansargeant/system-graft
cd system-graft
brew install squashfs # or: apt install squashfs-tools
python3 gui.pyThere is deliberately no frozen .app or .exe. A bundled app would still require
squashfs-tools on PATH, and an unsigned macOS bundle containing a nested interpreter is
liable to be killed by Gatekeeper without a visible error. Running the scripts is both
simpler and more reliable.
What it does
Patch — inject .ko files into the initrd, add a load hook to init, repack matching the
source's compressor and block size.
Write — put the whole boot tree on removable media as a UEFI-bootable volume
(GPT + FAT32), substituting the patched initrd in flight.
Why it isn't just unsquashfs + mksquashfs
Doing this by hand quietly produces a broken image:
- Ownership is lost — a non-root extract cannot restore uid/gid.
- setuid/setgid bits are dropped, so a setuid-root busybox comes back unprivileged.
- The root inode escapes even a careful pseudo-file.
This reads the full mode/uid/gid table from the source, replays it through a mksquashfs
pseudo-file, applies the root inode via -root-uid/-root-gid/-root-mode, then re-reads the
output and diffs it against the source. It does not report success unless the permission
table matches exactly.
It also checks vermagic against modules already in the image and refuses on mismatch by
default — that failure otherwise shows up silently at boot, on a machine you may have no
console on.
Safety
USB writing only ever offers devices the OS reports as external, excludes virtual devices
unless explicitly asked, re-reads the device immediately before writing, refuses anything
mounted at a system path, requires the device node to be typed to confirm, and verifies
every written file by sha256 before ejecting.
Tested
16 tests, run on Ubuntu and macOS in CI. They build a synthetic appliance image from
scratch — root-owned files, a setuid binary, a directory owned by a uid with no passwd
entry — patch it, and assert all of it survives. Also covered: hook placement and
indentation, hook landing inside the correct init branch, idempotency across three
consecutive re-patches, vermagic blocking and override, input immutability, and
output-overwrite refusal.
macOS is the tested path for USB writing. Linux is implemented but untested. Windows is
not supported.
See CHANGELOG.md.