From 2adeba20d4180284e647ac2d0a06aec9caf8d256 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:19:28 +0300 Subject: [PATCH 01/10] Add statix patch to disable getpwnam & getgrnam --- scripts/staticx_patch.diff | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 scripts/staticx_patch.diff diff --git a/scripts/staticx_patch.diff b/scripts/staticx_patch.diff new file mode 100644 index 000000000..6ac46fa0f --- /dev/null +++ b/scripts/staticx_patch.diff @@ -0,0 +1,30 @@ +diff --git a/libtar/decode.c b/libtar/decode.c +index b34b1d9..5105cb0 100644 +--- a/libtar/decode.c ++++ b/libtar/decode.c +@@ -46,9 +46,9 @@ th_get_uid(const TAR *t) + int uid; + struct passwd *pw; + +- pw = getpwnam(t->th_buf.uname); +- if (pw != NULL) +- return pw->pw_uid; ++ // pw = getpwnam(t->th_buf.uname); ++ // if (pw != NULL) ++ // return pw->pw_uid; + + /* if the password entry doesn't exist */ + sscanf(t->th_buf.uid, "%o", &uid); +@@ -62,9 +62,9 @@ th_get_gid(const TAR *t) + int gid; + struct group *gr; + +- gr = getgrnam(t->th_buf.gname); +- if (gr != NULL) +- return gr->gr_gid; ++ // gr = getgrnam(t->th_buf.gname); ++ // if (gr != NULL) ++ // return gr->gr_gid; + + /* if the group entry doesn't exist */ + sscanf(t->th_buf.gid, "%o", &gid); From 77f4d4ce7ff1616ac5b35f2c16f311745bea7867 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:35:21 +0300 Subject: [PATCH 02/10] Upgrade staticx to 0.13.6 --- exe-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exe-requirements.txt b/exe-requirements.txt index 9b4e0b87d..6b7562d92 100644 --- a/exe-requirements.txt +++ b/exe-requirements.txt @@ -3,4 +3,4 @@ pyinstaller==4.0; platform.machine == "x86_64" # aarch64 requires a later version due to the use of a newer centos version. # see https://github.com/pyinstaller/pyinstaller/issues/5540 pyinstaller==4.10; platform.machine == "aarch64" -staticx==0.12.1 +staticx==0.13.6 From e9126594b80b36e9d496f3744fe2a35251ae27d4 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:35:53 +0300 Subject: [PATCH 03/10] scripts: list_needed_libs.sh: Make sure to print each lib once, new staticx doesn't like multiple times --- scripts/list_needed_libs.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/list_needed_libs.sh b/scripts/list_needed_libs.sh index ad82daee2..d5f6282ca 100755 --- a/scripts/list_needed_libs.sh +++ b/scripts/list_needed_libs.sh @@ -1,9 +1,10 @@ + #!/usr/bin/env bash # # Copyright (c) Granulate. All rights reserved. # Licensed under the AGPL3 License. See LICENSE.md in the project root for license information. # -set -e +set -euo pipefail # this file lists all dynamic dependenices of executables in gprofiler/resources. # we use it to let staticx know which libraries it should pack inside. @@ -40,7 +41,11 @@ for f in $BINS ; do fi done +printed= for l in $libs ; do - >&2 echo "found needed lib: $l" - echo -n " -l $l" + if ! echo "$printed" | grep -q "$l"; then + >&2 echo "found needed lib: $l" + echo -n " -l $l" + printed="$printed $l" + fi done From 4f6b5f1f99a8de723ec246b02ce2303237298b2d Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:36:03 +0300 Subject: [PATCH 04/10] fixup! Add statix patch to disable getpwnam & getgrnam --- scripts/staticx_patch.diff | 48 ++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/scripts/staticx_patch.diff b/scripts/staticx_patch.diff index 6ac46fa0f..7a57167a6 100644 --- a/scripts/staticx_patch.diff +++ b/scripts/staticx_patch.diff @@ -1,30 +1,28 @@ diff --git a/libtar/decode.c b/libtar/decode.c -index b34b1d9..5105cb0 100644 +index b34b1d9..d221c3a 100644 --- a/libtar/decode.c +++ b/libtar/decode.c -@@ -46,9 +46,9 @@ th_get_uid(const TAR *t) - int uid; - struct passwd *pw; +@@ -44,11 +44,6 @@ uid_t + th_get_uid(const TAR *t) + { + int uid; +- struct passwd *pw; +- +- pw = getpwnam(t->th_buf.uname); +- if (pw != NULL) +- return pw->pw_uid; -- pw = getpwnam(t->th_buf.uname); -- if (pw != NULL) -- return pw->pw_uid; -+ // pw = getpwnam(t->th_buf.uname); -+ // if (pw != NULL) -+ // return pw->pw_uid; + /* if the password entry doesn't exist */ + sscanf(t->th_buf.uid, "%o", &uid); +@@ -60,11 +55,6 @@ gid_t + th_get_gid(const TAR *t) + { + int gid; +- struct group *gr; +- +- gr = getgrnam(t->th_buf.gname); +- if (gr != NULL) +- return gr->gr_gid; - /* if the password entry doesn't exist */ - sscanf(t->th_buf.uid, "%o", &uid); -@@ -62,9 +62,9 @@ th_get_gid(const TAR *t) - int gid; - struct group *gr; - -- gr = getgrnam(t->th_buf.gname); -- if (gr != NULL) -- return gr->gr_gid; -+ // gr = getgrnam(t->th_buf.gname); -+ // if (gr != NULL) -+ // return gr->gr_gid; - - /* if the group entry doesn't exist */ - sscanf(t->th_buf.gid, "%o", &gid); + /* if the group entry doesn't exist */ + sscanf(t->th_buf.gid, "%o", &gid); From ca0a785f8380f315722c0c84d1265da9c8f207b1 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:41:43 +0300 Subject: [PATCH 05/10] Install staticx from pypi only for x86_64 --- exe-requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exe-requirements.txt b/exe-requirements.txt index 6b7562d92..e9b0943ef 100644 --- a/exe-requirements.txt +++ b/exe-requirements.txt @@ -3,4 +3,5 @@ pyinstaller==4.0; platform.machine == "x86_64" # aarch64 requires a later version due to the use of a newer centos version. # see https://github.com/pyinstaller/pyinstaller/issues/5540 pyinstaller==4.10; platform.machine == "aarch64" -staticx==0.13.6 +# for aarch64 we build a slightly patched version +staticx==0.13.6; platform.machine == "x86_64" From 0a61d1b961b123a637d8e645dcdb1a219070f29f Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:42:05 +0300 Subject: [PATCH 06/10] Build patched staticx for aarch64 --- pyi.Dockerfile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyi.Dockerfile b/pyi.Dockerfile index 8f855fe7f..c3273376e 100644 --- a/pyi.Dockerfile +++ b/pyi.Dockerfile @@ -204,6 +204,15 @@ RUN pyinstaller pyinstaller.spec \ && test -f build/pyinstaller/warn-pyinstaller.txt \ && if grep 'gprofiler\.' build/pyinstaller/warn-pyinstaller.txt ; then echo 'PyInstaller failed to pack gProfiler code! See lines above. Make sure to check for SyntaxError as this is often the reason.'; exit 1; fi; +COPY scripts/staticx_patch.diff staticx_patch.diff +RUN if [ $(uname -m) = "aarch64" ]; then \ + git clone -b v0.13.6 https://github.com/JonathonReinhart/staticx.git && \ + cd staticx && \ + git reset --hard 819d8eafecbaab3646f70dfb1e3e19f6bbc017f8 && \ + git apply staticx_patch.diff && \ + python3 -m pip install . ; \ + fi + COPY ./scripts/list_needed_libs.sh ./scripts/list_needed_libs.sh # staticx packs dynamically linked app with all of their dependencies, it tries to figure out which dynamic libraries are need for its execution # in some cases, when the application is lazily loading some DSOs, staticx doesn't handle it. From c0eab538add4343c7e2571f82545ff0c6b9d5f2a Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:42:57 +0300 Subject: [PATCH 07/10] Use staticx on aarch64 --- pyi.Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyi.Dockerfile b/pyi.Dockerfile index c3273376e..add2a9982 100644 --- a/pyi.Dockerfile +++ b/pyi.Dockerfile @@ -219,8 +219,7 @@ COPY ./scripts/list_needed_libs.sh ./scripts/list_needed_libs.sh # we use list_needed_libs.sh to list the dynamic dependencies of *all* of our resources, # and make staticx pack them as well. # using scl here to get the proper LD_LIBRARY_PATH set -# TODO: use staticx for aarch64 as well; currently it doesn't generate correct binaries when run over Docker emulation. -RUN if [ $(uname -m) != "aarch64" ]; then source scl_source enable devtoolset-8 llvm-toolset-7 && libs=$(./scripts/list_needed_libs.sh) && staticx $libs dist/gprofiler dist/gprofiler; fi +RUN if [ $(uname -m) != "aarch64" ]; then source scl_source enable devtoolset-8 llvm-toolset-7 ; fi; libs=$(./scripts/list_needed_libs.sh) && staticx $libs dist/gprofiler dist/gprofiler FROM scratch AS export-stage From dd6c3747db613c5c50e675eb935f899e91b185f4 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:46:25 +0300 Subject: [PATCH 08/10] Add comment --- pyi.Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyi.Dockerfile b/pyi.Dockerfile index add2a9982..a8e74624f 100644 --- a/pyi.Dockerfile +++ b/pyi.Dockerfile @@ -204,6 +204,8 @@ RUN pyinstaller pyinstaller.spec \ && test -f build/pyinstaller/warn-pyinstaller.txt \ && if grep 'gprofiler\.' build/pyinstaller/warn-pyinstaller.txt ; then echo 'PyInstaller failed to pack gProfiler code! See lines above. Make sure to check for SyntaxError as this is often the reason.'; exit 1; fi; +# for aarch64 - build a patched version of staticx 0.13.6. we remove calls to getpwnam and getgrnam, for these end up doing dlopen()s which +# crash the staticx bootloader. we don't need them anyway (all files in our staticx tar are uid 0 and we don't need the names translation) COPY scripts/staticx_patch.diff staticx_patch.diff RUN if [ $(uname -m) = "aarch64" ]; then \ git clone -b v0.13.6 https://github.com/JonathonReinhart/staticx.git && \ From 604a2c5132d198873e7bdf4118c1f5f27db701e0 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 02:47:43 +0300 Subject: [PATCH 09/10] fix path --- pyi.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyi.Dockerfile b/pyi.Dockerfile index a8e74624f..f5f76ca84 100644 --- a/pyi.Dockerfile +++ b/pyi.Dockerfile @@ -211,7 +211,7 @@ RUN if [ $(uname -m) = "aarch64" ]; then \ git clone -b v0.13.6 https://github.com/JonathonReinhart/staticx.git && \ cd staticx && \ git reset --hard 819d8eafecbaab3646f70dfb1e3e19f6bbc017f8 && \ - git apply staticx_patch.diff && \ + git apply ../staticx_patch.diff && \ python3 -m pip install . ; \ fi From cadde71480b6950d0b2984e3f25842c53b3c8a1a Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 1 May 2022 17:37:49 +0300 Subject: [PATCH 10/10] Downgrade staticx 0.12.1 for x86_64 --- exe-requirements.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/exe-requirements.txt b/exe-requirements.txt index e9b0943ef..af9286b5c 100644 --- a/exe-requirements.txt +++ b/exe-requirements.txt @@ -4,4 +4,10 @@ pyinstaller==4.0; platform.machine == "x86_64" # see https://github.com/pyinstaller/pyinstaller/issues/5540 pyinstaller==4.10; platform.machine == "aarch64" # for aarch64 we build a slightly patched version -staticx==0.13.6; platform.machine == "x86_64" +# I tried upgrading to 0.13.6 but it crashes when the botoloader is run as non-root :/ +# I got this error in gdb: +# (gdb) run +# Starting program: /path/to/build/x86_64/gprofiler +# During startup program terminated with signal SIGSEGV, Segmentation fault. +# staying with 0.12.1 for the mean time... +staticx==0.12.1; platform.machine == "x86_64"