mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-08 15:41:15 +02:00
* ci: move the fusermount3 repair into a composite action Three copies of the same block were already drifting apart, and the target comes from PATH: only ever add setuid root to a root-owned, non-symlink binary under the system bin paths, and say why otherwise. * test: say that the process exited in the wait errors "process exit status 1 before ... accepted connections" is missing its verb. Also mark the SIGTERM return discarded - it fails with os.ErrProcessDone exactly when the select below already handles it. * ci: prefer the distro fusermount3 over escalating a shadow copy The shadowing /usr/local/bin/fusermount3 is not root-owned either, so setting its setuid bit would have handed root to a binary the runner user owns - the repair now symlinks the distro one earlier in PATH and touches nothing, keeping the in-place chmod for a root-owned binary with no distro alternative. A setuid bit only grants root when root owns the file, so accept an existing one only then. * ci: run the FUSE workflows when the shared action changes Their paths filters listed each workflow file but not the composite action all three now call.
67 lines
2.6 KiB
YAML
67 lines
2.6 KiB
YAML
name: Fix fusermount3 setuid
|
|
description: >
|
|
Make sure the fusermount3 an unprivileged mount will find can actually mount.
|
|
Some runner images carry a second, source-built fusermount3 in /usr/local/bin
|
|
that shadows the distro one in PATH; it is neither setuid nor root-owned, so
|
|
every mount fails with "mount failed: Operation not permitted". Both the Go
|
|
mount and sw-fuse resolve the helper through PATH.
|
|
Run it after the step that apt-installs fuse3.
|
|
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- name: Point PATH at a fusermount3 that can mount
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
# setuid only grants root when root owns the file, and exec follows
|
|
# symlinks, so judge the target.
|
|
can_mount() {
|
|
[ -u "$1" ] && [ "$(stat -Lc %u "$1")" = 0 ]
|
|
}
|
|
|
|
bin=$(command -v fusermount3 || true)
|
|
if [ -z "$bin" ]; then
|
|
echo "no fusermount3 in PATH" >&2
|
|
exit 1
|
|
fi
|
|
if can_mount "$bin"; then
|
|
ls -l "$bin"
|
|
exit 0
|
|
fi
|
|
echo "$bin cannot mount unprivileged:"
|
|
ls -l "$bin"
|
|
|
|
# The distro fusermount3 is setuid root and is the one meant to be used.
|
|
# Reach it through a symlink earlier in PATH: exec resolves the link, so
|
|
# the target keeps its setuid bit, and nothing on the image is modified.
|
|
for distro in /usr/bin/fusermount3 /bin/fusermount3; do
|
|
if [ "$distro" != "$bin" ] && can_mount "$distro"; then
|
|
mkdir -p "$RUNNER_TEMP/fuse-bin"
|
|
ln -sf "$distro" "$RUNNER_TEMP/fuse-bin/fusermount3"
|
|
echo "$RUNNER_TEMP/fuse-bin" >> "$GITHUB_PATH"
|
|
echo "using $distro instead"
|
|
ls -l "$distro"
|
|
exit 0
|
|
fi
|
|
done
|
|
|
|
# No usable distro binary, so setting the bit is the only way out - but
|
|
# the target came from PATH: do that only for a root-owned system binary,
|
|
# never for anything else that happens to sit there.
|
|
case "$bin" in
|
|
/bin/*|/sbin/*|/usr/bin/*|/usr/sbin/*|/usr/local/bin/*|/usr/local/sbin/*) ;;
|
|
*) echo "refusing to setuid $bin: outside the system bin paths" >&2; exit 1 ;;
|
|
esac
|
|
if [ -L "$bin" ] || [ ! -f "$bin" ] || [ ! -x "$bin" ]; then
|
|
echo "refusing to setuid $bin: not a regular executable file" >&2
|
|
exit 1
|
|
fi
|
|
if [ "$(stat -c %u "$bin")" != 0 ] || [ "$(stat -c %g "$bin")" != 0 ]; then
|
|
echo "refusing to setuid $bin: not owned by root:root" >&2
|
|
exit 1
|
|
fi
|
|
sudo chmod u+s "$bin"
|
|
ls -l "$bin"
|