diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c12d3643..3d109e789 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -241,3 +241,35 @@ jobs: cp -a tests/frida-tests tests/labrats lib/agent/frida-agent.so /tmp/pkg/ tar -C /tmp/pkg -cf /tmp/runner.tar . /opt/sabrelite/run.sh /tmp/runner.tar /opt/frida/frida-tests + + # This job is used to check that the Linux helpers are built correctly for all + # supported architectures. We do this because the binary artifacts are checked + # in, and we want to ensure that they are up-to-date with respect to the source + # for all architectures. + check-linux-helpers: + strategy: + matrix: + arch: [x86, x86_64, arm, arm64, mips, mipsel, mips64, mips64el] + runs-on: ubuntu-latest + container: ghcr.io/frida/core-linux-helpers-${{ matrix.arch }}:latest + steps: + - name: Check out repo + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Build + run: | + ./src/linux/helpers/rebuild.sh ${{ matrix.arch }} + - name: Check for unexpected changes + run: | + git config --global --add safe.directory "$(realpath .)" + status_output="$(git status --porcelain)" + if [ -n "$status_output" ]; then + echo "Unexpected changes detected:" + echo "$status_output" + echo "Diff:" + git diff + exit 1 + else + echo "No unexpected changes detected." + fi diff --git a/src/linux/helpers/bootstrapper-arm.bin b/src/linux/helpers/bootstrapper-arm.bin index 1bbe33bf4..bea7af224 100644 Binary files a/src/linux/helpers/bootstrapper-arm.bin and b/src/linux/helpers/bootstrapper-arm.bin differ diff --git a/src/linux/helpers/bootstrapper-mips.bin b/src/linux/helpers/bootstrapper-mips.bin index ad152cea4..33234d8a0 100644 Binary files a/src/linux/helpers/bootstrapper-mips.bin and b/src/linux/helpers/bootstrapper-mips.bin differ diff --git a/src/linux/helpers/bootstrapper-mips64.bin b/src/linux/helpers/bootstrapper-mips64.bin index 2314e142e..76f9ecde1 100644 Binary files a/src/linux/helpers/bootstrapper-mips64.bin and b/src/linux/helpers/bootstrapper-mips64.bin differ diff --git a/src/linux/helpers/bootstrapper-mips64el.bin b/src/linux/helpers/bootstrapper-mips64el.bin index 277f4ad9b..b0c90946f 100644 Binary files a/src/linux/helpers/bootstrapper-mips64el.bin and b/src/linux/helpers/bootstrapper-mips64el.bin differ diff --git a/src/linux/helpers/bootstrapper-mipsel.bin b/src/linux/helpers/bootstrapper-mipsel.bin index 545449136..f0e4f45bc 100644 Binary files a/src/linux/helpers/bootstrapper-mipsel.bin and b/src/linux/helpers/bootstrapper-mipsel.bin differ diff --git a/src/linux/helpers/bootstrapper-x86.bin b/src/linux/helpers/bootstrapper-x86.bin index 80b908f94..c9a9ad73f 100644 Binary files a/src/linux/helpers/bootstrapper-x86.bin and b/src/linux/helpers/bootstrapper-x86.bin differ diff --git a/src/linux/helpers/bootstrapper-x86_64.bin b/src/linux/helpers/bootstrapper-x86_64.bin index 63625083f..9ab54bda9 100644 Binary files a/src/linux/helpers/bootstrapper-x86_64.bin and b/src/linux/helpers/bootstrapper-x86_64.bin differ diff --git a/src/linux/helpers/loader-arm.bin b/src/linux/helpers/loader-arm.bin index ec1fcda18..23229e290 100644 Binary files a/src/linux/helpers/loader-arm.bin and b/src/linux/helpers/loader-arm.bin differ diff --git a/src/linux/helpers/loader-mips.bin b/src/linux/helpers/loader-mips.bin index 5eabd6d67..4e1843a43 100644 Binary files a/src/linux/helpers/loader-mips.bin and b/src/linux/helpers/loader-mips.bin differ diff --git a/src/linux/helpers/loader-mips64.bin b/src/linux/helpers/loader-mips64.bin index 7fda4fb51..d4de26972 100644 Binary files a/src/linux/helpers/loader-mips64.bin and b/src/linux/helpers/loader-mips64.bin differ diff --git a/src/linux/helpers/loader-mips64el.bin b/src/linux/helpers/loader-mips64el.bin index 73d4ac135..53841a73d 100644 Binary files a/src/linux/helpers/loader-mips64el.bin and b/src/linux/helpers/loader-mips64el.bin differ diff --git a/src/linux/helpers/loader-mipsel.bin b/src/linux/helpers/loader-mipsel.bin index 0e3ee5a28..98ab32da7 100644 Binary files a/src/linux/helpers/loader-mipsel.bin and b/src/linux/helpers/loader-mipsel.bin differ diff --git a/src/linux/helpers/loader-x86.bin b/src/linux/helpers/loader-x86.bin index 9e8fb3f35..6f95a4699 100644 Binary files a/src/linux/helpers/loader-x86.bin and b/src/linux/helpers/loader-x86.bin differ diff --git a/src/linux/helpers/loader-x86_64.bin b/src/linux/helpers/loader-x86_64.bin index 5fa4126f8..3bb302298 100644 Binary files a/src/linux/helpers/loader-x86_64.bin and b/src/linux/helpers/loader-x86_64.bin differ diff --git a/src/linux/helpers/meson.build b/src/linux/helpers/meson.build index 184f448d7..66cc4f8ff 100644 --- a/src/linux/helpers/meson.build +++ b/src/linux/helpers/meson.build @@ -24,6 +24,10 @@ if host_machine.cpu_family() == 'arm' extra_flags += '-marm' endif +if host_machine.cpu_family() == 'x86' + extra_flags += '-fno-stack-protector' +endif + common_objcopy_flags = [ '-O', 'binary', '-S', @@ -53,9 +57,10 @@ extra_link_args = [ '-Wl,-T,' + helper_lds, ] if host_machine.cpu_family() == 'arm' - extra_link_args += run_command('../../../../build/frida-android-arm-clang', '-print-libgcc-file-name', check: false).stdout().strip() + extra_link_args += run_command(cc, '-print-libgcc-file-name', check: false).stdout().strip() endif + bootstrapper_sources = [ 'bootstrapper.c', 'elf-parser.c', diff --git a/src/linux/helpers/nolibc-tweaks.patch b/src/linux/helpers/nolibc-tweaks.patch index ef0925b1b..016044218 100644 --- a/src/linux/helpers/nolibc-tweaks.patch +++ b/src/linux/helpers/nolibc-tweaks.patch @@ -303,26 +303,3 @@ index 78473d34e..f17e6f598 100644 + mode = va_arg(args, /* mode_t */ unsigned int); va_end(args); } - -diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h -index fbbc0e68c..d003c368d 100644 ---- a/tools/include/nolibc/types.h -+++ b/tools/include/nolibc/types.h -@@ -92,6 +92,8 @@ - #define FD_SETIDXMASK (8 * sizeof(unsigned long)) - #define FD_SETBITMASK (8 * sizeof(unsigned long)-1) - -+#ifndef __mips__ -+ - /* for select() */ - typedef struct { - unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK]; -@@ -131,6 +133,8 @@ typedef struct { - __set->fds[__idx] = 0; \ - } while (0) - -+#endif -+ - /* for poll() */ - #define POLLIN 0x0001 - #define POLLPRI 0x0002 diff --git a/src/linux/helpers/rebuild.sh b/src/linux/helpers/rebuild.sh new file mode 100755 index 000000000..b16635d6d --- /dev/null +++ b/src/linux/helpers/rebuild.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +# This script is responsible for building Frida helpers for various Linux +# architectures. It can build helpers for a single specified architecture on the +# local machine, or for supported architectures in a container. The script uses +# Docker containers to ensure consistent build environments for each +# architecture. +# +# Note that the expectation is that when running the build for a specific +# architecture that it be run from inside the relevant container. This script is +# used by CI. + +set -euo pipefail + +CURRENT_FILE="${BASH_SOURCE[0]}" +HELPERS_DIR="$(cd "$(dirname "$CURRENT_FILE")" && pwd)" +FRIDA_CORE_DIR="$(cd "$HELPERS_DIR/../../.." && pwd)" +RELENG_DIR="$FRIDA_CORE_DIR/releng" +BUILD_DIR="$FRIDA_CORE_DIR/build" +RELATIVE_TO_FRIDA_CORE_DIR=$(realpath --relative-to="$FRIDA_CORE_DIR" "$CURRENT_FILE") + +TMP_MESON_DIR=$(mktemp -d) +trap 'rm -rf "$TMP_MESON_DIR"' EXIT + +CONTAINER_REGISTRY="${CONTAINER_REGISTRY:-ghcr.io/frida}" + +main () { + if [ "$#" -eq 0 ]; then + build_arches_in_container + return + fi + + if [ "$#" -gt 1 ]; then + echo >&2 "Error: Too many arguments" + usage + fi + + build_arch "$1" +} + +usage () { + echo >&2 "Usage: $0 []" + echo >&2 "If no arch is specified, then all helpers will be built in the container." + exit 1 +} + +setup_meson () { + ln -s "$RELENG_DIR/meson/meson.py" "$TMP_MESON_DIR/meson" + chmod +x "$TMP_MESON_DIR/meson" + export PATH="$TMP_MESON_DIR:$PATH" +} + +ARCHS=( + x86 + x86_64 + arm + arm64 + mips + mipsel + mips64 + mips64el +) + +build_arch () { + ARCH=$1 + if [ -z "$ARCH" ]; then + usage + fi + if ! printf '%s\n' "${ARCHS[@]}" | grep -qx "$ARCH"; then + echo >&2 "Error: Invalid architecture '$ARCH'" + echo >&2 "Supported architectures: ${ARCHS[*]}" + exit 1 + fi + + if [[ "$ARCH" == arm* ]]; then + export FRIDA_HOST=android-$ARCH + else + export FRIDA_HOST=linux-$ARCH + fi + + EXTRA_FLAGS=() + if [ "$FRIDA_HOST" == "linux-x86" ]; then + EXTRA_FLAGS+=("--build=linux-x86") + export CC="gcc -m32" CXX="g++ -m32" STRIP="strip" + fi + + setup_meson + + cd "$FRIDA_CORE_DIR" + + rm -rf "$BUILD_DIR" + # Note that $XTOOLS_HOST is set by the container. + ./configure --host="$XTOOLS_HOST" "${EXTRA_FLAGS[@]}" + make -C src/linux/helpers +} + +build_arches_in_container () { + for ARCH in "${ARCHS[@]}"; do + docker run -u "$(id -u):$(id -g)" \ + -w /frida-core \ + -i -t \ + -v "$FRIDA_CORE_DIR:/frida-core" \ + "$CONTAINER_REGISTRY/core-linux-helpers-$ARCH:latest" \ + "/frida-core/$RELATIVE_TO_FRIDA_CORE_DIR" "$ARCH" + done +} + +main "$@"