Skip to content
New issue

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

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

Already on GitHub? # to your account

Workaround for fusermountN #48

Merged
merged 5 commits into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@ if ! command -v apk; then
exit 1
fi

# Minimize binary size
export CFLAGS="-ffunction-sections -fdata-sections -Os"

apk update
apk add alpine-sdk util-linux strace file autoconf automake libtool
apk add alpine-sdk util-linux strace file autoconf automake libtool xz

# Build static libfuse3 with patch for https://github.com/AppImage/type2-runtime/issues/10
apk add eudev-dev gettext-dev linux-headers meson # From https://git.alpinelinux.org/aports/tree/main/fuse3/APKBUILD
wget -c -q "https://github.com/libfuse/libfuse/releases/download/fuse-3.15.0/fuse-3.15.0.tar.xz"
tar xf fuse-3.*.tar.xz
cd fuse-3.*/
patch -p1 < ../patches/libfuse/mount.c.diff
mkdir build
cd build
meson setup --prefix=/usr ..
meson configure --default-library static
ninja install
cd ../../

# Build static squashfuse
apk add fuse-dev fuse-static zstd-dev zstd-static zlib-dev zlib-static # fuse3-static fuse3-dev
apk add zstd-dev zstd-static zlib-dev zlib-static # fuse-dev fuse-static fuse3-static fuse3-dev
wget -c -q "https://github.com/vasi/squashfuse/archive/e51978c.tar.gz"
tar xf e51978c.tar.gz
cd squashfuse-*/
Expand All @@ -26,11 +42,11 @@ cd -
# Build static AppImage runtime
export GIT_COMMIT=$(cat src/runtime/version)
cd src/runtime
make runtime-fuse2 -j$(nproc)
file runtime-fuse2
strip runtime-fuse2
ls -lh runtime-fuse2
echo -ne 'AI\x02' | dd of=runtime-fuse2 bs=1 count=3 seek=8 conv=notrunc # magic bytes, always do AFTER strip
make runtime-fuse3 -j$(nproc)
file runtime-fuse3
strip runtime-fuse3
ls -lh runtime-fuse3
echo -ne 'AI\x02' | dd of=runtime-fuse3 bs=1 count=3 seek=8 conv=notrunc # magic bytes, always do AFTER strip
cd -

# Build static patchelf
Expand Down Expand Up @@ -125,7 +141,7 @@ strip bsdtar
cd -

mkdir -p out
cp src/runtime/runtime-fuse2 out/runtime-fuse2-$ARCHITECTURE
cp src/runtime/runtime-fuse3 out/runtime-fuse3-$ARCHITECTURE
cp patchelf-*/patchelf out/patchelf-$ARCHITECTURE
cp zsync-*/zsyncmake out/zsyncmake-$ARCHITECTURE
cp squashfs-tools-*/squashfs-tools/mksquashfs out/mksquashfs-$ARCHITECTURE
Expand Down
3 changes: 2 additions & 1 deletion chroot_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ cd -
#############################################

sudo cp -r ./src miniroot/src
sudo cp -r ./patches miniroot/patches

sudo mount -o bind /dev miniroot/dev
sudo mount -t proc none miniroot/proc
Expand Down Expand Up @@ -58,7 +59,7 @@ sudo umount miniroot/proc miniroot/sys miniroot/dev
if [ "$ARCHITECTURE" = "x86" ] ; then ARCHITECTURE=i686 ; fi

mkdir out/
sudo find miniroot/ -type f -executable -name 'runtime-fuse2' -exec cp {} out/runtime-fuse2-$ARCHITECTURE \;
sudo find miniroot/ -type f -executable -name 'runtime-fuse3' -exec cp {} out/runtime-fuse3-$ARCHITECTURE \;
sudo find miniroot/ -type f -executable -name 'patchelf' -exec cp {} out/patchelf-$ARCHITECTURE \;
sudo find miniroot/ -type f -executable -name 'zsyncmake' -exec cp {} out/zsyncmake-$ARCHITECTURE \;
sudo find miniroot/ -type f -executable -name 'mksquashfs' -exec cp {} out/mksquashfs-$ARCHITECTURE \;
Expand Down
130 changes: 130 additions & 0 deletions patches/libfuse/mount.c.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
diff --git a/lib/mount.c b/lib/mount.c
index d71e6fc55..acc1711ff 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -41,7 +41,6 @@
#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0)
#endif

