From 2c60a2c2b503d981535008d3a4cfdc41fdeb12e0 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 24 Sep 2026 10:09:33 +0800 Subject: [PATCH] fix(appimage): build AppRun with bounded argument splitting AppRun v2.0.0, which appimage-builder downloads, copies each argument into a 1 KiB stack buffer in apprun_shell_split_arguments, so any argument of 1024 bytes or more aborts the AppImage with "buffer overflow detected" before RustDesk starts (e.g. --connect with a 10000-char id). Build AppRun from the v2.0.0 commit with a patch that sizes the buffer from the input and stops the quote/escape scanning at the terminating NUL, in ubuntu:16.04 like upstream's release, and put it where appimage-builder looks before downloading. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/flutter-build.yml | 1 + appimage/apprun-split-arguments.patch | 55 +++++++++++++++++++++++++++ appimage/build-apprun.sh | 32 ++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 appimage/apprun-split-arguments.patch create mode 100755 appimage/build-apprun.sh diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index 4199ae201..8c71645bf 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -2444,6 +2444,7 @@ jobs: sudo pip3 install git+https://github.com/rustdesk-org/appimage-builder.git # run appimage-builder pushd appimage + ./build-apprun.sh ${{ matrix.job.arch }} sudo appimage-builder --skip-tests --recipe ./AppImageBuilder-${{ matrix.job.arch }}.yml - name: Publish appimage package diff --git a/appimage/apprun-split-arguments.patch b/appimage/apprun-split-arguments.patch new file mode 100644 index 000000000..b1855bbc2 --- /dev/null +++ b/appimage/apprun-split-arguments.patch @@ -0,0 +1,55 @@ +--- a/src/common/shell_utils.c ++++ b/src/common/shell_utils.c +@@ -201,7 +201,8 @@ + + const char *begin = str; + const char *end = str; +- char buffer[1024] = {0x0}; ++ size_t buffer_size = strlen(str) + 1; ++ char *buffer = calloc(buffer_size, sizeof(char)); + + while (*begin != '\0') { + begin = apprun_string_consume_spaces(begin); +@@ -209,7 +210,7 @@ + + if (*begin == '\\') { + strncat(buffer, begin + 1, 1); +- end = begin + 2; ++ end = begin[1] != '\0' ? begin + 2 : begin + 1; + consumed = true; + } + +@@ -218,7 +219,8 @@ + strncat(buffer, begin + 1, end - begin - 1); + consumed = true; + +- end++; ++ if (*end != '\0') ++ end++; + } + + if (!consumed && *begin == '\"') { +@@ -226,7 +228,8 @@ + strncat(buffer, begin + 1, end - begin - 1); + consumed = true; + +- end++; ++ if (*end != '\0') ++ end++; + } + + if (!consumed && *begin != '\'' && *begin != '\"' && *begin != '\\') { +@@ -240,11 +243,12 @@ + split_count++; + } + +- memset(buffer, 0, 1024); ++ memset(buffer, 0, buffer_size); + } + + begin = end; + } + ++ free(buffer); + return splits; + } diff --git a/appimage/build-apprun.sh b/appimage/build-apprun.sh new file mode 100755 index 000000000..e9c4d0e8e --- /dev/null +++ b/appimage/build-apprun.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# AppRun v2.0.0, which appimage-builder downloads, splits every argument into a 1 KiB stack +# buffer, so any argument of 1024 bytes or more aborts the AppImage before RustDesk starts. +# Build it with apprun-split-arguments.patch into the path appimage-builder checks before +# downloading. ubuntu:16.04 is what upstream released from, so the host glibc floor is unchanged. +set -euo pipefail + +arch=$1 +version=v2.0.0 +commit=407700ccef58e1a64cc49856074aee4b1c75d599 +here=$(cd "$(dirname "$0")" && pwd) + +case $arch in + x86_64) packages="cmake make g++" ;; + aarch64) packages="cmake make g++ g++-aarch64-linux-gnu" ;; + *) echo "Unsupported arch: $arch" >&2; exit 1 ;; +esac + +src=$(mktemp -d) +curl -fsSL "https://github.com/AppImageCrafters/AppRun/archive/$commit.tar.gz" | tar -xz -C "$src" --strip-components=1 +patch -d "$src" -p1 < "$here/apprun-split-arguments.patch" + +docker run --rm -v "$src:/src" -w /src -e DEBIAN_FRONTEND=noninteractive ubuntu:16.04 bash -c " + set -e + apt-get update + apt-get install -y --no-install-recommends $packages + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../cmake/$arch-toolchain.cmake + cmake --build . --target AppRun" + +mkdir -p "$here/appimage-build/AppRun/$version" +cp "$src/build/src/apprun/AppRun" "$here/appimage-build/AppRun/$version/AppRun-Release-$arch"