diff --git a/.github/actions/build-dependencies/action.yml b/.github/actions/build-dependencies/action.yml index 695b7e4e..679167d5 100644 --- a/.github/actions/build-dependencies/action.yml +++ b/.github/actions/build-dependencies/action.yml @@ -62,7 +62,7 @@ runs: docker system prune -a --volumes sudo apt remove -y *docker* # Install uidmap which will be required for the explicitly installed Docker - sudo apt install uidmap + sudo apt install -y uidmap if: runner.os == 'Linux' - name: Update system dependencies diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 12ae78d6..6a4fdc33 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -208,7 +208,7 @@ jobs: - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0 - name: shellcheck run: | - sudo apt install shellcheck + sudo apt install -y shellcheck find . -iname "*.sh" | while read -r script; do shellcheck --enable=all --shell=sh --severity=info $script done diff --git a/.github/workflows/stack_size.yml b/.github/workflows/stack_size.yml new file mode 100644 index 00000000..031d3f63 --- /dev/null +++ b/.github/workflows/stack_size.yml @@ -0,0 +1,93 @@ +name: Check Update Default Stack Size + +on: + push: + paths: + - "orchestration/increase_default_stack_size.sh" + pull_request: + paths: + - "orchestration/increase_default_stack_size.sh" + workflow_dispatch: + # Also run weekly to ensure this doesn't inadvertently decay + schedule: + - cron: "0 0 * * 1" + +jobs: + stack_size: + strategy: + matrix: + os: [ubuntu-latest, ubuntu-24.04, ubuntu-22.04] + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0 + + - name: Download Monero + uses: ./.github/actions/monero + + - name: Verify expected behavior + shell: bash + run: | + cp /usr/bin/monerod monerod + + STACK=$((8 * 1024 * 1024)) + + cp monerod monerod-chelf + git clone https://github.com/Gottox/chelf + cd chelf + git checkout b2994186cea7b7d61a588fd06c1cc1ae75bcc21a + make + ./chelf -s $STACK ../monerod-chelf + cd .. + + cp monerod monerod-muslstack + GOBIN=$(pwd) go install github.com/yaegashi/muslstack@d19cc5866abce3ca59dfc1666df7cc97097d0933 + ./muslstack -s $STACK ./monerod-muslstack + + sudo apt update -y + sudo apt install -y ksh bash dash zsh busybox mksh yash + sudo ln -s $(which busybox) /usr/bin/ash + sudo ln -s $(which busybox) /usr/bin/hush + cargo install brush-shell + for shell in sh ksh bash dash zsh ash hush mksh yash brush; do + cp monerod monerod-idss-$shell + ln -s $(which $shell) sh + ./sh ./orchestration/increase_default_stack_size.sh monerod-idss-$shell + rm ./sh + done + + sha256() { + sha256sum "$1" | cut -d' ' -f1 + } + CHELF=$(sha256 monerod-chelf) + find . -iname "monerod-*" | while read -r bin; do + BIN=$(sha256 "$bin") + if [ ! "$CHELF" = "$BIN" ]; then + echo "Different artifact between monerod-chelf ($CHELF) and $bin ($BIN)" + exit 1 + fi + done + + read_stack() { + STACK_INFO=$(readelf "$1" -l | grep STACK -A1) + MEMSZ=$(echo "$STACK_INFO" | tail -n1 | sed -E s/^[[:space:]]*//g | cut -f2 -d' ') + printf "%i" $((MEMSZ)) + } + INITIAL_STACK=$(read_stack monerod) + if [ "$INITIAL_STACK" -ne "0" ]; then + echo "Initial \`PT_GNU_STACK\` wasn't 0" + exit 2 + fi + + UPDATED_STACK=$(read_stack monerod-chelf) + if [ "$UPDATED_STACK" -ne "$STACK" ]; then + echo "Updated \`PT_GNU_STACK\` ($UPDATED_STACK) wasn't 8 MB ($STACK)" + exit 3 + fi + + # Only one byte should be different due to the bit pattern of 8 MB + BYTES_DIFFERENT=$(cmp -l monerod monerod-chelf | wc -l || true) + if [ "$BYTES_DIFFERENT" -ne 1 ]; then + echo "More than one byte was different between the two binaries" + exit 4 + fi diff --git a/orchestration/increase_default_stack_size.sh b/orchestration/increase_default_stack_size.sh index 9cc2b2a7..b989808c 100755 --- a/orchestration/increase_default_stack_size.sh +++ b/orchestration/increase_default_stack_size.sh @@ -26,23 +26,28 @@ hex() { read_bytes() { dd bs=1 skip="$1" count="$2" if="$ELF" 2> /dev/null | hex } +hex_to_octal() { + printf "ibase=16; obase=8; %s\n" "$1" | bc +} write_bytes() { POS=$1 BYTES=$2 while [ ! "$BYTES" = "" ]; do - NEXT=$(printf "%s" "$BYTES" | head -c2) + NEXT=$(printf "%s" "$BYTES" | cut -c-2) # Advance to the third byte, as in, after the first two bytes BYTES=$(printf "%s" "$BYTES" | tail -c+3) + NEXT=$(hex_to_octal "$NEXT") # shellcheck disable=SC2059 - printf "\x$NEXT" | dd conv=notrunc bs=1 seek="$POS" of="$ELF" 2> /dev/null + printf \\"$NEXT" | dd conv=notrunc bs=1 seek="$POS" of="$ELF" 2> /dev/null POS=$((POS + 1)) done } # Magic MAGIC=$(read_bytes 0 4) -EXPECTED_MAGIC=$(printf "\x7ELF" | hex) +# shellcheck disable=SC2059 +EXPECTED_MAGIC=$(printf \\"$(hex_to_octal 7F)"ELF | hex) if [ ! "$MAGIC" = "$EXPECTED_MAGIC" ]; then echo "Not ELF" exit 2 @@ -101,9 +106,13 @@ swap_native_endian() { return fi - while [ ! "$BYTES" = "" ]; do + while :; do printf "%s" "$BYTES" | tail -c2 - BYTES=$(printf "%s" "$BYTES" | head -c-2) + NEW_LENGTH=$(( $(printf "%s" "$BYTES" | wc -c) - 2 )) + if [ "$NEW_LENGTH" -eq 0 ]; then + break + fi + BYTES=$(printf "%s" "$BYTES" | cut -c-$NEW_LENGTH) done } @@ -144,7 +153,7 @@ while [ "$NEXT_PROGRAM_HEADER" -ne -1 ]; do NEXT_PROGRAM_HEADER=$(( NEXT_PROGRAM_HEADER - 1 )) PROGRAM_HEADER=$(read_program_header "$THIS_PROGRAM_HEADER") - HEADER_TYPE=$(printf "%s" "$PROGRAM_HEADER" | head -c8) + HEADER_TYPE=$(printf "%s" "$PROGRAM_HEADER" | cut -c-8) HEADER_TYPE=$(swap_native_endian "$HEADER_TYPE") # `PT_GNU_STACK` # https://github.com/torvalds/linux/blob/c2f2b01b74be8b40a2173372bcd770723f87e7b2/include/uapi/linux/elf.h#L41