2025-12-08 20:04:23 -05:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
2025-12-08 01:58:19 -05:00
|
|
|
# Raises `PT_GNU_STACK`'s memory to be at least 8 MB.
|
|
|
|
|
#
|
|
|
|
|
# This causes `musl` to use a 8 MB default for new threads, resolving the primary
|
|
|
|
|
# compatibility issue faced when executing a program on a `musl` system.
|
|
|
|
|
#
|
|
|
|
|
# See https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-stack-size
|
|
|
|
|
# for reference. This differs that instead of setting at time of link, it
|
|
|
|
|
# patches the binary as an already-linked ELF executable.
|
|
|
|
|
|
2025-12-08 20:04:23 -05:00
|
|
|
set -e
|
2025-12-08 01:58:19 -05:00
|
|
|
|
|
|
|
|
ELF="$1"
|
|
|
|
|
if [ ! -f "$ELF" ]; then
|
|
|
|
|
echo "\`increase_default_stack_size.sh\` [ELF binary]"
|
|
|
|
|
echo ""
|
|
|
|
|
echo "Sets the \`PT_GNU_STACK\` program header to its existing value or 8 MB,"
|
|
|
|
|
echo "whichever is greater."
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2025-12-08 20:04:23 -05:00
|
|
|
hex() {
|
|
|
|
|
od -tx1 -v -A none | tr -d "[:space:]"
|
2025-12-08 01:58:19 -05:00
|
|
|
}
|
2025-12-08 20:04:23 -05:00
|
|
|
read_bytes() {
|
|
|
|
|
dd bs=1 skip="$1" count="$2" if="$ELF" 2> /dev/null | hex
|
2025-12-08 01:58:19 -05:00
|
|
|
}
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
hex_to_octal() {
|
2025-12-09 04:03:24 -05:00
|
|
|
HEX=$(printf "%s" "$1" | tr "[:lower:]" "[:upper:]")
|
|
|
|
|
printf "ibase=16; obase=8; %s\n" "$HEX" | bc
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
}
|
2025-12-08 20:04:23 -05:00
|
|
|
write_bytes() {
|
2025-12-08 01:58:19 -05:00
|
|
|
POS=$1
|
|
|
|
|
BYTES=$2
|
2025-12-08 20:04:23 -05:00
|
|
|
while [ ! "$BYTES" = "" ]; do
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
NEXT=$(printf "%s" "$BYTES" | cut -c-2)
|
2025-12-08 20:04:23 -05:00
|
|
|
# Advance to the third byte, as in, after the first two bytes
|
|
|
|
|
BYTES=$(printf "%s" "$BYTES" | tail -c+3)
|
|
|
|
|
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
NEXT=$(hex_to_octal "$NEXT")
|
2025-12-08 20:04:23 -05:00
|
|
|
# shellcheck disable=SC2059
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
printf \\"$NEXT" | dd conv=notrunc bs=1 seek="$POS" of="$ELF" 2> /dev/null
|
2025-12-08 20:04:23 -05:00
|
|
|
POS=$((POS + 1))
|
2025-12-08 01:58:19 -05:00
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Magic
|
|
|
|
|
MAGIC=$(read_bytes 0 4)
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
# shellcheck disable=SC2059
|
2025-12-09 04:03:24 -05:00
|
|
|
EXPECTED_MAGIC=$(printf \\"$(hex_to_octal 7f)"ELF | hex)
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ ! "$MAGIC" = "$EXPECTED_MAGIC" ]; then
|
2025-12-08 01:58:19 -05:00
|
|
|
echo "Not ELF"
|
|
|
|
|
exit 2
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 1 if 32-bit, 2 if 64-bit
|
|
|
|
|
BITS=$(read_bytes 4 1)
|
|
|
|
|
case $BITS in
|
|
|
|
|
"01") BITS=32;;
|
|
|
|
|
"02") BITS=64;;
|
|
|
|
|
*)
|
|
|
|
|
echo "Not 32- or 64- bit"
|
|
|
|
|
exit 3
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
# For `value_per_bits a b`, `a` if 32-bit and `b` if 64-bit
|
2025-12-08 20:04:23 -05:00
|
|
|
value_per_bits() {
|
2025-12-08 01:58:19 -05:00
|
|
|
RESULT=$(($1))
|
|
|
|
|
if [ $BITS = 64 ]; then
|
|
|
|
|
RESULT=$(($2))
|
|
|
|
|
fi
|
2025-12-08 20:04:23 -05:00
|
|
|
printf "%s" "$RESULT"
|
2025-12-08 01:58:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Read an integer by its offset, differing depending on if 32- or 64-bit
|
2025-12-08 20:04:23 -05:00
|
|
|
read_integer_by_offset() {
|
|
|
|
|
OFFSET=$(value_per_bits "$1" "$2")
|
|
|
|
|
BYTES=$(read_bytes "$OFFSET" "$3")
|
|
|
|
|
BYTES=$(swap_native_endian "$BYTES")
|
2025-12-09 04:03:24 -05:00
|
|
|
BYTES=$(printf "%s" "$BYTES" | tr "[:lower:]" "[:upper:]")
|
|
|
|
|
LESS_THAN_SANITY=$(printf "ibase=16; if(%s < 6FFFFFFF)1;\n" "$BYTES" | bc)
|
|
|
|
|
if [ ! "$LESS_THAN_SANITY" = "1" ]; then
|
|
|
|
|
echo "Integer value is approximate to 2**31, risking a signed long overflow"
|
|
|
|
|
exit 4
|
|
|
|
|
fi
|
2025-12-08 20:04:23 -05:00
|
|
|
printf "%i" $(( 0x$BYTES ))
|
2025-12-08 01:58:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 1 if little-endian, 2 if big-endian
|
|
|
|
|
LITTLE_ENDIAN=$(read_bytes 5 1)
|
|
|
|
|
case $LITTLE_ENDIAN in
|
|
|
|
|
"01") LITTLE_ENDIAN=1;;
|
|
|
|
|
"02") LITTLE_ENDIAN=0;;
|
|
|
|
|
*)
|
|
|
|
|
echo "Not little- or big- endian"
|
2025-12-09 04:03:24 -05:00
|
|
|
exit 5
|
2025-12-08 01:58:19 -05:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
# While this script is written in big-endian, we need to work with the file in
|
|
|
|
|
# its declared endian. This function swaps from big to native, or vice versa,
|
|
|
|
|
# as necessary.
|
2025-12-08 20:04:23 -05:00
|
|
|
swap_native_endian() {
|
2025-12-08 01:58:19 -05:00
|
|
|
BYTES="$1"
|
|
|
|
|
if [ "$BYTES" = "" ]; then
|
2025-12-08 20:04:23 -05:00
|
|
|
read -r BYTES
|
2025-12-08 01:58:19 -05:00
|
|
|
fi
|
|
|
|
|
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ "$LITTLE_ENDIAN" -eq 0 ]; then
|
|
|
|
|
printf "%s" "$BYTES"
|
2025-12-08 01:58:19 -05:00
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
while :; do
|
2025-12-08 20:04:23 -05:00
|
|
|
printf "%s" "$BYTES" | tail -c2
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
NEW_LENGTH=$(( $(printf "%s" "$BYTES" | wc -c) - 2 ))
|
|
|
|
|
if [ "$NEW_LENGTH" -eq 0 ]; then
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
BYTES=$(printf "%s" "$BYTES" | cut -c-$NEW_LENGTH)
|
2025-12-08 01:58:19 -05:00
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ELF_VERSION=$(read_bytes 6 1)
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ ! "$ELF_VERSION" = "01" ]; then
|
2025-12-08 01:58:19 -05:00
|
|
|
echo "Unknown ELF Version ($ELF_VERSION)"
|
2025-12-09 04:03:24 -05:00
|
|
|
exit 6
|
2025-12-08 01:58:19 -05:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
ELF_VERSION_2=$(read_bytes $((0x14)) 4)
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ ! "$ELF_VERSION_2" = "$(swap_native_endian 00000001)" ]; then
|
2025-12-08 01:58:19 -05:00
|
|
|
echo "Unknown secondary ELF Version ($ELF_VERSION_2)"
|
2025-12-09 04:03:24 -05:00
|
|
|
exit 7
|
2025-12-08 01:58:19 -05:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Find where the program headers are
|
2025-12-08 20:04:23 -05:00
|
|
|
PROGRAM_HEADERS_OFFSET=$(read_integer_by_offset 0x1c 0x20 "$(value_per_bits 4 8)")
|
2025-12-08 01:58:19 -05:00
|
|
|
PROGRAM_HEADER_SIZE=$(value_per_bits 0x20 0x38)
|
|
|
|
|
DECLARED_PROGRAM_HEADER_SIZE=$(read_integer_by_offset 0x2a 0x36 2)
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ ! "$PROGRAM_HEADER_SIZE" -eq "$DECLARED_PROGRAM_HEADER_SIZE" ]; then
|
2025-12-08 01:58:19 -05:00
|
|
|
echo "Unexpected size of a program header ($DECLARED_PROGRAM_HEADER_SIZE)"
|
2025-12-09 04:03:24 -05:00
|
|
|
exit 8
|
2025-12-08 01:58:19 -05:00
|
|
|
fi
|
2025-12-08 20:04:23 -05:00
|
|
|
program_header_start() {
|
|
|
|
|
printf "%i" $((PROGRAM_HEADERS_OFFSET + ($1 * PROGRAM_HEADER_SIZE)))
|
2025-12-08 01:58:19 -05:00
|
|
|
}
|
2025-12-08 20:04:23 -05:00
|
|
|
read_program_header() {
|
|
|
|
|
START=$(program_header_start "$1")
|
|
|
|
|
read_bytes "$START" "$PROGRAM_HEADER_SIZE"
|
2025-12-08 01:58:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Iterate over each program header
|
|
|
|
|
PROGRAM_HEADERS=$(read_integer_by_offset 0x2c 0x38 2)
|
2025-12-08 20:04:23 -05:00
|
|
|
NEXT_PROGRAM_HEADER=$(( PROGRAM_HEADERS - 1 ))
|
2025-12-08 01:58:19 -05:00
|
|
|
FOUND=0
|
2025-12-08 20:04:23 -05:00
|
|
|
while [ "$NEXT_PROGRAM_HEADER" -ne -1 ]; do
|
2025-12-08 01:58:19 -05:00
|
|
|
THIS_PROGRAM_HEADER=$NEXT_PROGRAM_HEADER
|
2025-12-08 20:04:23 -05:00
|
|
|
NEXT_PROGRAM_HEADER=$(( NEXT_PROGRAM_HEADER - 1 ))
|
|
|
|
|
PROGRAM_HEADER=$(read_program_header "$THIS_PROGRAM_HEADER")
|
2025-12-08 01:58:19 -05:00
|
|
|
|
Add a CI for `increase_default_stack_size.sh`
This runs whenever the script is modified, or weekly to ensure the CI doesn't
inadvertently decay (due to using the latest packages for a variety of shells).
This runs with `sh` (presumably `dash`), `ksh`, `bash`, `dash` (explicitly),
`zsh`, `ash` (Busybox), `hush` (Busybox), `mksh`, `yash`, and `brush`. While
none of these guarantee this script is POSIX-compliant, as a fully and
explicitly-only POSIX-compliant environment is not constructed, this does
reasonably test the script itself to be POSIX-compliant. The tools called have
been reviewed for being used to the POSIX standard (although not audited to
that degree).
The script itself is modified with the following changes for compliance with
POSIX:
1) `hexdump` is replaced with `od` (`od` suggested by @PlasmaPower)
2) `printf \xFF` replaced with octal escapes, as `\x` is not part of POSIX
3) `head -c` is replaced with `cut`, as the `-c` option is not standardized
under POSIX (despite it being present for `tail`). This was identified by
@PlasmaPower. As we used `head -c-2` to truncate the last two characters of
a string, we now use `wc -c` for a `strlen` to enable the necessary
arithmetic to calculate what two bytes in from the end of the string is.
This entire effort can be argued pointless, as we could simply run `monerod` on
Debian. This script is useful, the journey down the rabbithole of POSIX
compliance fascinating, and the methodology applicable to other potential
futures though (whether running binaries on Alpine or testing other `sh`
scripts for their portability). As part of this effort overall, our CI was
extended with `shellcheck` for all `sh` scripts in-tree, including all of our
existing `sh` scripts. That there is an actual, direct benefit past this
specific effort.
2025-12-09 00:57:26 -05:00
|
|
|
HEADER_TYPE=$(printf "%s" "$PROGRAM_HEADER" | cut -c-8)
|
2025-12-08 20:04:23 -05:00
|
|
|
HEADER_TYPE=$(swap_native_endian "$HEADER_TYPE")
|
2025-12-08 01:58:19 -05:00
|
|
|
# `PT_GNU_STACK`
|
|
|
|
|
# https://github.com/torvalds/linux/blob/c2f2b01b74be8b40a2173372bcd770723f87e7b2/include/uapi/linux/elf.h#L41
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ ! "$HEADER_TYPE" = "6474e551" ]; then
|
2025-12-08 01:58:19 -05:00
|
|
|
continue
|
|
|
|
|
fi
|
|
|
|
|
FOUND=1
|
|
|
|
|
|
2025-12-09 04:03:24 -05:00
|
|
|
# This line is the only line really risking an arithmetic overflow, yet the bound on the start of
|
|
|
|
|
# the section, combined with a maximum section length of `0xffff * 0x38`, makes this fit
|
2025-12-08 20:04:23 -05:00
|
|
|
MEMSZ_OFFSET=$(( $(program_header_start "$THIS_PROGRAM_HEADER") + $(value_per_bits 0x14 0x28) ))
|
2025-12-08 01:58:19 -05:00
|
|
|
MEMSZ_LEN=$(value_per_bits 4 8)
|
|
|
|
|
# `MEMSZ_OFFSET MEMSZ_OFFSET` as we've already derived it depending on the amount of bits
|
2025-12-08 20:04:23 -05:00
|
|
|
MEMSZ=$(read_integer_by_offset "$MEMSZ_OFFSET" "$MEMSZ_OFFSET" "$MEMSZ_LEN")
|
2025-12-08 01:58:19 -05:00
|
|
|
DESIRED_STACK_SIZE=$((8 * 1024 * 1024))
|
|
|
|
|
# Only run if the inherent value is _smaller_
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ "$MEMSZ" -lt "$DESIRED_STACK_SIZE" ]; then
|
2025-12-08 01:58:19 -05:00
|
|
|
# `2 *`, as this is its length in hexadecimal
|
2025-12-08 20:04:23 -05:00
|
|
|
HEX_MEMSZ=$(printf %."$((2 * MEMSZ_LEN))"x "$DESIRED_STACK_SIZE")
|
|
|
|
|
HEX_MEMSZ=$(swap_native_endian "$HEX_MEMSZ")
|
|
|
|
|
write_bytes "$MEMSZ_OFFSET" "$HEX_MEMSZ"
|
2025-12-08 01:58:19 -05:00
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
2025-12-08 20:04:23 -05:00
|
|
|
if [ "$FOUND" -eq 0 ]; then
|
2025-12-08 01:58:19 -05:00
|
|
|
echo "\`PT_GNU_STACK\` program header not found"
|
2025-12-09 04:03:24 -05:00
|
|
|
exit 9
|
2025-12-08 01:58:19 -05:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "All instances of \`PT_GNU_STACK\` patched to be at least 8 MB"
|
|
|
|
|
exit 0
|