diff --git a/patches/libfuse/mount.c.diff b/patches/libfuse/mount.c.diff index 0dfa9cf..8308f87 100644 --- a/patches/libfuse/mount.c.diff +++ b/patches/libfuse/mount.c.diff @@ -1,5 +1,5 @@ diff --git a/lib/mount.c b/lib/mount.c -index d71e6fc55..acc1711ff 100644 +index d71e6fc..0e35652 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -41,7 +41,6 @@ @@ -10,78 +10,54 @@ index d71e6fc55..acc1711ff 100644 #define FUSE_COMMFD_ENV "_FUSE_COMMFD" #ifndef HAVE_FORK -@@ -117,17 +116,79 @@ static const struct fuse_opt fuse_mount_opts[] = { +@@ -117,17 +116,55 @@ 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; -+ } ++static void try_fusermount(char *binary_name, const char *argv[], int errnos[2]) ++{ ++ // +1 for the '/' and +1 for the terminating null byte ++ static size_t dir_len = strlen(FUSERMOUNT_DIR) + 2; ++ size_t full_path_len = dir_len + strlen(binary_name); ++ char full_path[full_path_len]; + -+ // If the binary does not exist in FUSERMOUNT_DIR, return NULL -+ return NULL; ++ snprintf(full_path, full_path_len, "%s/%s", FUSERMOUNT_DIR, binary_name); ++ argv[0] = binary_name; ++ errnos[0] = (execv(full_path, (char **) argv), errno); ++ errnos[1] = (execvp(binary_name, (char **) argv), errno); +} + -+static const char *fuse_mount_prog(void) ++static void print_errno(char *binary_name, int errnos[2]) +{ -+ // 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; ++ fprintf(stderr, "\t"FUSERMOUNT_DIR "/%s : %s\n", binary_name, strerror(errnos[0])); ++ fprintf(stderr, "\t%s : %s\n", binary_name, strerror(errnos[1])); +} + 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); ++ int errnos[97 * 2]; ++ char binary_name[] = "fusermount\0\0"; ++ char *binary_number = &binary_name[10]; ++ ++ try_fusermount(binary_name, argv, &errnos[0]); ++ for (unsigned int i = 3; i <= 99; i++) { ++ snprintf(binary_number, 3, "%u", i); ++ try_fusermount(binary_name, argv, &errnos[(i - 2) * 2]); ++ } ++ ++ fprintf(stderr, "fuse: failed to exec fusermount, tried the following:\n"); ++ memset(binary_number, 0, 2); ++ print_errno(binary_name, &errnos[0]); ++ for (unsigned int i = 3; i <= 99; i++) { ++ snprintf(binary_number, 3, "%u", i); ++ print_errno(binary_name, &errnos[(i - 2) * 2]); + } ++ fprintf(stderr, ++ "If you think this is an error, please report the issue to the AppImage" ++ " runtime developpers at https://github.com/AppImage/type2-runtime" ++ " along with the above output.\n"); } void fuse_mount_version(void) @@ -89,42 +65,50 @@ index d71e6fc55..acc1711ff 100644 int pid = fork(); if (!pid) { - const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL }; -+ const char *argv[] = { fuse_mount_prog(), "--version", NULL }; ++ const char *argv[] = { NULL, "--version", NULL }; exec_fusermount(argv); _exit(1); } else if (pid != -1) -@@ -300,7 +361,7 @@ void fuse_kern_unmount(const char *mountpoint, int fd) +@@ -300,7 +337,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", ++ const char *argv[] = { NULL, "-u", "-q", "-z", "--", mountpoint, NULL }; exec_fusermount(argv); -@@ -346,7 +407,7 @@ static int setup_auto_unmount(const char *mountpoint, int quiet) +@@ -346,7 +383,7 @@ static int setup_auto_unmount(const char *mountpoint, int quiet) } } - argv[a++] = FUSERMOUNT_PROG; -+ argv[a++] = fuse_mount_prog(); ++ argv[a++] = NULL; 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, +@@ -357,7 +394,6 @@ static int setup_auto_unmount(const char *mountpoint, int quiet) + snprintf(env, sizeof(env), "%i", fds[0]); + setenv(FUSE_COMMFD_ENV, env, 1); + exec_fusermount(argv); +- perror("fuse: failed to exec fusermount3"); + _exit(1); + } + +@@ -407,7 +443,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo, } } - argv[a++] = FUSERMOUNT_PROG; -+ argv[a++] = fuse_mount_prog(); ++ argv[a++] = NULL; if (opts) { argv[a++] = "-o"; argv[a++] = opts; -@@ -421,7 +482,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo, +@@ -421,7 +457,6 @@ 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); } +