* The description of the FUSE_CAP_READDIRPLUS_AUTO flag has been
improved.
+* Allow open `/dev/fuse` file descriptors to be passed via mountpoints of the
+ special format `/dev/fd/%u`. This allows mounting to be handled by the parent
+ so the FUSE filesystem process can run fully unprivileged.
+
libfuse 3.2.6 (2018-08-31)
==========================
#include "fuse_kernel.h"
#include "fuse_opt.h"
#include "fuse_misc.h"
+#include "mount_util.h"
#include <stdio.h>
#include <stdlib.h>
close(fd);
} while (fd >= 0 && fd <= 2);
+ /*
+ * To allow FUSE daemons to run without privileges, the caller may open
+ * /dev/fuse before launching the file system and pass on the file
+ * descriptor by specifying /dev/fd/N as the mount point. Note that the
+ * parent process takes care of performing the mount in this case.
+ */
+ fd = fuse_mnt_parse_fuse_fd(mountpoint);
+ if (fd != -1) {
+ if (fcntl(fd, F_GETFD) == -1) {
+ fprintf(stderr,
+ "fuse: Invalid file descriptor /dev/fd/%u\n",
+ fd);
+ return -1;
+ }
+ se->fd = fd;
+ return 0;
+ }
+
/* Open channel */
fd = fuse_kern_mount(mountpoint, se->mo);
if (fd == -1)
void fuse_session_unmount(struct fuse_session *se)
{
- fuse_kern_unmount(se->mountpoint, se->fd);
- free(se->mountpoint);
- se->mountpoint = NULL;
+ if (se->mountpoint != NULL) {
+ fuse_kern_unmount(se->mountpoint, se->fd);
+ free(se->mountpoint);
+ se->mountpoint = NULL;
+ }
}
#ifdef linux
#include "fuse_misc.h"
#include "fuse_opt.h"
#include "fuse_lowlevel.h"
+#include "mount_util.h"
#include <stdio.h>
#include <stdlib.h>
switch (key) {
case FUSE_OPT_KEY_NONOPT:
if (!opts->mountpoint) {
- char mountpoint[PATH_MAX];
+ if (fuse_mnt_parse_fuse_fd(arg) != -1) {
+ return fuse_opt_add_opt(&opts->mountpoint, arg);
+ }
+
+ char mountpoint[PATH_MAX] = "";
if (realpath(arg, mountpoint) == NULL) {
fprintf(stderr,
"fuse: bad mount point `%s': %s\n",
fclose(f);
return 0;
}
+
+int fuse_mnt_parse_fuse_fd(const char *mountpoint)
+{
+ int fd = -1;
+ int len = 0;
+
+ if (sscanf(mountpoint, "/dev/fd/%u%n", &fd, &len) == 1 &&
+ len == strlen(mountpoint)) {
+ return fd;
+ }
+
+ return -1;
+}
const char *rel_mnt, int lazy);
char *fuse_mnt_resolve_path(const char *progname, const char *orig);
int fuse_mnt_check_fuseblk(void);
+int fuse_mnt_parse_fuse_fd(const char *mountpoint);