-
Notifications
You must be signed in to change notification settings - Fork 417
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kernelCTF: GHA: add build releaser workflow
- Loading branch information
1 parent
90d419b
commit d8211d8
Showing
9 changed files
with
408 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: kernelCTF auto releaser | ||
on: | ||
workflow_dispatch: | ||
schedule: | ||
- cron: '0 12 * * *' # every day at 12:00 UTC | ||
permissions: | ||
contents: read | ||
defaults: | ||
run: | ||
shell: bash | ||
working-directory: kernelctf | ||
jobs: | ||
get_new_builds: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout repo | ||
uses: actions/checkout@v3 | ||
|
||
- name: Install prerequisites | ||
run: sudo apt install -yq --no-install-recommends python3-lxml | ||
|
||
- id: check | ||
name: Check latest kernel versions | ||
run: ./get_latest_kernel_versions.py | ||
outputs: | ||
releases: ${{ steps.check.outputs.releases }} | ||
|
||
build_release: | ||
needs: get_new_builds | ||
strategy: | ||
matrix: | ||
release: ${{ fromJSON(needs.get_new_builds.outputs.releases) }} | ||
fail-fast: false # do not cancel other builds | ||
uses: ./.github/workflows/kernelctf-release-build.yaml | ||
secrets: inherit | ||
with: | ||
releaseId: ${{ matrix.release.releaseId }} | ||
branch: ${{ matrix.release.branch }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
name: kernelCTF release build | ||
on: | ||
workflow_dispatch: | ||
inputs: | ||
releaseId: | ||
description: 'Release ID' | ||
type: string | ||
required: true | ||
branch: | ||
description: 'Branch, tag or commit' | ||
type: string | ||
required: false | ||
workflow_call: | ||
inputs: | ||
releaseId: | ||
type: string | ||
branch: | ||
type: string | ||
run-name: 'kernelCTF release: ${{inputs.releaseId}}' | ||
permissions: | ||
contents: read | ||
defaults: | ||
run: | ||
shell: bash | ||
working-directory: kernelctf | ||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout repo | ||
uses: actions/checkout@v3 | ||
|
||
- name: Check release does not exist yet | ||
run: curl --fail -I https://storage.googleapis.com/kernelctf-build/releases/${{inputs.releaseId}}/bzImage && exit 1 || true | ||
|
||
- name: Install prerequisites | ||
run: sudo apt install -yq --no-install-recommends build-essential flex bison bc ca-certificates libelf-dev libssl-dev cpio pahole | ||
|
||
- name: Build | ||
run: ./build_release.sh ${{inputs.releaseId}} ${{inputs.branch}} | ||
|
||
- name: Show releases | ||
run: find releases -type f|xargs ls -al | ||
|
||
- name: Upload release artifact | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: ${{inputs.releaseId}} | ||
path: kernelctf/releases/${{inputs.releaseId}} | ||
if-no-files-found: error | ||
|
||
upload: | ||
runs-on: ubuntu-latest | ||
needs: build | ||
steps: | ||
- name: Download exploit | ||
uses: actions/download-artifact@v3 | ||
with: | ||
name: ${{inputs.releaseId}} | ||
path: ./kernelctf/releases/${{inputs.releaseId}} | ||
|
||
- name: Authenticate to Google Cloud | ||
uses: google-github-actions/auth@v1 | ||
with: | ||
credentials_json: '${{secrets.KERNELCTF_GCS_SA_KEY}}' | ||
|
||
- name: Upload release | ||
uses: 'google-github-actions/upload-cloud-storage@v1' | ||
with: | ||
path: kernelctf/releases/${{inputs.releaseId}} | ||
destination: kernelctf-build/releases | ||
predefinedAcl: publicRead | ||
process_gcloudignore: false # removes warnings that .gcloudignore file does not exist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
.cache/ | ||
__pycache__/ | ||
builds/ | ||
releases/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#!/bin/bash | ||
set -ex | ||
|
||
usage() { | ||
echo "Usage: $0 (lts|cos|mitigation)-<version> [<branch-tag-or-commit>]"; | ||
exit 1; | ||
} | ||
|
||
RELEASE_NAME="$1" | ||
BRANCH="$2" | ||
|
||
if [[ ! "$RELEASE_NAME" =~ ^(lts|cos|mitigation)-(.*) ]]; then usage; fi | ||
TARGET="${BASH_REMATCH[1]}" | ||
VERSION="${BASH_REMATCH[2]}" | ||
|
||
case $TARGET in | ||
lts) | ||
REPO="https://github.com/gregkh/linux" | ||
DEFAULT_BRANCH="v${VERSION}" | ||
CONFIG_FN="lts.config" | ||
;; | ||
cos) | ||
REPO="https://cos.googlesource.com/third_party/kernel" | ||
;; | ||
mitigation) | ||
REPO="https://github.com/thejh/linux" | ||
case $VERSION in | ||
v3-6.1.55) | ||
DEFAULT_BRANCH="mitigations-next" | ||
CONFIG_FN="mitigation-v3.config" | ||
CONFIG_FULL_FN="mitigation-v3-full.config" | ||
;; | ||
6.1 | 6.1-v2) | ||
DEFAULT_BRANCH="slub-virtual-v6.1" | ||
CONFIG_FN="mitigation-v1.config" | ||
;; | ||
esac ;; | ||
*) | ||
usage ;; | ||
esac | ||
|
||
BRANCH="${BRANCH:-$DEFAULT_BRANCH}" | ||
if [ -z "$BRANCH" ]; then usage; fi | ||
|
||
echo "REPO=$REPO" | ||
echo "BRANCH=$BRANCH" | ||
|
||
BASEDIR=`pwd` | ||
BUILD_DIR="$BASEDIR/builds/$RELEASE_NAME" | ||
RELEASE_DIR="$BASEDIR/releases/$RELEASE_NAME" | ||
CONFIGS_DIR="$BASEDIR/kernel_configs" | ||
|
||
if [ -d "$RELEASE_DIR" ]; then echo "Release directory already exists. Stopping."; exit 1; fi | ||
|
||
mkdir -p $BUILD_DIR 2>/dev/null || true | ||
cd $BUILD_DIR | ||
if [ ! -d ".git" ]; then git init && git remote add origin $REPO; fi | ||
|
||
if ! git checkout $BRANCH; then | ||
git fetch --depth 1 origin $BRANCH:$BRANCH || true # TODO: hack, solve it better | ||
git checkout $BRANCH | ||
fi | ||
|
||
if [ "$TARGET" == "cos" ]; then | ||
rm lakitu_defconfig || true | ||
make lakitu_defconfig | ||
cp .config lakitu_defconfig | ||
else | ||
curl 'https://cos.googlesource.com/third_party/kernel/+/refs/heads/cos-6.1/arch/x86/configs/lakitu_defconfig?format=text'|base64 -d > lakitu_defconfig | ||
cp lakitu_defconfig .config | ||
fi | ||
|
||
# build everything into the kernel instead of modules | ||
# note: this can increase the attack surface! | ||
sed -i s/=m/=y/g .config | ||
|
||
if [ ! -z "$CONFIG_FN" ]; then | ||
cp $CONFIGS_DIR/$CONFIG_FN kernel/configs/ | ||
make $CONFIG_FN | ||
fi | ||
|
||
make olddefconfig | ||
|
||
if [ ! -z "$CONFIG_FN" ]; then | ||
if scripts/diffconfig $CONFIGS_DIR/$CONFIG_FN .config|grep "^[^+]"; then | ||
echo "Config did not apply cleanly." | ||
exit 1 | ||
fi | ||
fi | ||
|
||
if [ ! -z "$CONFIG_FULL_FN" ]; then | ||
if scripts/diffconfig $CONFIGS_DIR/$CONFIG_FULL_FN .config|grep "^[^+]"; then | ||
echo "The full config has differences compared to the applied config. Check if the base config changed since custom config was created." | ||
exit 1 | ||
fi | ||
fi | ||
|
||
make -j`nproc` | ||
|
||
mkdir -p $RELEASE_DIR 2>/dev/null || true | ||
|
||
echo "REPOSITORY_URL=$REPO" > $RELEASE_DIR/COMMIT_INFO | ||
(echo -n "COMMIT_HASH="; git rev-parse HEAD) >> $RELEASE_DIR/COMMIT_INFO | ||
|
||
cp $BUILD_DIR/arch/x86/boot/bzImage $RELEASE_DIR/ | ||
cp $BUILD_DIR/lakitu_defconfig $RELEASE_DIR/ | ||
cp $BUILD_DIR/.config $RELEASE_DIR/ | ||
gzip -c $BUILD_DIR/vmlinux > $RELEASE_DIR/vmlinux.gz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#!/usr/bin/env -S python3 -u | ||
import json | ||
from utils import * | ||
from lxml import etree | ||
|
||
releases = [] | ||
|
||
def add_release(release_id, branch=None): | ||
url = f"https://storage.googleapis.com/kernelctf-build/releases/{release_id}/bzImage" | ||
status_code = requests.head(url).status_code | ||
if status_code == 200: | ||
print(" -> Release already exists, skipping...") | ||
return | ||
if status_code != 403: | ||
fail(f"Unexpected HTTP status code for release check: {status_code} (url = {url})") | ||
|
||
global releases | ||
releases.append({ "releaseId": release_id, "branch": branch }) | ||
|
||
latest_lts = run("git ls-remote --tags --sort='-v:refname' https://github.com/gregkh/linux 'v6.1.*[0-9]'")[0].split("refs/tags/")[1] | ||
print(f"Latest LTS: {latest_lts}") | ||
add_release(f"lts-{latest_lts[1:]}") | ||
|
||
for cos_milestone in [97, 105]: | ||
release_notes = fetch(f"https://cloud.google.com/feeds/cos-{cos_milestone}-release-notes.xml") | ||
tree = etree.XML(release_notes.encode('utf-8')) | ||
entries = tree.xpath("//*[local-name() = 'content']/text()") | ||
latest_entry = entries[0] | ||
version_tuple = checkOnlyOne(list(set(re.findall(f"cos-{cos_milestone}-(\d+)-(\d+)-(\d+)", latest_entry))), "too many versions were found") | ||
release_id = f"cos-{cos_milestone}-{'.'.join(version_tuple)}" | ||
commit = checkOnlyOne(re.findall("https://cos.googlesource.com/third_party/kernel/\+/([0-9a-f]{40})", latest_entry), "multiple commits were found") | ||
print(f"Latest COS {cos_milestone}: {release_id}, commit = {commit}") | ||
add_release(release_id, commit) | ||
|
||
ghSet("OUTPUT", "releases=" + json.dumps(releases)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# CONFIG_IO_URING is not set | ||
CONFIG_SYSTEM_TRUSTED_KEYS="" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# CONFIG_IO_URING is not set | ||
CONFIG_SYSTEM_TRUSTED_KEYS="" | ||
|
||
## required by CONFIG_SLAB_VIRTUAL | ||
CONFIG_DEBUG_VIRTUAL=y | ||
|
||
## required by CONFIG_KMALLOC_SPLIT_VARSIZE | ||
# CONFIG_SLAB_MERGE_DEFAULT is not set | ||
|
||
## turns on Jann's hardening | ||
CONFIG_KMALLOC_SPLIT_VARSIZE=y | ||
CONFIG_SLAB_VIRTUAL=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
################### General hardening ########################################## | ||
|
||
# Panic instead of failing gracefully and printing a warning when detecting data | ||
# corruption (e.g. in list debugging and SLAB_VIRTUAL) | ||
CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
# Check linked lists for corruption. Must be enabled together with | ||
# CONFIG_BUG_ON_DATA_CORRUPTION. | ||
CONFIG_DEBUG_LIST=y | ||
# Prevent overflows and other overwrites in copy_from/to_user | ||
CONFIG_HARDENED_USERCOPY=y | ||
# Detect some buffer overflows in strcpy/memcpy | ||
CONFIG_FORTIFY_SOURCE=y | ||
# Sets kernel.dmesg_restrict to 1 by default | ||
CONFIG_SECURITY_DMESG_RESTRICT=y | ||
# Prevent processes belonging to the same (unprivileged) user from ptracing each | ||
# other except for parents ptracing their children | ||
CONFIG_SECURITY_YAMA=y | ||
# Zero stack frames on function entry, makes some uninitialized variable uses | ||
# unexploitable | ||
CONFIG_INIT_STACK_ALL_ZERO=y | ||
# Print a warning if there are WX mappings at boot | ||
CONFIG_DEBUG_WX=y | ||
# Stack canaries | ||
CONFIG_STACKPROTECTOR=y | ||
CONFIG_STACKPROTECTOR_STRONG=y | ||
# Guard pages for kernel stacks | ||
CONFIG_VMAP_STACK=y | ||
# Randomize the offset of data on the kernel stack in syscalls | ||
CONFIG_RANDOMIZE_KSTACK_OFFSET=y | ||
CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y | ||
# Text KASLR | ||
CONFIG_RANDOMIZE_BASE=y | ||
# Other KASLR | ||
CONFIG_RANDOMIZE_MEMORY=y | ||
# Enforce W^X in the kernel | ||
CONFIG_STRICT_KERNEL_RWX=y | ||
CONFIG_STRICT_MODULE_RWX=y | ||
# Enable UMIP on the CPU to prevent using sidt/sgdt in userspace to leak kernel | ||
# pointers (if the CPU supports UMIP) | ||
CONFIG_X86_UMIP=y | ||
|
||
################### CPU side channels ########################################## | ||
|
||
# Meltdown mitigation | ||
CONFIG_PAGE_TABLE_ISOLATION=y | ||
# Spectre mitigations | ||
CONFIG_RETPOLINE=y | ||
CONFIG_CPU_IBPB_ENTRY=y | ||
CONFIG_CPU_IBRS_ENTRY=y | ||
|
||
################### Memory allocator ########################################### | ||
|
||
# SLUB because SLAB_VIRTUAL doesn't support SLAB or SLOB and those are | ||
# deprecated anyway | ||
CONFIG_SLUB=y | ||
# Randomize the order of the freelist when a new slab is created | ||
CONFIG_SLAB_FREELIST_RANDOM=y | ||
# Prevent attacks on the SLUB freelists | ||
CONFIG_SLAB_FREELIST_HARDENED=y | ||
# Don't merge slab caches (makes random caches/varsize useless and cross-cache easier) | ||
CONFIG_SLAB_MERGE_DEFAULT=n | ||
# Allocate msg_msg and some other useful objects in separate -cg caches | ||
CONFIG_CGROUPS=y | ||
CONFIG_MEMCG=y | ||
|
||
################### BPF ######################################################## | ||
|
||
# Allow sandboxing with seccomp | ||
CONFIG_SECCOMP=y | ||
CONFIG_SECCOMP_FILTER=y | ||
# This is required for jitting seccomp filters (probably) | ||
CONFIG_BPF_SYSCALL=y | ||
# Remove Spectre gadgets in the BPF interpreter | ||
CONFIG_BPF_JIT=y | ||
CONFIG_BPF_JIT_ALWAYS_ON=y | ||
# Makes the kernel.unprivileged_bpf_disabled default to 2 | ||
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y | ||
|
||
################### Attack surface reduction ################################### | ||
|
||
# Disable io_uring | ||
CONFIG_IO_URING=n | ||
# Prevent attackers from stopping the kernel inside copy_from/to_user | ||
CONFIG_USERFAULTFD=n | ||
CONFIG_FUSE_FS=n | ||
# Disable staging drivers, which may be more buggy | ||
CONFIG_STAGING=n | ||
|
||
################## Extra mitigations/not upstreamed ############################ | ||
|
||
# Protects against cross-cache attacks. Must be enabled together with | ||
# CONFIG_BUG_ON_DATA_CORRUPTION | ||
CONFIG_SLAB_VIRTUAL=y | ||
# Splits kmalloc caches in fixed-size and dynamic size to make UaF exploitation | ||
# harder | ||
CONFIG_KMALLOC_SPLIT_VARSIZE=y | ||
# Create multiple copies of the normal and -cg kmalloc caches to make spraying | ||
# harder | ||
CONFIG_RANDOM_KMALLOC_CACHES=y | ||
|
||
################### Make the kernel less annyoing to debug ##################### | ||
|
||
# Compile the kernel with debug info | ||
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y | ||
# Have all symbols in kallsyms | ||
CONFIG_KALLSYMS=y | ||
CONFIG_KALLSYMS_ALL=y | ||
CONFIG_TRIM_UNUSED_KSYMS=n | ||
# Include the kernel configuration in the bzImage/vmlinux | ||
CONFIG_IKCONFIG=y | ||
CONFIG_IKCONFIG_PROC=y | ||
# SLUB stats in /sys/slab | ||
SLUB_DEBUG=y |
Oops, something went wrong.