add self-escalation in appimage, prefering pkexec, sudo as backup#315
Conversation
|
so im wondering why it has to be self-escalation and not just normally escalating the python script similar to PINCE.sh |
|
So from my findings, the reason why that perm broken folder is like that is because it's created with root privileges. For some reason it doesn't behave like the other folders where you can still see the perms, but they correctly show up once you do a Having said that, I'd still prefer to see if there's a way for us to avoid double mounting the same AppImage, so I was thinking if we should modify AppRun to be a simple privilege escalation script and store the main runner in another AppRun-like script. |
9520fbd to
89f1856
Compare
trying if [ "$(id -u)" != "0" ]; then
if type pkexec &> /dev/null; then
# Preserve env vars to keep settings like theme preferences.
# Pkexec does not support passing all of env via a flag like `-E` so we need to
# rebuild the env and then pass it through.
ENV=()
while IFS= read -r line
do
ENV+=("$line")
done < <(printenv)
pkexec env "${ENV[@]}" $APPDIR/usr/bin/python3 $APPDIR/opt/PINCE/PINCE.py
elif type sudo &> /dev/null; then
# Debian/Ubuntu does not preserve PATH through sudo even with -E for security reasons
# so we need to force PATH preservation with venv activated user's PATH.
sudo -E --preserve-env=PATH PYTHONDONTWRITEBYTECODE=1 $APPDIR/usr/bin/python3 $APPDIR/opt/PINCE/PINCE.py
else
echo "No supported privilege escalation utility found. Please run this as root manually."
exit 1
fi
exit
figives the error |
so A.sh will self escalate itself, running smth like sudo A.sh which will then run B.sh which runs the python script? |
|
Seems that FUSE completely prevents running anything from the tmp mount as root then, but it's weird how you can call the AppImage itself as root. I suppose FUSE doesn't prevent the script itself running an external file as root but just the internal files are prevented. |
or just have A.sh (escalation script) that does sudo B.sh (the python exec script), that would be simpler |
89f1856 to
f9f21c5
Compare
f9f21c5 to
6b16350
Compare
|
is it because the shell script is mounted within the noexec FUSE fs? |
|
Hmm, maybe if the shell script creates it directly outside on the fly? |
|
Any new updates on this? |
|
i have not yet looked at how other projects escalate their appimage |
|
Cool, just wanted to know if you did anything about this in private before trying to crack at it for a few hours. I'm waiting on this PR to be finished before I tag 0.5 and release a new AppImage. |
nope, go right ahead |
|
So the main issue is that unless FUSE mounting options are changed from user-side, not only you're not allowed to run things as root inside but root user won't see the files inside at all. A very bruteforce-y way is to just temporarily copy the inside of AppImage mounted folder and then run it from outside. This is effectively the same as running the AppImage from itself and even though doing that seems iffy, it would probably be more preferable than doing this, because AFAIK, FUSE mounting shouldn't occupy space so all 800 megs of our AppImage is not duplicated onto the /tmp folder, but this copy way would and that would not be preferable to the user. You can find below a working patch with the "copy insides to outside" method. diff --git a/ci/package.sh b/ci/package.sh
index b910377..15ee0bf 100755
--- a/ci/package.sh
+++ b/ci/package.sh
@@ -176,19 +176,50 @@ EOF
# Placeholder icon for above desktop file
touch AppDir/usr/share/icons/hicolor/scalable/apps/PINCE.svg
-# Create main running script
+# Create AppImage setup and self-escalation script
cat > AppRun.sh <<\EOF
#!/bin/bash
+export APPDIR="$(dirname "$0")"
if [ "$(id -u)" != "0" ]; then
- echo "Please run this AppImage using 'sudo -E'!"
- exit 1
+ export TEMP_APPDIR=/tmp/PINCE-AppImg
+ mkdir -p $TEMP_APPDIR
+ cp -r $APPDIR/opt $TEMP_APPDIR/
+ cp -r $APPDIR/usr $TEMP_APPDIR/
+ export APPDIR=$TEMP_APPDIR
+
+ if type pkexec &> /dev/null; then
+ # Preserve env vars to keep settings like theme preferences.
+ # Pkexec does not support passing all of env via a flag like `-E` so we need to
+ # rebuild the env and then pass it through.
+ ENV=()
+ while IFS= read -r line
+ do
+ ENV+=("$line")
+ done < <(printenv)
+
+ pkexec env "${ENV[@]}" $APPDIR/opt/PINCERun.sh
+ elif type sudo &> /dev/null; then
+ # Debian/Ubuntu does not preserve PATH through sudo even with -E for security reasons
+ # so we need to force PATH preservation with venv activated user's PATH.
+ sudo -E --preserve-env=PATH PYTHONDONTWRITEBYTECODE=1 $APPDIR/opt/PINCERun.sh
+ else
+ echo "No supported privilege escalation utility found. Please run this as root manually."
+ exit 1
+ fi
+ exit
fi
-export APPDIR="$(dirname "$0")"
-export PYTHONHOME=$APPDIR/usr/conda
-$APPDIR/usr/bin/python3 $APPDIR/opt/PINCE/PINCE.py
+$APPDIR/opt/PINCERun.sh
EOF
chmod +x AppRun.sh
+# Create main running script
+cat > AppDir/opt/PINCERun.sh <<\EOoF
+export PYTHONHOME=$APPDIR/usr/conda
+$APPDIR/usr/bin/python3 $APPDIR/opt/PINCE/PINCE.py
+rm -rf $TEMP_APPDIR
+EOoF
+chmod +x AppDir/opt/PINCERun.sh
+
# Patch libqxcb's runpath (not rpath) to point to our packaged libxcb-cursor to fix X11 issues
patchelf --add-rpath "\$ORIGIN/../../../../../../" AppDir/usr/conda/lib/python3.13/site-packages/PyQt6/Qt6/plugins/platforms/libqxcb.so
I think the only lead that remains to chase starting from this code is to temporarily copy only the required files to kickstart the process. Sadly trying to do this was unsuccessful as Python keeps complaining about missing modules even if I'll have to look into this more but feel free to try this idea yourself too if you want. |
|
Nah, I give up. Life is too short and my hatred for Python too high for me to waste time trying to do this and then fix edge case after edge case. Feel free to update the PR with your |
same here bud 💀, you know its bad when collaborators of a python project even hate python |
6b16350 to
f587563
Compare
|
that should be the same $appimage approach from before |
|
/ranton Python IMO is one of the biggest dogshit languages when it comes to actually making a program larger than a small script and especially when it comes to publishing/packaging. So many packaging issues and even normal issues would've been fixed if we could've compiled the code and then ship with either statically linked libraries or just dynamic targeting specific base versions. You have no idea how many times I wanted to rewrite this in another language. PS: pip should be nuked off of this universe. /rantoff |
f587563 to
31bcd83
Compare
|
personally my biggest gripe with python is how shitty the tooling is, you cant use pip without doing 20 steps. i also really really love how it handles versions, making it impossible to use any dependencies even though python is touted as having the best ecosystem. for the love of god python needs to take after the go ecosystem: all you need is a pr works for me, hopefully you can double check it |
|
Works for me, thanks for the PR. "Python is touted as having the best ecosystem", whoever said that line needs to be checked. 🫡 |

No description provided.