diff --git a/.github/typos_config.toml b/.github/typos_config.toml index e5ba5d36..1f71d736 100644 --- a/.github/typos_config.toml +++ b/.github/typos_config.toml @@ -4,7 +4,7 @@ # tricky, so some false positives are fine [files] -extend-exclude = ["LICENSE", "misc/*/packages.txt"] +extend-exclude = ["LICENSE", "misc/*/packages.txt", "misc/*/*/packages.txt"] [default.extend-identifiers] # misc variable names & symbols @@ -13,7 +13,10 @@ ba = "ba" fo = "fo" fof = "fof" O_WRONLY = "O_WRONLY" +# clang-analyzer-optin.cplusplus +optin = "optin" sidelen = "sidelen" +tpos = "tpos" # assembly sources CArry = "CArry" hda = "hda" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96f76a00..497dd9c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,7 @@ jobs: sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ rm -rf ./*.deb ./packages sudo ldconfig + # install upx-stubtools wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ - name: 'Check out code' uses: actions/checkout@v3 @@ -285,8 +286,6 @@ jobs: - name: 'Prepare sources and Check out test suite' shell: bash run: | - git config --global core.autocrlf input - git --version && bash --version git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd} - name: 'Set up Developer Command Prompt' @@ -297,7 +296,7 @@ jobs: - name: 'Build by hand' shell: cmd run: | - @REM setup directories + @REM ===== set vars ===== where cl & where link set RUN_CL=cl ${{ matrix.cl_machine_flags }} -MT set RUN_LIB=link -lib ${{ matrix.link_machine_flags }} @@ -331,7 +330,7 @@ jobs: set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp - %RUN_CL% -J -O2 -W4 -WX -std:c++17 -Zc:__cplusplus -EHsc -DUPX_VERSION_GITREV="""%GITREV%""" %UPX_DEFS% %DEFS% -I%H%\vendor -Feupx.exe %sources% %UPX_LIBS% /link ${{ matrix.link_machine_flags }} setargv.obj + %RUN_CL% -J -O2 -W4 -WX -std:c++17 -Zc:__cplusplus -EHsc -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% %UPX_DEFS% -I%H%\vendor -Feupx.exe %sources% %UPX_LIBS% /link ${{ matrix.link_machine_flags }} setargv.obj - name: 'Make artifact' shell: bash run: | diff --git a/.github/workflows/static-analyzer-clang-analyzer.yml b/.github/workflows/static-analyzer-clang-analyzer.yml index 8e5de988..bac9a868 100644 --- a/.github/workflows/static-analyzer-clang-analyzer.yml +++ b/.github/workflows/static-analyzer-clang-analyzer.yml @@ -2,7 +2,7 @@ name: 'Static Analyzer - clang-analyzer' on: - schedule: [cron: '20 5 * * 3'] # run weekly Wednesday 05:20 UTC + schedule: [cron: '10 5 * * 3'] # run weekly Wednesday 05:10 UTC workflow_dispatch: jobs: diff --git a/.github/workflows/static-analyzer-codeql.yml b/.github/workflows/static-analyzer-codeql.yml index 4149c760..13679861 100644 --- a/.github/workflows/static-analyzer-codeql.yml +++ b/.github/workflows/static-analyzer-codeql.yml @@ -2,7 +2,7 @@ name: 'Static Analyzer - CodeQL' on: - schedule: [cron: '40 5 * * 3'] # run weekly Wednesday 05:40 UTC + schedule: [cron: '50 5 * * 3'] # run weekly Wednesday 05:50 UTC workflow_dispatch: jobs: diff --git a/.github/workflows/weekly-ci-alpine-linux.yml b/.github/workflows/weekly-ci-alpine-linux.yml index 029fda41..4cb88f5a 100644 --- a/.github/workflows/weekly-ci-alpine-linux.yml +++ b/.github/workflows/weekly-ci-alpine-linux.yml @@ -1,9 +1,9 @@ # Copyright (C) Markus Franz Xaver Johannes Oberhumer -# build under various Alpine Linux versions with clang and gcc, and -# also test building with C++20 and C++23 +# Build under various Alpine Linux versions with clang and gcc, and +# also test building with C++20 and C++23. -# also uses a subdirectory "upx with space" that contains whitespace in order -# to detect possible quoting issues +# And also uses a subdirectory "upx with space" that contains whitespace in order +# to detect possible quoting issues. # info: Alpine 3.9 has clang-5, cmake-3.13.0 and gcc-8, which nicely # matches our minimal build requirements diff --git a/.gitignore b/.gitignore index d54552a3..5fe0b25b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,18 +13,25 @@ tmp* *.a *.d +*.bz2 *.dll +*.dylib *.exe +*.gz *.lib *.map *.o *.obj *.out *.py[cdo] +*.rar *.so *.swp *.tmp *.ttp +*.xz +*.zip +*.zst doc/*.man doc/*.ps diff --git a/misc/cross-compile-upx-with-podman/11-list-packages.sh b/misc/cross-compile-upx-with-podman/11-list-packages.sh index 9150c112..37457aba 100755 --- a/misc/cross-compile-upx-with-podman/11-list-packages.sh +++ b/misc/cross-compile-upx-with-podman/11-list-packages.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # list all system packages that are installed in the image # using a rootless Podman container -image=upx-cross-compile-20230115-v4 +image="$("$argv0dir/10-create-image.sh" --print-image)" podman image list "$image" echo diff --git a/misc/rebuild-stubs-with-podman/11-list-packages.sh b/misc/rebuild-stubs-with-podman/11-list-packages.sh index 64cd04e4..37457aba 100755 --- a/misc/rebuild-stubs-with-podman/11-list-packages.sh +++ b/misc/rebuild-stubs-with-podman/11-list-packages.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # list all system packages that are installed in the image # using a rootless Podman container -image=upx-stubtools-20221212-v6 +image="$("$argv0dir/10-create-image.sh" --print-image)" podman image list "$image" echo diff --git a/misc/test-qemu-with-podman/test-qemu3-alpine/10-create-image.sh b/misc/test-qemu-with-podman/test-qemu3-alpine/10-create-image.sh new file mode 100755 index 00000000..46e4af1e --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu3-alpine/10-create-image.sh @@ -0,0 +1,16 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# create the image from Dockerfile +# using a rootless Podman container + +image=upx-test-qemu3-alpine-20230708-v1 +[[ $1 == --print-image ]] && echo "$image" && exit 0 + +podman build --squash -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" + +podman image list "$image" +echo +podman image tree "$image" diff --git a/misc/test-qemu-with-podman/test-qemu3-alpine/11-list-packages.sh b/misc/test-qemu-with-podman/test-qemu3-alpine/11-list-packages.sh new file mode 100755 index 00000000..58445cc0 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu3-alpine/11-list-packages.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# list all system packages that are installed in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +podman image list "$image" +echo +podman image tree "$image" + +echo 'Packages:' +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +podman run "${flags[@]}" "$image" bash -c $'apk info -v | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/misc/test-qemu-with-podman/test-qemu3-alpine/20-image-run-shell.sh b/misc/test-qemu-with-podman/test-qemu3-alpine/20-image-run-shell.sh new file mode 100755 index 00000000..1f83802d --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu3-alpine/20-image-run-shell.sh @@ -0,0 +1,37 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# run an interactive shell in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM +if [[ 1 == 1 ]]; then + # run as user upx 2000:2000 + flags+=( --user 2000 ) + # map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user + flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 ) + # map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group + flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 ) + # NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx + # INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs! + flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" ) + flags+=( -w /home/upx/src/upx ) # set working directory + flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs + flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs +else + # run as user root 0:0 + # ONLY FOR DEBUGGING THE IMAGE + # map container user/group 0 to current host user/group + flags+=( --user 0 ) +fi + +podman run "${flags[@]}" "$image" bash -l + +# please see usage instructions in ../README.md diff --git a/misc/test-qemu-with-podman/test-qemu3-alpine/Dockerfile b/misc/test-qemu-with-podman/test-qemu3-alpine/Dockerfile new file mode 100644 index 00000000..fac27809 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu3-alpine/Dockerfile @@ -0,0 +1,26 @@ +FROM docker.io/library/alpine:3.9 + +# install qemu 3.1.0-r3 and some utils +RUN apk update && apk upgrade && apk add \ + bash-completion \ + musl-dbg \ + qemu-aarch64 \ + qemu-arm \ + qemu-armeb \ + qemu-i386 \ + qemu-mips \ + qemu-mipsel \ + qemu-ppc \ + qemu-ppc64 \ + qemu-ppc64le \ + qemu-x86_64 \ + strace \ + && true + +# create default user upx 2000:2000 +RUN adduser upx -u 2000 -D \ + && cd /home/upx && chmod 00700 . \ + && mkdir -p .cache .local/bin src/upx \ + && chown -R upx:upx . \ + && true +USER upx diff --git a/misc/test-qemu-with-podman/test-qemu4-alpine/10-create-image.sh b/misc/test-qemu-with-podman/test-qemu4-alpine/10-create-image.sh new file mode 100755 index 00000000..f4c635e5 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu4-alpine/10-create-image.sh @@ -0,0 +1,16 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# create the image from Dockerfile +# using a rootless Podman container + +image=upx-test-qemu4-alpine-20230708-v1 +[[ $1 == --print-image ]] && echo "$image" && exit 0 + +podman build --squash -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" + +podman image list "$image" +echo +podman image tree "$image" diff --git a/misc/test-qemu-with-podman/test-qemu4-alpine/11-list-packages.sh b/misc/test-qemu-with-podman/test-qemu4-alpine/11-list-packages.sh new file mode 100755 index 00000000..58445cc0 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu4-alpine/11-list-packages.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# list all system packages that are installed in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +podman image list "$image" +echo +podman image tree "$image" + +echo 'Packages:' +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +podman run "${flags[@]}" "$image" bash -c $'apk info -v | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/misc/test-qemu-with-podman/test-qemu4-alpine/20-image-run-shell.sh b/misc/test-qemu-with-podman/test-qemu4-alpine/20-image-run-shell.sh new file mode 100755 index 00000000..1f83802d --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu4-alpine/20-image-run-shell.sh @@ -0,0 +1,37 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# run an interactive shell in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM +if [[ 1 == 1 ]]; then + # run as user upx 2000:2000 + flags+=( --user 2000 ) + # map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user + flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 ) + # map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group + flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 ) + # NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx + # INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs! + flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" ) + flags+=( -w /home/upx/src/upx ) # set working directory + flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs + flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs +else + # run as user root 0:0 + # ONLY FOR DEBUGGING THE IMAGE + # map container user/group 0 to current host user/group + flags+=( --user 0 ) +fi + +podman run "${flags[@]}" "$image" bash -l + +# please see usage instructions in ../README.md diff --git a/misc/test-qemu-with-podman/test-qemu4-alpine/Dockerfile b/misc/test-qemu-with-podman/test-qemu4-alpine/Dockerfile new file mode 100644 index 00000000..981c5aa6 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu4-alpine/Dockerfile @@ -0,0 +1,26 @@ +FROM docker.io/library/alpine:3.11 + +# install qemu 4.2.0-r0 and some utils +RUN apk update && apk upgrade && apk add \ + bash-completion \ + musl-dbg \ + qemu-aarch64 \ + qemu-arm \ + qemu-armeb \ + qemu-i386 \ + qemu-mips \ + qemu-mipsel \ + qemu-ppc \ + qemu-ppc64 \ + qemu-ppc64le \ + qemu-x86_64 \ + strace \ + && true + +# create default user upx 2000:2000 +RUN adduser upx -u 2000 -D \ + && cd /home/upx && chmod 00700 . \ + && mkdir -p .cache .local/bin src/upx \ + && chown -R upx:upx . \ + && true +USER upx diff --git a/misc/test-qemu-with-podman/test-qemu5-alpine/10-create-image.sh b/misc/test-qemu-with-podman/test-qemu5-alpine/10-create-image.sh new file mode 100755 index 00000000..7cc0c30c --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu5-alpine/10-create-image.sh @@ -0,0 +1,16 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# create the image from Dockerfile +# using a rootless Podman container + +image=upx-test-qemu5-alpine-20230708-v1 +[[ $1 == --print-image ]] && echo "$image" && exit 0 + +podman build --squash -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" + +podman image list "$image" +echo +podman image tree "$image" diff --git a/misc/test-qemu-with-podman/test-qemu5-alpine/11-list-packages.sh b/misc/test-qemu-with-podman/test-qemu5-alpine/11-list-packages.sh new file mode 100755 index 00000000..58445cc0 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu5-alpine/11-list-packages.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# list all system packages that are installed in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +podman image list "$image" +echo +podman image tree "$image" + +echo 'Packages:' +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +podman run "${flags[@]}" "$image" bash -c $'apk info -v | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/misc/test-qemu-with-podman/test-qemu5-alpine/20-image-run-shell.sh b/misc/test-qemu-with-podman/test-qemu5-alpine/20-image-run-shell.sh new file mode 100755 index 00000000..1f83802d --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu5-alpine/20-image-run-shell.sh @@ -0,0 +1,37 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# run an interactive shell in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM +if [[ 1 == 1 ]]; then + # run as user upx 2000:2000 + flags+=( --user 2000 ) + # map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user + flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 ) + # map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group + flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 ) + # NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx + # INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs! + flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" ) + flags+=( -w /home/upx/src/upx ) # set working directory + flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs + flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs +else + # run as user root 0:0 + # ONLY FOR DEBUGGING THE IMAGE + # map container user/group 0 to current host user/group + flags+=( --user 0 ) +fi + +podman run "${flags[@]}" "$image" bash -l + +# please see usage instructions in ../README.md diff --git a/misc/test-qemu-with-podman/test-qemu5-alpine/Dockerfile b/misc/test-qemu-with-podman/test-qemu5-alpine/Dockerfile new file mode 100644 index 00000000..d654b33e --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu5-alpine/Dockerfile @@ -0,0 +1,26 @@ +FROM docker.io/library/alpine:3.13 + +# install qemu 5.2.0-r3 and some utils +RUN apk update && apk upgrade && apk add \ + bash-completion \ + musl-dbg \ + qemu-aarch64 \ + qemu-arm \ + qemu-armeb \ + qemu-i386 \ + qemu-mips \ + qemu-mipsel \ + qemu-ppc \ + qemu-ppc64 \ + qemu-ppc64le \ + qemu-x86_64 \ + strace \ + && true + +# create default user upx 2000:2000 +RUN adduser upx -u 2000 -D \ + && cd /home/upx && chmod 00700 . \ + && mkdir -p .cache .local/bin src/upx \ + && chown -R upx:upx . \ + && true +USER upx diff --git a/misc/test-qemu-with-podman/test-qemu6-alpine/11-list-packages.sh b/misc/test-qemu-with-podman/test-qemu6-alpine/11-list-packages.sh new file mode 100755 index 00000000..58445cc0 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu6-alpine/11-list-packages.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# list all system packages that are installed in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +podman image list "$image" +echo +podman image tree "$image" + +echo 'Packages:' +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +podman run "${flags[@]}" "$image" bash -c $'apk info -v | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/misc/test-qemu-with-podman/test-qemu6-alpine/Dockerfile b/misc/test-qemu-with-podman/test-qemu6-alpine/Dockerfile index b9ee32a5..7e341f6a 100644 --- a/misc/test-qemu-with-podman/test-qemu6-alpine/Dockerfile +++ b/misc/test-qemu-with-podman/test-qemu6-alpine/Dockerfile @@ -3,6 +3,7 @@ FROM docker.io/library/alpine:3.15 # install qemu 6.1.1-r0 and some utils RUN apk update && apk upgrade && apk add \ bash-completion \ + musl-dbg \ qemu-aarch64 \ qemu-arm \ qemu-armeb \ @@ -13,6 +14,7 @@ RUN apk update && apk upgrade && apk add \ qemu-ppc64 \ qemu-ppc64le \ qemu-x86_64 \ + strace \ && true # create default user upx 2000:2000 diff --git a/misc/test-qemu-with-podman/test-qemu7-alpine/11-list-packages.sh b/misc/test-qemu-with-podman/test-qemu7-alpine/11-list-packages.sh new file mode 100755 index 00000000..58445cc0 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu7-alpine/11-list-packages.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# list all system packages that are installed in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +podman image list "$image" +echo +podman image tree "$image" + +echo 'Packages:' +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +podman run "${flags[@]}" "$image" bash -c $'apk info -v | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/misc/test-qemu-with-podman/test-qemu7-alpine/Dockerfile b/misc/test-qemu-with-podman/test-qemu7-alpine/Dockerfile index e97a0caf..deb1c243 100644 --- a/misc/test-qemu-with-podman/test-qemu7-alpine/Dockerfile +++ b/misc/test-qemu-with-podman/test-qemu7-alpine/Dockerfile @@ -3,6 +3,7 @@ FROM docker.io/library/alpine:3.17 # install qemu 7.1.0-r7 and some utils RUN apk update && apk upgrade && apk add \ bash-completion \ + musl-dbg \ qemu-aarch64 \ qemu-arm \ qemu-armeb \ @@ -13,6 +14,7 @@ RUN apk update && apk upgrade && apk add \ qemu-ppc64 \ qemu-ppc64le \ qemu-x86_64 \ + strace \ && true # create default user upx 2000:2000 diff --git a/misc/test-qemu-with-podman/test-qemu8-alpine/11-list-packages.sh b/misc/test-qemu-with-podman/test-qemu8-alpine/11-list-packages.sh new file mode 100755 index 00000000..58445cc0 --- /dev/null +++ b/misc/test-qemu-with-podman/test-qemu8-alpine/11-list-packages.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash +## vim:set ts=4 sw=4 et: +set -e; set -o pipefail +argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" + +# list all system packages that are installed in the image +# using a rootless Podman container + +image="$("$argv0dir/10-create-image.sh" --print-image)" + +podman image list "$image" +echo +podman image tree "$image" + +echo 'Packages:' +flags=( --read-only --rm --pull=never ) +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +podman run "${flags[@]}" "$image" bash -c $'apk info -v | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/misc/test-qemu-with-podman/test-qemu8-alpine/Dockerfile b/misc/test-qemu-with-podman/test-qemu8-alpine/Dockerfile index 72a81abd..1429fb5e 100644 --- a/misc/test-qemu-with-podman/test-qemu8-alpine/Dockerfile +++ b/misc/test-qemu-with-podman/test-qemu8-alpine/Dockerfile @@ -1,8 +1,9 @@ FROM docker.io/library/alpine:3.18 -# install qemu 8.0.2-r1 and some utils +# install qemu 8.0.3-r0 and some utils RUN apk update && apk upgrade && apk add \ bash-completion \ + musl-dbg \ qemu-aarch64 \ qemu-arm \ qemu-armeb \ @@ -13,6 +14,7 @@ RUN apk update && apk upgrade && apk add \ qemu-ppc64 \ qemu-ppc64le \ qemu-x86_64 \ + strace \ && true # create default user upx 2000:2000 diff --git a/src/Makefile b/src/Makefile index c8dc1cb4..6b1440cf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,7 +22,7 @@ endif # redirect to top-level CMake build # -# note that top-level Makefile .DEFAULT_GOAL is build/release +# NOTE that top-level Makefile .DEFAULT_GOAL is build/release .DEFAULT_GOAL = build/debug build/debug: $(top_srcdir)/build/debug/upx diff --git a/src/check/dt_check.cpp b/src/check/dt_check.cpp index 04ef8f92..366f7dba 100644 --- a/src/check/dt_check.cpp +++ b/src/check/dt_check.cpp @@ -541,18 +541,21 @@ void upx_compiler_sanity_check(void) noexcept { **************************************************************************/ TEST_CASE("assert_noexcept") { - // just to make sure that our assert macros don't generate any warnings + // just to make sure that our own assert macros don't generate any warnings byte dummy = 0; byte *ptr1 = &dummy; const byte *const ptr2 = &dummy; + void *ptr3 = nullptr; assert(true); assert(1); assert(ptr1); assert(ptr2); + assert(!ptr3); assert_noexcept(true); assert_noexcept(1); assert_noexcept(ptr1); assert_noexcept(ptr2); + assert_noexcept(!ptr3); } TEST_CASE("noncopyable") { diff --git a/src/conf.h b/src/conf.h index fb52e1e6..914d4125 100644 --- a/src/conf.h +++ b/src/conf.h @@ -317,6 +317,7 @@ typedef upx_int64_t upx_off_t; # define attribute_format(a,b) /*empty*/ #endif +// for no-op debug output inline void NO_printf(const char *, ...) attribute_format(1, 2); inline void NO_fprintf(FILE *, const char *, ...) attribute_format(2, 3); inline void NO_printf(const char *, ...) {} diff --git a/src/headers.h b/src/headers.h index c5d53954..ef750f3b 100644 --- a/src/headers.h +++ b/src/headers.h @@ -30,6 +30,7 @@ #error "C++17 is required" #endif +// sanity check #if defined(__ILP32) || defined(__ILP32__) static_assert(sizeof(int) == 4); static_assert(sizeof(long) == 4); diff --git a/src/packer.h b/src/packer.h index 074064f3..0ccd8402 100644 --- a/src/packer.h +++ b/src/packer.h @@ -288,7 +288,7 @@ protected: template static inline constexpr bool is_te16_type = is_same_any_v; template - static inline constexpr bool is_te32_type = is_same_any_v; + static inline constexpr bool is_te32_type = is_same_any_v; template static inline constexpr bool is_te64_type = is_same_any_v; diff --git a/src/util/xspan.cpp b/src/util/xspan.cpp index 32995422..108d805f 100644 --- a/src/util/xspan.cpp +++ b/src/util/xspan.cpp @@ -33,7 +33,7 @@ XSPAN_NAMESPACE_BEGIN // debugging stats struct XSpanStats { upx_std_atomic(size_t) check_range_counter; - // doctest checks will set these: + // these normally will be zero, but doctest checks will populate them upx_std_atomic(size_t) fail_nullptr; upx_std_atomic(size_t) fail_nullbase; upx_std_atomic(size_t) fail_not_same_base; @@ -70,15 +70,15 @@ void xspan_fail_range_range() { throwCantPack("xspan_check_range: pointer out of range; take care!"); } -void xspan_check_range(const void *p, const void *base, ptrdiff_t size_in_bytes) { - if very_unlikely (p == nullptr) +void xspan_check_range(const void *ptr, const void *base, ptrdiff_t size_in_bytes) { + xspan_stats.check_range_counter += 1; + if very_unlikely (ptr == nullptr) xspan_fail_range_nullptr(); if very_unlikely (base == nullptr) xspan_fail_range_nullbase(); - ptrdiff_t off = (const charptr) p - (const charptr) base; + ptrdiff_t off = (const charptr) ptr - (const charptr) base; if very_unlikely (off < 0 || off > size_in_bytes || size_in_bytes > UPX_RSIZE_MAX) xspan_fail_range_range(); - xspan_stats.check_range_counter += 1; NO_fprintf(stderr, "xspan_check_range done\n"); } diff --git a/src/util/xspan.h b/src/util/xspan.h index cf6b9813..fa891d25 100644 --- a/src/util/xspan.h +++ b/src/util/xspan.h @@ -43,7 +43,7 @@ #define XSPAN_CONFIG_ENABLE_IMPLICIT_CONVERSION 0 #endif // allow automatic conversion PtrOrSpanOrNull => PtrOrSpan => Span (with run-time checks) -// choose between compile-time safety vs. possible run-time errors +// choose between compile-time safety vs. possible run-time exceptions #ifndef XSPAN_CONFIG_ENABLE_SPAN_CONVERSION #define XSPAN_CONFIG_ENABLE_SPAN_CONVERSION 1 #endif diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index f6f63344..d846e682 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -42,13 +42,13 @@ XSPAN_NAMESPACE_BEGIN // HINT: set env-var "UPX_DEBUG_DOCTEST_DISABLE=1" for improved debugging experience -noinline void xspan_fail_nullptr(); -noinline void xspan_fail_nullbase(); -noinline void xspan_fail_not_same_base(); -noinline void xspan_fail_range_nullptr(); -noinline void xspan_fail_range_nullbase(); -noinline void xspan_fail_range_range(); -void xspan_check_range(const void *p, const void *base, ptrdiff_t size_in_bytes); +noinline void xspan_fail_nullptr(void); +noinline void xspan_fail_nullbase(void); +noinline void xspan_fail_not_same_base(void); +noinline void xspan_fail_range_nullptr(void); +noinline void xspan_fail_range_nullbase(void); +noinline void xspan_fail_range_range(void); +void xspan_check_range(const void *ptr, const void *base, ptrdiff_t size_in_bytes); // help constructor to distinguish between number of elements and bytes struct XSpanCount { diff --git a/src/util/xspan_impl_common.h b/src/util/xspan_impl_common.h index 31caa7e2..9fac0961 100644 --- a/src/util/xspan_impl_common.h +++ b/src/util/xspan_impl_common.h @@ -113,6 +113,7 @@ forceinline ~CSelf() noexcept {} #endif noinline void invalidate() { assertInvariants(); + // poison the pointer ptr = (pointer) (upx_uintptr_t) 16; // point to non-null invalid address // ptr = (pointer) (void *) &ptr; // point to self base = ptr; diff --git a/src/util/xspan_impl_ptr.h b/src/util/xspan_impl_ptr.h index ad8f63d2..6feb38cb 100644 --- a/src/util/xspan_impl_ptr.h +++ b/src/util/xspan_impl_ptr.h @@ -59,6 +59,8 @@ private: public: #if XSPAN_CONFIG_ENABLE_IMPLICIT_CONVERSION || 1 + // Ptr always provides automatic conversion to underlying type because + // it has limited functionality operator pointer() const noexcept { return ptr; } #endif @@ -75,6 +77,7 @@ public: #endif noinline void invalidate() { assertInvariants(); + // poison the pointer ptr = (pointer) (upx_uintptr_t) 16; // point to non-null invalid address // ptr = (pointer) (void *) &ptr; // point to self assertInvariants();