-#define FUSERMOUNT_PROG "fusermount3"
#define FUSE_COMMFD_ENV "_FUSE_COMMFD"

#ifndef HAVE_FORK
@@ -117,17 +116,79 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_END
};

+int fileExists(const char* path);
+char* findBinaryInFusermountDir(const char* binaryName);
+
+int fileExists(const char* path) {
+ FILE* file = fopen(path, "r");
+ if (file) {
+ fclose(file);
+ return 1;
+ }
+ return 0;
+}
+
+char* findBinaryInFusermountDir(const char* binaryName) {
+ // For security reasons, we do not search the binary on the $PATH;
+ // instead, we check if the binary exists in FUSERMOUNT_DIR
+ // as defined in meson.build
+ char* binaryPath = malloc(strlen(FUSERMOUNT_DIR) + strlen(binaryName) + 2);
+ strcpy(binaryPath, FUSERMOUNT_DIR);
+ strcat(binaryPath, "/");
+ strcat(binaryPath, binaryName);
+ if (fileExists(binaryPath)) {
+ return binaryPath;
+ }
+
+ // If the binary does not exist in FUSERMOUNT_DIR, return NULL
+ return NULL;
+}
+
+static const char *fuse_mount_prog(void)
+{
+ // Check if the FUSERMOUNT_PROG environment variable is set and if so, use it
+ const char *prog = getenv("FUSERMOUNT_PROG");
+ if (prog) {
+ if (access(prog, X_OK) == 0)
+ return prog;
+ }
+
+ // Check if there is a binary "fusermount3"
+ prog = findBinaryInFusermountDir("fusermount3");
+ if (access(prog, X_OK) == 0)
+ return prog;
+
+ // Check if there is a binary called "fusermount"
+ // This is known to work for our purposes
+ prog = findBinaryInFusermountDir("fusermount");
+ if (access(prog, X_OK) == 0)
+ return prog;
+
+ // For i = 4...99, check if there is a binary called "fusermount" + i
+ // It is not yet known whether this will work for our purposes, but it is better than not even attempting
+ for (int i = 4; i < 100; i++) {
+ prog = findBinaryInFusermountDir("fusermount" + i);
+ if (access(prog, X_OK) == 0)
+ return prog;
+ }
+
+ // If all else fails, return NULL
+ return NULL;
+}
+
static void exec_fusermount(const char *argv[])
{
- execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
- execvp(FUSERMOUNT_PROG, (char **) argv);
+ const char *fusermount_prog = fuse_mount_prog();
+ if (fusermount_prog) {
+ execv(fusermount_prog, (char **) argv);
+ }
}

void fuse_mount_version(void)
{
int pid = fork();
if (!pid) {
- const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
+ const char *argv[] = { fuse_mount_prog(), "--version", NULL };
exec_fusermount(argv);
_exit(1);
} else if (pid != -1)
@@ -300,7 +361,7 @@ void fuse_kern_unmount(const char *mountpoint, int fd)
return;

if(pid == 0) {
- const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z",
+ const char *argv[] = { fuse_mount_prog(), "-u", "-q", "-z",
"--", mountpoint, NULL };

exec_fusermount(argv);
@@ -346,7 +407,7 @@ static int setup_auto_unmount(const char *mountpoint, int quiet)
}
}

- argv[a++] = FUSERMOUNT_PROG;
+ argv[a++] = fuse_mount_prog();
argv[a++] = "--auto-unmount";
argv[a++] = "--";
argv[a++] = mountpoint;
@@ -407,7 +468,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
}
}

- argv[a++] = FUSERMOUNT_PROG;
+ argv[a++] = fuse_mount_prog();
if (opts) {
argv[a++] = "-o";
argv[a++] = opts;
@@ -421,7 +482,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
snprintf(env, sizeof(env), "%i", fds[0]);
setenv(FUSE_COMMFD_ENV, env, 1);
exec_fusermount(argv);
- perror("fuse: failed to exec fusermount3");
+ perror("fuse: failed to exec fusermount");
_exit(1);
}
Loading