Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setcap is broken once packaged to appimage #881

Closed
duchy opened this issue Nov 12, 2018 · 8 comments
Closed

setcap is broken once packaged to appimage #881

duchy opened this issue Nov 12, 2018 · 8 comments

Comments

@duchy
Copy link

duchy commented Nov 12, 2018

setcap cap-sys-nice+ep
With above command, capibility can be set, but takes no effect.
I tried but failed when set a thread with realtime priority in the program packaged into a appimage file on ubuntu 16.04

@probonopd
Copy link
Member

Please paste the exact commands here.

@TheAssassin
Copy link
Member

@duchy that might be a limitation because the AppImage is mounted using FUSE. Such filesystems are limited, e.g., permission wise (setuid bit cannot be used for instance).

You really must provide more information, otherwise we cannot help you even if we wanted to.

@probonopd
Copy link
Member

AppImages are read-only, you cannot change their contents or change their contents' capabilities.

@duchy
Copy link
Author

duchy commented Nov 28, 2018

@TheAssassin I think you are right. It is not supported as the FUSE being used in AppImages.

The program I wrote will require some capabilities, e.g. realtime priority or access raw net packets.
But it can not be configured with "setcap" command for such kinds capabilities for AppImages.
setcap cap_net_raw+eip <*.AppImage>
The above command will take no effect.

@probonopd Do you guys have any suggestion/workarounds on this issue?

@TheAssassin
Copy link
Member

All this is disabled for security reasons, squashfs also strips out anything that might be exploited (like setuid bits, etc.).

Your app might just (re-run) itself using root through some tool like gksudo or, even better, pkexec as a workaround.

@probonopd
Copy link
Member

Check what the Etcher AppImage is to get root rights. It "just works" regarding permissions.

@phil294
Copy link

phil294 commented Apr 1, 2023

AppImages are read-only, you cannot change their contents or change their contents' capabilities.

That makes sense, but can you not just copy the relevant files out to $HOME, set capabilities and run it from there?

Since I need this functionality as well, I set out to try to answer this question myself today and built a linuxdeploy plugin that replaces all binaries with bash script wrappers: They copy the original binary over to ~/.cache/appname/AppImage/usr/bin/, link $APPIMAGE/usr/share and local to ~/.cache/appname/AppImage/usr/, run pkexec setcap "cap_dac_override=+p" original_binary (if changed) and run original_binary.

# assuming BINCACHE_BIN_TARGET_FOLDER='$HOME/.cache/appname/AppImage'

pushd "$APPDIR"
# Wrap all binaries
for bin in usr/bin/*; do
    cp "$bin" "${bin}_bincache_"
    cat > "$bin" <<EOF
#!/usr/bin/env bash
set -e

mkdir -p "$BINCACHE_BIN_TARGET_FOLDER/usr/bin"

bin_path="\$APPDIR/$bin"
bin_name="$(basename "$bin")"
source="\${bin_path}_bincache_"
dest="$BINCACHE_BIN_TARGET_FOLDER/usr/bin/\$bin_name"
# Update cache if changed
if ! time cmp --silent -- "\$source" "\$dest"; then
    echo 'bincache: Caching new version' >&2
    time cp "\$source" "\$dest"
    # setcap: Here somewhere (I did it in the binary itself & restart itself)
fi

ln -sf "\$APPDIR/usr/lib" "$BINCACHE_BIN_TARGET_FOLDER/usr/lib"
ln -sf "\$APPDIR/usr/share" "$BINCACHE_BIN_TARGET_FOLDER/usr/share"

"\$dest" "\$@"
EOF

This all works great except once setcap ran, the original binary doesn't start anymore as Linux disables LD_LIBRARY_PATH once you set custom capabilities. https://stackoverflow.com/q/9843178 I had to learn this the hard way - and since AppImage heavily relies on LD_LIBRARY_PATH, it seems to be entirely impossible to combine AppImage + setcap on any of its contents, in any way.

Maybe I'm wrong though and it may be possible some way?

It's unfortunate because I'm building an app that relies on reading from /dev/input/event* and want to avoid asking the users to run as root or add themselves to the input group. I also can't take Etcher's route (ask the user for PW for each admin action) because I need it in the background, all the time. CAP_DAC_OVERRIDE would solve this nicely, especially given how the program could activate it for opening up FDs and then irrevocably disable the capability for the remaining lifetime of the process. Looks like I'll have to dump it and go the input group route anyway.

@VakarisZ
Copy link

I know this is an old issue, but it's the #1 search result for capabilities not working on AppImage. I found a workaround I'd like to share.
In AppRun file we did

# Save HOME and USER because capsh changes them. Until ubuntu adds --noenv option we have to rely on a workaround
export home_saved=$HOME
export user_saved=$USER

export PYTHONNOUSERSITE=1

(PYTHONHOME="${APPDIR}/opt/python3.11" exec sudo capsh --keep=1 --user=${user_saved} --inh=cap_net_bind_service --addamb=cap_net_bind_service -- -c "env HOME=${home_saved} USER=${user_saved} ${APPDIR}/opt/python3.11/bin/python3.11 ${APPDIR}/usr/src/monkey_island.py" $@)

Ambient capabilities seem to work on the AppImage, we used that as a workaround

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants