libfuse
fusermount.c
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU GPLv2.
6  See the file COPYING.
7 */
8 /* This program does the mounting and unmounting of FUSE filesystems */
9 
10 #define _GNU_SOURCE /* for clone */
11 #include "fuse_config.h"
12 #include "mount_util.h"
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <unistd.h>
19 #include <getopt.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <pwd.h>
23 #include <paths.h>
24 #include <mntent.h>
25 #include <sys/wait.h>
26 #include <sys/stat.h>
27 #include <sys/mount.h>
28 #include <sys/fsuid.h>
29 #include <sys/socket.h>
30 #include <sys/utsname.h>
31 #include <sched.h>
32 #include <stdbool.h>
33 #include <sys/vfs.h>
34 
35 #define FUSE_COMMFD_ENV "_FUSE_COMMFD"
36 
37 #define FUSE_DEV "/dev/fuse"
38 
39 #ifndef MS_DIRSYNC
40 #define MS_DIRSYNC 128
41 #endif
42 #ifndef MS_REC
43 #define MS_REC 16384
44 #endif
45 #ifndef MS_PRIVATE
46 #define MS_PRIVATE (1<<18)
47 #endif
48 
49 #ifndef UMOUNT_DETACH
50 #define UMOUNT_DETACH 0x00000002 /* Just detach from the tree */
51 #endif
52 #ifndef UMOUNT_NOFOLLOW
53 #define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
54 #endif
55 #ifndef UMOUNT_UNUSED
56 #define UMOUNT_UNUSED 0x80000000 /* Flag guaranteed to be unused */
57 #endif
58 
59 static const char *progname;
60 
61 static int user_allow_other = 0;
62 static int mount_max = 1000;
63 
64 static int auto_unmount = 0;
65 
66 static const char *get_user_name(void)
67 {
68  struct passwd *pw = getpwuid(getuid());
69  if (pw != NULL && pw->pw_name != NULL)
70  return pw->pw_name;
71  else {
72  fprintf(stderr, "%s: could not determine username\n", progname);
73  return NULL;
74  }
75 }
76 
77 static uid_t oldfsuid;
78 static gid_t oldfsgid;
79 
80 static void drop_privs(void)
81 {
82  if (getuid() != 0) {
83  oldfsuid = setfsuid(getuid());
84  oldfsgid = setfsgid(getgid());
85  }
86 }
87 
88 static void restore_privs(void)
89 {
90  if (getuid() != 0) {
91  setfsuid(oldfsuid);
92  setfsgid(oldfsgid);
93  }
94 }
95 
96 #ifndef IGNORE_MTAB
97 /*
98  * Make sure that /etc/mtab is checked and updated atomically
99  */
100 static int lock_umount(void)
101 {
102  const char *mtab_lock = _PATH_MOUNTED ".fuselock";
103  int mtablock;
104  int res;
105  struct stat mtab_stat;
106 
107  /* /etc/mtab could be a symlink to /proc/mounts */
108  if (lstat(_PATH_MOUNTED, &mtab_stat) == 0 && S_ISLNK(mtab_stat.st_mode))
109  return -1;
110 
111  mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600);
112  if (mtablock == -1) {
113  fprintf(stderr, "%s: unable to open fuse lock file: %s\n",
114  progname, strerror(errno));
115  return -1;
116  }
117  res = lockf(mtablock, F_LOCK, 0);
118  if (res < 0) {
119  fprintf(stderr, "%s: error getting lock: %s\n", progname,
120  strerror(errno));
121  close(mtablock);
122  return -1;
123  }
124 
125  return mtablock;
126 }
127 
128 static void unlock_umount(int mtablock)
129 {
130  if (mtablock >= 0) {
131  int res;
132 
133  res = lockf(mtablock, F_ULOCK, 0);
134  if (res < 0) {
135  fprintf(stderr, "%s: error releasing lock: %s\n",
136  progname, strerror(errno));
137  }
138  close(mtablock);
139  }
140 }
141 
142 static int add_mount(const char *source, const char *mnt, const char *type,
143  const char *opts)
144 {
145  return fuse_mnt_add_mount(progname, source, mnt, type, opts);
146 }
147 
148 static int may_unmount(const char *mnt, int quiet)
149 {
150  struct mntent *entp;
151  FILE *fp;
152  const char *user = NULL;
153  char uidstr[32];
154  unsigned uidlen = 0;
155  int found;
156  const char *mtab = _PATH_MOUNTED;
157 
158  user = get_user_name();
159  if (user == NULL)
160  return -1;
161 
162  fp = setmntent(mtab, "r");
163  if (fp == NULL) {
164  fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
165  strerror(errno));
166  return -1;
167  }
168 
169  uidlen = sprintf(uidstr, "%u", getuid());
170 
171  found = 0;
172  while ((entp = getmntent(fp)) != NULL) {
173  if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
174  (strcmp(entp->mnt_type, "fuse") == 0 ||
175  strcmp(entp->mnt_type, "fuseblk") == 0 ||
176  strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
177  strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
178  char *p = strstr(entp->mnt_opts, "user=");
179  if (p &&
180  (p == entp->mnt_opts || *(p-1) == ',') &&
181  strcmp(p + 5, user) == 0) {
182  found = 1;
183  break;
184  }
185  /* /etc/mtab is a link pointing to
186  /proc/mounts: */
187  else if ((p =
188  strstr(entp->mnt_opts, "user_id=")) &&
189  (p == entp->mnt_opts ||
190  *(p-1) == ',') &&
191  strncmp(p + 8, uidstr, uidlen) == 0 &&
192  (*(p+8+uidlen) == ',' ||
193  *(p+8+uidlen) == '\0')) {
194  found = 1;
195  break;
196  }
197  }
198  }
199  endmntent(fp);
200 
201  if (!found) {
202  if (!quiet)
203  fprintf(stderr,
204  "%s: entry for %s not found in %s\n",
205  progname, mnt, mtab);
206  return -1;
207  }
208 
209  return 0;
210 }
211 #endif
212 
213 /*
214  * Check whether the file specified in "fusermount3 -u" is really a
215  * mountpoint and not a symlink. This is necessary otherwise the user
216  * could move the mountpoint away and replace it with a symlink
217  * pointing to an arbitrary mount, thereby tricking fusermount3 into
218  * unmounting that (umount(2) will follow symlinks).
219  *
220  * This is the child process running in a separate mount namespace, so
221  * we don't mess with the global namespace and if the process is
222  * killed for any reason, mounts are automatically cleaned up.
223  *
224  * First make sure nothing is propagated back into the parent
225  * namespace by marking all mounts "private".
226  *
227  * Then bind mount parent onto a stable base where the user can't move
228  * it around.
229  *
230  * Finally check /proc/mounts for an entry matching the requested
231  * mountpoint. If it's found then we are OK, and the user can't move
232  * it around within the parent directory as rename() will return
233  * EBUSY. Be careful to ignore any mounts that existed before the
234  * bind.
235  */
236 static int check_is_mount_child(void *p)
237 {
238  const char **a = p;
239  const char *last = a[0];
240  const char *mnt = a[1];
241  const char *type = a[2];
242  int res;
243  const char *procmounts = "/proc/mounts";
244  int found;
245  FILE *fp;
246  struct mntent *entp;
247  int count;
248 
249  res = mount("", "/", "", MS_PRIVATE | MS_REC, NULL);
250  if (res == -1) {
251  fprintf(stderr, "%s: failed to mark mounts private: %s\n",
252  progname, strerror(errno));
253  return 1;
254  }
255 
256  fp = setmntent(procmounts, "r");
257  if (fp == NULL) {
258  fprintf(stderr, "%s: failed to open %s: %s\n", progname,
259  procmounts, strerror(errno));
260  return 1;
261  }
262 
263  count = 0;
264  while (getmntent(fp) != NULL)
265  count++;
266  endmntent(fp);
267 
268  fp = setmntent(procmounts, "r");
269  if (fp == NULL) {
270  fprintf(stderr, "%s: failed to open %s: %s\n", progname,
271  procmounts, strerror(errno));
272  return 1;
273  }
274 
275  res = mount(".", "/", "", MS_BIND | MS_REC, NULL);
276  if (res == -1) {
277  fprintf(stderr, "%s: failed to bind parent to /: %s\n",
278  progname, strerror(errno));
279  return 1;
280  }
281 
282  found = 0;
283  while ((entp = getmntent(fp)) != NULL) {
284  if (count > 0) {
285  count--;
286  continue;
287  }
288  if (entp->mnt_dir[0] == '/' &&
289  strcmp(entp->mnt_dir + 1, last) == 0 &&
290  (!type || strcmp(entp->mnt_type, type) == 0)) {
291  found = 1;
292  break;
293  }
294  }
295  endmntent(fp);
296 
297  if (!found) {
298  fprintf(stderr, "%s: %s not mounted\n", progname, mnt);
299  return 1;
300  }
301 
302  return 0;
303 }
304 
305 static pid_t clone_newns(void *a)
306 {
307  char buf[131072];
308  char *stack = buf + (sizeof(buf) / 2 - ((size_t) buf & 15));
309 
310 #ifdef __ia64__
311  extern int __clone2(int (*fn)(void *),
312  void *child_stack_base, size_t stack_size,
313  int flags, void *arg, pid_t *ptid,
314  void *tls, pid_t *ctid);
315 
316  return __clone2(check_is_mount_child, stack, sizeof(buf) / 2,
317  CLONE_NEWNS, a, NULL, NULL, NULL);
318 #else
319  return clone(check_is_mount_child, stack, CLONE_NEWNS, a);
320 #endif
321 }
322 
323 static int check_is_mount(const char *last, const char *mnt, const char *type)
324 {
325  pid_t pid, p;
326  int status;
327  const char *a[3] = { last, mnt, type };
328 
329  pid = clone_newns((void *) a);
330  if (pid == (pid_t) -1) {
331  fprintf(stderr, "%s: failed to clone namespace: %s\n",
332  progname, strerror(errno));
333  return -1;
334  }
335  p = waitpid(pid, &status, __WCLONE);
336  if (p == (pid_t) -1) {
337  fprintf(stderr, "%s: waitpid failed: %s\n",
338  progname, strerror(errno));
339  return -1;
340  }
341  if (!WIFEXITED(status)) {
342  fprintf(stderr, "%s: child terminated abnormally (status %i)\n",
343  progname, status);
344  return -1;
345  }
346  if (WEXITSTATUS(status) != 0)
347  return -1;
348 
349  return 0;
350 }
351 
352 static int chdir_to_parent(char *copy, const char **lastp)
353 {
354  char *tmp;
355  const char *parent;
356  char buf[65536];
357  int res;
358 
359  tmp = strrchr(copy, '/');
360  if (tmp == NULL || tmp[1] == '\0') {
361  fprintf(stderr, "%s: internal error: invalid abs path: <%s>\n",
362  progname, copy);
363  return -1;
364  }
365  if (tmp != copy) {
366  *tmp = '\0';
367  parent = copy;
368  *lastp = tmp + 1;
369  } else if (tmp[1] != '\0') {
370  *lastp = tmp + 1;
371  parent = "/";
372  } else {
373  *lastp = ".";
374  parent = "/";
375  }
376 
377  res = chdir(parent);
378  if (res == -1) {
379  fprintf(stderr, "%s: failed to chdir to %s: %s\n",
380  progname, parent, strerror(errno));
381  return -1;
382  }
383 
384  if (getcwd(buf, sizeof(buf)) == NULL) {
385  fprintf(stderr, "%s: failed to obtain current directory: %s\n",
386  progname, strerror(errno));
387  return -1;
388  }
389  if (strcmp(buf, parent) != 0) {
390  fprintf(stderr, "%s: mountpoint moved (%s -> %s)\n", progname,
391  parent, buf);
392  return -1;
393 
394  }
395 
396  return 0;
397 }
398 
399 #ifndef IGNORE_MTAB
400 static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
401 {
402  int res;
403  char *copy;
404  const char *last;
405  int umount_flags = (lazy ? UMOUNT_DETACH : 0) | UMOUNT_NOFOLLOW;
406 
407  if (getuid() != 0) {
408  res = may_unmount(mnt, quiet);
409  if (res == -1)
410  return -1;
411  }
412 
413  copy = strdup(mnt);
414  if (copy == NULL) {
415  fprintf(stderr, "%s: failed to allocate memory\n", progname);
416  return -1;
417  }
418 
419  drop_privs();
420  res = chdir_to_parent(copy, &last);
421  restore_privs();
422  if (res == -1)
423  goto out;
424 
425  res = umount2(last, umount_flags);
426  if (res == -1 && !quiet) {
427  fprintf(stderr, "%s: failed to unmount %s: %s\n",
428  progname, mnt, strerror(errno));
429  }
430 
431 out:
432  free(copy);
433  if (res == -1)
434  return -1;
435 
436  res = chdir("/");
437  if (res == -1) {
438  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
439  return -1;
440  }
441 
442  return fuse_mnt_remove_mount(progname, mnt);
443 }
444 
445 static int unmount_fuse(const char *mnt, int quiet, int lazy)
446 {
447  int res;
448  int mtablock = lock_umount();
449 
450  res = unmount_fuse_locked(mnt, quiet, lazy);
451  unlock_umount(mtablock);
452 
453  return res;
454 }
455 
456 static int count_fuse_fs(void)
457 {
458  struct mntent *entp;
459  int count = 0;
460  const char *mtab = _PATH_MOUNTED;
461  FILE *fp = setmntent(mtab, "r");
462  if (fp == NULL) {
463  fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
464  strerror(errno));
465  return -1;
466  }
467  while ((entp = getmntent(fp)) != NULL) {
468  if (strcmp(entp->mnt_type, "fuse") == 0 ||
469  strncmp(entp->mnt_type, "fuse.", 5) == 0)
470  count ++;
471  }
472  endmntent(fp);
473  return count;
474 }
475 
476 
477 #else /* IGNORE_MTAB */
478 static int count_fuse_fs(void)
479 {
480  return 0;
481 }
482 
483 static int add_mount(const char *source, const char *mnt, const char *type,
484  const char *opts)
485 {
486  (void) source;
487  (void) mnt;
488  (void) type;
489  (void) opts;
490  return 0;
491 }
492 
493 static int unmount_fuse(const char *mnt, int quiet, int lazy)
494 {
495  (void) quiet;
496  return fuse_mnt_umount(progname, mnt, mnt, lazy);
497 }
498 #endif /* IGNORE_MTAB */
499 
500 static void strip_line(char *line)
501 {
502  char *s = strchr(line, '#');
503  if (s != NULL)
504  s[0] = '\0';
505  for (s = line + strlen(line) - 1;
506  s >= line && isspace((unsigned char) *s); s--);
507  s[1] = '\0';
508  for (s = line; isspace((unsigned char) *s); s++);
509  if (s != line)
510  memmove(line, s, strlen(s)+1);
511 }
512 
513 static void parse_line(char *line, int linenum)
514 {
515  int tmp;
516  if (strcmp(line, "user_allow_other") == 0)
517  user_allow_other = 1;
518  else if (sscanf(line, "mount_max = %i", &tmp) == 1)
519  mount_max = tmp;
520  else if(line[0])
521  fprintf(stderr,
522  "%s: unknown parameter in %s at line %i: '%s'\n",
523  progname, FUSE_CONF, linenum, line);
524 }
525 
526 static void read_conf(void)
527 {
528  FILE *fp = fopen(FUSE_CONF, "r");
529  if (fp != NULL) {
530  int linenum = 1;
531  char line[256];
532  int isnewline = 1;
533  while (fgets(line, sizeof(line), fp) != NULL) {
534  if (isnewline) {
535  if (line[strlen(line)-1] == '\n') {
536  strip_line(line);
537  parse_line(line, linenum);
538  } else {
539  isnewline = 0;
540  }
541  } else if(line[strlen(line)-1] == '\n') {
542  fprintf(stderr, "%s: reading %s: line %i too long\n", progname, FUSE_CONF, linenum);
543 
544  isnewline = 1;
545  }
546  if (isnewline)
547  linenum ++;
548  }
549  if (!isnewline) {
550  fprintf(stderr, "%s: reading %s: missing newline at end of file\n", progname, FUSE_CONF);
551 
552  }
553  if (ferror(fp)) {
554  fprintf(stderr, "%s: reading %s: read failed\n", progname, FUSE_CONF);
555  exit(1);
556  }
557  fclose(fp);
558  } else if (errno != ENOENT) {
559  bool fatal = (errno != EACCES && errno != ELOOP &&
560  errno != ENAMETOOLONG && errno != ENOTDIR &&
561  errno != EOVERFLOW);
562  fprintf(stderr, "%s: failed to open %s: %s\n",
563  progname, FUSE_CONF, strerror(errno));
564  if (fatal)
565  exit(1);
566  }
567 }
568 
569 static int begins_with(const char *s, const char *beg)
570 {
571  if (strncmp(s, beg, strlen(beg)) == 0)
572  return 1;
573  else
574  return 0;
575 }
576 
577 struct mount_flags {
578  const char *opt;
579  unsigned long flag;
580  int on;
581  int safe;
582 };
583 
584 static struct mount_flags mount_flags[] = {
585  {"rw", MS_RDONLY, 0, 1},
586  {"ro", MS_RDONLY, 1, 1},
587  {"suid", MS_NOSUID, 0, 0},
588  {"nosuid", MS_NOSUID, 1, 1},
589  {"dev", MS_NODEV, 0, 0},
590  {"nodev", MS_NODEV, 1, 1},
591  {"exec", MS_NOEXEC, 0, 1},
592  {"noexec", MS_NOEXEC, 1, 1},
593  {"async", MS_SYNCHRONOUS, 0, 1},
594  {"sync", MS_SYNCHRONOUS, 1, 1},
595  {"atime", MS_NOATIME, 0, 1},
596  {"noatime", MS_NOATIME, 1, 1},
597  {"diratime", MS_NODIRATIME, 0, 1},
598  {"nodiratime", MS_NODIRATIME, 1, 1},
599  {"lazytime", MS_LAZYTIME, 1, 1},
600  {"nolazytime", MS_LAZYTIME, 0, 1},
601  {"relatime", MS_RELATIME, 1, 1},
602  {"norelatime", MS_RELATIME, 0, 1},
603  {"strictatime", MS_STRICTATIME, 1, 1},
604  {"nostrictatime", MS_STRICTATIME, 0, 1},
605  {"dirsync", MS_DIRSYNC, 1, 1},
606  {NULL, 0, 0, 0}
607 };
608 
609 static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
610 {
611  int i;
612 
613  for (i = 0; mount_flags[i].opt != NULL; i++) {
614  const char *opt = mount_flags[i].opt;
615  if (strlen(opt) == len && strncmp(opt, s, len) == 0) {
616  *on = mount_flags[i].on;
617  *flag = mount_flags[i].flag;
618  if (!mount_flags[i].safe && getuid() != 0) {
619  *flag = 0;
620  fprintf(stderr,
621  "%s: unsafe option %s ignored\n",
622  progname, opt);
623  }
624  return 1;
625  }
626  }
627  return 0;
628 }
629 
630 static int add_option(char **optsp, const char *opt, unsigned expand)
631 {
632  char *newopts;
633  if (*optsp == NULL)
634  newopts = strdup(opt);
635  else {
636  unsigned oldsize = strlen(*optsp);
637  unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;
638  newopts = (char *) realloc(*optsp, newsize);
639  if (newopts)
640  sprintf(newopts + oldsize, ",%s", opt);
641  }
642  if (newopts == NULL) {
643  fprintf(stderr, "%s: failed to allocate memory\n", progname);
644  return -1;
645  }
646  *optsp = newopts;
647  return 0;
648 }
649 
650 static int get_mnt_opts(int flags, char *opts, char **mnt_optsp)
651 {
652  int i;
653  int l;
654 
655  if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1)
656  return -1;
657 
658  for (i = 0; mount_flags[i].opt != NULL; i++) {
659  if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
660  add_option(mnt_optsp, mount_flags[i].opt, 0) == -1)
661  return -1;
662  }
663 
664  if (add_option(mnt_optsp, opts, 0) == -1)
665  return -1;
666  /* remove comma from end of opts*/
667  l = strlen(*mnt_optsp);
668  if ((*mnt_optsp)[l-1] == ',')
669  (*mnt_optsp)[l-1] = '\0';
670  if (getuid() != 0) {
671  const char *user = get_user_name();
672  if (user == NULL)
673  return -1;
674 
675  if (add_option(mnt_optsp, "user=", strlen(user)) == -1)
676  return -1;
677  strcat(*mnt_optsp, user);
678  }
679  return 0;
680 }
681 
682 static int opt_eq(const char *s, unsigned len, const char *opt)
683 {
684  if(strlen(opt) == len && strncmp(s, opt, len) == 0)
685  return 1;
686  else
687  return 0;
688 }
689 
690 static int get_string_opt(const char *s, unsigned len, const char *opt,
691  char **val)
692 {
693  int i;
694  unsigned opt_len = strlen(opt);
695  char *d;
696 
697  if (*val)
698  free(*val);
699  *val = (char *) malloc(len - opt_len + 1);
700  if (!*val) {
701  fprintf(stderr, "%s: failed to allocate memory\n", progname);
702  return 0;
703  }
704 
705  d = *val;
706  s += opt_len;
707  len -= opt_len;
708  for (i = 0; i < len; i++) {
709  if (s[i] == '\\' && i + 1 < len)
710  i++;
711  *d++ = s[i];
712  }
713  *d = '\0';
714  return 1;
715 }
716 
717 /* The kernel silently truncates the "data" argument to PAGE_SIZE-1 characters.
718  * This can be dangerous if it e.g. truncates the option "group_id=1000" to
719  * "group_id=1".
720  * This wrapper detects this case and bails out with an error.
721  */
722 static int mount_notrunc(const char *source, const char *target,
723  const char *filesystemtype, unsigned long mountflags,
724  const char *data) {
725  if (strlen(data) > sysconf(_SC_PAGESIZE) - 1) {
726  fprintf(stderr, "%s: mount options too long\n", progname);
727  errno = EINVAL;
728  return -1;
729  }
730  return mount(source, target, filesystemtype, mountflags, data);
731 }
732 
733 
734 static int do_mount(const char *mnt, const char **typep, mode_t rootmode,
735  int fd, const char *opts, const char *dev, char **sourcep,
736  char **mnt_optsp)
737 {
738  int res;
739  int flags = MS_NOSUID | MS_NODEV;
740  char *optbuf;
741  char *mnt_opts = NULL;
742  const char *s;
743  char *d;
744  char *fsname = NULL;
745  char *subtype = NULL;
746  char *source = NULL;
747  char *type = NULL;
748  int blkdev = 0;
749 
750  optbuf = (char *) malloc(strlen(opts) + 128);
751  if (!optbuf) {
752  fprintf(stderr, "%s: failed to allocate memory\n", progname);
753  return -1;
754  }
755 
756  for (s = opts, d = optbuf; *s;) {
757  unsigned len;
758  const char *fsname_str = "fsname=";
759  const char *subtype_str = "subtype=";
760  bool escape_ok = begins_with(s, fsname_str) ||
761  begins_with(s, subtype_str);
762  for (len = 0; s[len]; len++) {
763  if (escape_ok && s[len] == '\\' && s[len + 1])
764  len++;
765  else if (s[len] == ',')
766  break;
767  }
768  if (begins_with(s, fsname_str)) {
769  if (!get_string_opt(s, len, fsname_str, &fsname))
770  goto err;
771  } else if (begins_with(s, subtype_str)) {
772  if (!get_string_opt(s, len, subtype_str, &subtype))
773  goto err;
774  } else if (opt_eq(s, len, "blkdev")) {
775  if (getuid() != 0) {
776  fprintf(stderr,
777  "%s: option blkdev is privileged\n",
778  progname);
779  goto err;
780  }
781  blkdev = 1;
782  } else if (opt_eq(s, len, "auto_unmount")) {
783  auto_unmount = 1;
784  } else if (!opt_eq(s, len, "nonempty") &&
785  !begins_with(s, "fd=") &&
786  !begins_with(s, "rootmode=") &&
787  !begins_with(s, "user_id=") &&
788  !begins_with(s, "group_id=")) {
789  int on;
790  int flag;
791  int skip_option = 0;
792  if (opt_eq(s, len, "large_read")) {
793  struct utsname utsname;
794  unsigned kmaj, kmin;
795  res = uname(&utsname);
796  if (res == 0 &&
797  sscanf(utsname.release, "%u.%u",
798  &kmaj, &kmin) == 2 &&
799  (kmaj > 2 || (kmaj == 2 && kmin > 4))) {
800  fprintf(stderr, "%s: note: 'large_read' mount option is deprecated for %i.%i kernels\n", progname, kmaj, kmin);
801  skip_option = 1;
802  }
803  }
804  if (getuid() != 0 && !user_allow_other &&
805  (opt_eq(s, len, "allow_other") ||
806  opt_eq(s, len, "allow_root"))) {
807  fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in %s\n", progname, len, s, FUSE_CONF);
808  goto err;
809  }
810  if (!skip_option) {
811  if (find_mount_flag(s, len, &on, &flag)) {
812  if (on)
813  flags |= flag;
814  else
815  flags &= ~flag;
816  } else if (opt_eq(s, len, "default_permissions") ||
817  opt_eq(s, len, "allow_other") ||
818  begins_with(s, "max_read=") ||
819  begins_with(s, "blksize=")) {
820  memcpy(d, s, len);
821  d += len;
822  *d++ = ',';
823  } else {
824  fprintf(stderr, "%s: unknown option '%.*s'\n", progname, len, s);
825  exit(1);
826  }
827  }
828  }
829  s += len;
830  if (*s)
831  s++;
832  }
833  *d = '\0';
834  res = get_mnt_opts(flags, optbuf, &mnt_opts);
835  if (res == -1)
836  goto err;
837 
838  sprintf(d, "fd=%i,rootmode=%o,user_id=%u,group_id=%u",
839  fd, rootmode, getuid(), getgid());
840 
841  source = malloc((fsname ? strlen(fsname) : 0) +
842  (subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
843 
844  type = malloc((subtype ? strlen(subtype) : 0) + 32);
845  if (!type || !source) {
846  fprintf(stderr, "%s: failed to allocate memory\n", progname);
847  goto err;
848  }
849 
850  if (subtype)
851  sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
852  else
853  strcpy(type, blkdev ? "fuseblk" : "fuse");
854 
855  if (fsname)
856  strcpy(source, fsname);
857  else
858  strcpy(source, subtype ? subtype : dev);
859 
860  res = mount_notrunc(source, mnt, type, flags, optbuf);
861  if (res == -1 && errno == ENODEV && subtype) {
862  /* Probably missing subtype support */
863  strcpy(type, blkdev ? "fuseblk" : "fuse");
864  if (fsname) {
865  if (!blkdev)
866  sprintf(source, "%s#%s", subtype, fsname);
867  } else {
868  strcpy(source, type);
869  }
870 
871  res = mount_notrunc(source, mnt, type, flags, optbuf);
872  }
873  if (res == -1 && errno == EINVAL) {
874  /* It could be an old version not supporting group_id */
875  sprintf(d, "fd=%i,rootmode=%o,user_id=%u",
876  fd, rootmode, getuid());
877  res = mount_notrunc(source, mnt, type, flags, optbuf);
878  }
879  if (res == -1) {
880  int errno_save = errno;
881  if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
882  fprintf(stderr, "%s: 'fuseblk' support missing\n",
883  progname);
884  else
885  fprintf(stderr, "%s: mount failed: %s\n", progname,
886  strerror(errno_save));
887  goto err;
888  }
889  *sourcep = source;
890  *typep = type;
891  *mnt_optsp = mnt_opts;
892  free(fsname);
893  free(optbuf);
894 
895  return 0;
896 
897 err:
898  free(fsname);
899  free(subtype);
900  free(source);
901  free(type);
902  free(mnt_opts);
903  free(optbuf);
904  return -1;
905 }
906 
907 static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd)
908 {
909  int res;
910  const char *mnt = *mntp;
911  const char *origmnt = mnt;
912  struct statfs fs_buf;
913  size_t i;
914 
915  res = lstat(mnt, stbuf);
916  if (res == -1) {
917  fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
918  progname, mnt, strerror(errno));
919  return -1;
920  }
921 
922  /* No permission checking is done for root */
923  if (getuid() == 0)
924  return 0;
925 
926  if (S_ISDIR(stbuf->st_mode)) {
927  res = chdir(mnt);
928  if (res == -1) {
929  fprintf(stderr,
930  "%s: failed to chdir to mountpoint: %s\n",
931  progname, strerror(errno));
932  return -1;
933  }
934  mnt = *mntp = ".";
935  res = lstat(mnt, stbuf);
936  if (res == -1) {
937  fprintf(stderr,
938  "%s: failed to access mountpoint %s: %s\n",
939  progname, origmnt, strerror(errno));
940  return -1;
941  }
942 
943  if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
944  fprintf(stderr, "%s: mountpoint %s not owned by user\n",
945  progname, origmnt);
946  return -1;
947  }
948 
949  res = access(mnt, W_OK);
950  if (res == -1) {
951  fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
952  progname, origmnt);
953  return -1;
954  }
955  } else if (S_ISREG(stbuf->st_mode)) {
956  static char procfile[256];
957  *mountpoint_fd = open(mnt, O_WRONLY);
958  if (*mountpoint_fd == -1) {
959  fprintf(stderr, "%s: failed to open %s: %s\n",
960  progname, mnt, strerror(errno));
961  return -1;
962  }
963  res = fstat(*mountpoint_fd, stbuf);
964  if (res == -1) {
965  fprintf(stderr,
966  "%s: failed to access mountpoint %s: %s\n",
967  progname, mnt, strerror(errno));
968  return -1;
969  }
970  if (!S_ISREG(stbuf->st_mode)) {
971  fprintf(stderr,
972  "%s: mountpoint %s is no longer a regular file\n",
973  progname, mnt);
974  return -1;
975  }
976 
977  sprintf(procfile, "/proc/self/fd/%i", *mountpoint_fd);
978  *mntp = procfile;
979  } else {
980  fprintf(stderr,
981  "%s: mountpoint %s is not a directory or a regular file\n",
982  progname, mnt);
983  return -1;
984  }
985 
986  /* Do not permit mounting over anything in procfs - it has a couple
987  * places to which we have "write access" without being supposed to be
988  * able to just put anything we want there.
989  * Luckily, without allow_other, we can't get other users to actually
990  * use any fake information we try to put there anyway.
991  * Use a whitelist to be safe. */
992  if (statfs(*mntp, &fs_buf)) {
993  fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
994  progname, mnt, strerror(errno));
995  return -1;
996  }
997 
998  /* Define permitted filesystems for the mount target. This was
999  * originally the same list as used by the ecryptfs mount helper
1000  * (https://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/view/head:/src/utils/mount.ecryptfs_private.c#L225)
1001  * but got expanded as we found more filesystems that needed to be
1002  * overlayed. */
1003  typeof(fs_buf.f_type) f_type_whitelist[] = {
1004  0x61756673 /* AUFS_SUPER_MAGIC */,
1005  0x00000187 /* AUTOFS_SUPER_MAGIC */,
1006  0xCA451A4E /* BCACHEFS_STATFS_MAGIC */,
1007  0x9123683E /* BTRFS_SUPER_MAGIC */,
1008  0x00C36400 /* CEPH_SUPER_MAGIC */,
1009  0xFF534D42 /* CIFS_MAGIC_NUMBER */,
1010  0x0000F15F /* ECRYPTFS_SUPER_MAGIC */,
1011  0X2011BAB0 /* EXFAT_SUPER_MAGIC */,
1012  0x0000EF53 /* EXT[234]_SUPER_MAGIC */,
1013  0xF2F52010 /* F2FS_SUPER_MAGIC */,
1014  0x65735546 /* FUSE_SUPER_MAGIC */,
1015  0x01161970 /* GFS2_MAGIC */,
1016  0x47504653 /* GPFS_SUPER_MAGIC */,
1017  0x0000482b /* HFSPLUS_SUPER_MAGIC */,
1018  0x000072B6 /* JFFS2_SUPER_MAGIC */,
1019  0x3153464A /* JFS_SUPER_MAGIC */,
1020  0x0BD00BD0 /* LL_SUPER_MAGIC */,
1021  0X00004D44 /* MSDOS_SUPER_MAGIC */,
1022  0x0000564C /* NCP_SUPER_MAGIC */,
1023  0x00006969 /* NFS_SUPER_MAGIC */,
1024  0x00003434 /* NILFS_SUPER_MAGIC */,
1025  0x5346544E /* NTFS_SB_MAGIC */,
1026  0x5346414f /* OPENAFS_SUPER_MAGIC */,
1027  0x794C7630 /* OVERLAYFS_SUPER_MAGIC */,
1028  0x52654973 /* REISERFS_SUPER_MAGIC */,
1029  0xFE534D42 /* SMB2_SUPER_MAGIC */,
1030  0x73717368 /* SQUASHFS_MAGIC */,
1031  0x01021994 /* TMPFS_MAGIC */,
1032  0x24051905 /* UBIFS_SUPER_MAGIC */,
1033  0x736675005346544e /* UFSD */,
1034  0x58465342 /* XFS_SB_MAGIC */,
1035  0x2FC12FC1 /* ZFS_SUPER_MAGIC */,
1036  };
1037  for (i = 0; i < sizeof(f_type_whitelist)/sizeof(f_type_whitelist[0]); i++) {
1038  if (f_type_whitelist[i] == fs_buf.f_type)
1039  return 0;
1040  }
1041 
1042  fprintf(stderr, "%s: mounting over filesystem type %#010lx is forbidden\n",
1043  progname, (unsigned long)fs_buf.f_type);
1044  return -1;
1045 }
1046 
1047 static int try_open(const char *dev, char **devp, int silent)
1048 {
1049  int fd = open(dev, O_RDWR);
1050  if (fd != -1) {
1051  *devp = strdup(dev);
1052  if (*devp == NULL) {
1053  fprintf(stderr, "%s: failed to allocate memory\n",
1054  progname);
1055  close(fd);
1056  fd = -1;
1057  }
1058  } else if (errno == ENODEV ||
1059  errno == ENOENT)/* check for ENOENT too, for the udev case */
1060  return -2;
1061  else if (!silent) {
1062  fprintf(stderr, "%s: failed to open %s: %s\n", progname, dev,
1063  strerror(errno));
1064  }
1065  return fd;
1066 }
1067 
1068 static int try_open_fuse_device(char **devp)
1069 {
1070  int fd;
1071 
1072  drop_privs();
1073  fd = try_open(FUSE_DEV, devp, 0);
1074  restore_privs();
1075  return fd;
1076 }
1077 
1078 static int open_fuse_device(char **devp)
1079 {
1080  int fd = try_open_fuse_device(devp);
1081  if (fd >= -1)
1082  return fd;
1083 
1084  fprintf(stderr,
1085  "%s: fuse device not found, try 'modprobe fuse' first\n",
1086  progname);
1087 
1088  return -1;
1089 }
1090 
1091 
1092 static int mount_fuse(const char *mnt, const char *opts, const char **type)
1093 {
1094  int res;
1095  int fd;
1096  char *dev;
1097  struct stat stbuf;
1098  char *source = NULL;
1099  char *mnt_opts = NULL;
1100  const char *real_mnt = mnt;
1101  int mountpoint_fd = -1;
1102 
1103  fd = open_fuse_device(&dev);
1104  if (fd == -1)
1105  return -1;
1106 
1107  drop_privs();
1108  read_conf();
1109 
1110  if (getuid() != 0 && mount_max != -1) {
1111  int mount_count = count_fuse_fs();
1112  if (mount_count >= mount_max) {
1113  fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in %s\n", progname, FUSE_CONF);
1114  goto fail_close_fd;
1115  }
1116  }
1117 
1118  res = check_perm(&real_mnt, &stbuf, &mountpoint_fd);
1119  restore_privs();
1120  if (res != -1)
1121  res = do_mount(real_mnt, type, stbuf.st_mode & S_IFMT,
1122  fd, opts, dev, &source, &mnt_opts);
1123 
1124  if (mountpoint_fd != -1)
1125  close(mountpoint_fd);
1126 
1127  if (res == -1)
1128  goto fail_close_fd;
1129 
1130  res = chdir("/");
1131  if (res == -1) {
1132  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1133  goto fail_close_fd;
1134  }
1135 
1136  if (geteuid() == 0) {
1137  res = add_mount(source, mnt, *type, mnt_opts);
1138  if (res == -1) {
1139  /* Can't clean up mount in a non-racy way */
1140  goto fail_close_fd;
1141  }
1142  }
1143 
1144 out_free:
1145  free(source);
1146  free(mnt_opts);
1147  free(dev);
1148 
1149  return fd;
1150 
1151 fail_close_fd:
1152  close(fd);
1153  fd = -1;
1154  goto out_free;
1155 }
1156 
1157 static int send_fd(int sock_fd, int fd)
1158 {
1159  int retval;
1160  struct msghdr msg;
1161  struct cmsghdr *p_cmsg;
1162  struct iovec vec;
1163  size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
1164  int *p_fds;
1165  char sendchar = 0;
1166 
1167  msg.msg_control = cmsgbuf;
1168  msg.msg_controllen = sizeof(cmsgbuf);
1169  p_cmsg = CMSG_FIRSTHDR(&msg);
1170  p_cmsg->cmsg_level = SOL_SOCKET;
1171  p_cmsg->cmsg_type = SCM_RIGHTS;
1172  p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
1173  p_fds = (int *) CMSG_DATA(p_cmsg);
1174  *p_fds = fd;
1175  msg.msg_controllen = p_cmsg->cmsg_len;
1176  msg.msg_name = NULL;
1177  msg.msg_namelen = 0;
1178  msg.msg_iov = &vec;
1179  msg.msg_iovlen = 1;
1180  msg.msg_flags = 0;
1181  /* "To pass file descriptors or credentials you need to send/read at
1182  * least one byte" (man 7 unix) */
1183  vec.iov_base = &sendchar;
1184  vec.iov_len = sizeof(sendchar);
1185  while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
1186  if (retval != 1) {
1187  perror("sending file descriptor");
1188  return -1;
1189  }
1190  return 0;
1191 }
1192 
1193 /* The parent fuse process has died: decide whether to auto_unmount.
1194  *
1195  * In the normal case (umount or fusermount -u), the filesystem
1196  * has already been unmounted. If we simply unmount again we can
1197  * cause problems with stacked mounts (e.g. autofs).
1198  *
1199  * So we unmount here only in abnormal case where fuse process has
1200  * died without unmount happening. To detect this, we first look in
1201  * the mount table to make sure the mountpoint is still mounted and
1202  * has proper type. If so, we then see if opening the mount dir is
1203  * returning 'Transport endpoint is not connected'.
1204  *
1205  * The order of these is important, because if autofs is in use,
1206  * opening the dir to check for ENOTCONN will cause a new mount
1207  * in the normal case where filesystem has been unmounted cleanly.
1208  */
1209 static int should_auto_unmount(const char *mnt, const char *type)
1210 {
1211  char *copy;
1212  const char *last;
1213  int result = 0;
1214  int fd;
1215 
1216  copy = strdup(mnt);
1217  if (copy == NULL) {
1218  fprintf(stderr, "%s: failed to allocate memory\n", progname);
1219  return 0;
1220  }
1221 
1222  if (chdir_to_parent(copy, &last) == -1)
1223  goto out;
1224  if (check_is_mount(last, mnt, type) == -1)
1225  goto out;
1226 
1227  fd = open(mnt, O_RDONLY);
1228  if (fd != -1) {
1229  close(fd);
1230  } else {
1231  result = errno == ENOTCONN;
1232  }
1233 out:
1234  free(copy);
1235  return result;
1236 }
1237 
1238 static void usage(void)
1239 {
1240  printf("%s: [options] mountpoint\n"
1241  "Options:\n"
1242  " -h print help\n"
1243  " -V print version\n"
1244  " -o opt[,opt...] mount options\n"
1245  " -u unmount\n"
1246  " -q quiet\n"
1247  " -z lazy unmount\n",
1248  progname);
1249  exit(1);
1250 }
1251 
1252 static void show_version(void)
1253 {
1254  printf("fusermount3 version: %s\n", PACKAGE_VERSION);
1255  exit(0);
1256 }
1257 
1258 int main(int argc, char *argv[])
1259 {
1260  sigset_t sigset;
1261  int ch;
1262  int fd;
1263  int res;
1264  char *origmnt;
1265  char *mnt;
1266  static int unmount = 0;
1267  static int lazy = 0;
1268  static int quiet = 0;
1269  char *commfd;
1270  int cfd;
1271  const char *opts = "";
1272  const char *type = NULL;
1273 
1274  static const struct option long_opts[] = {
1275  {"unmount", no_argument, NULL, 'u'},
1276  {"lazy", no_argument, NULL, 'z'},
1277  {"quiet", no_argument, NULL, 'q'},
1278  {"help", no_argument, NULL, 'h'},
1279  {"version", no_argument, NULL, 'V'},
1280  {0, 0, 0, 0}};
1281 
1282  progname = strdup(argc > 0 ? argv[0] : "fusermount");
1283  if (progname == NULL) {
1284  fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
1285  exit(1);
1286  }
1287 
1288  while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
1289  NULL)) != -1) {
1290  switch (ch) {
1291  case 'h':
1292  usage();
1293  break;
1294 
1295  case 'V':
1296  show_version();
1297  break;
1298 
1299  case 'o':
1300  opts = optarg;
1301  break;
1302 
1303  case 'u':
1304  unmount = 1;
1305  break;
1306 
1307  case 'z':
1308  lazy = 1;
1309  break;
1310 
1311  case 'q':
1312  quiet = 1;
1313  break;
1314 
1315  default:
1316  exit(1);
1317  }
1318  }
1319 
1320  if (lazy && !unmount) {
1321  fprintf(stderr, "%s: -z can only be used with -u\n", progname);
1322  exit(1);
1323  }
1324 
1325  if (optind >= argc) {
1326  fprintf(stderr, "%s: missing mountpoint argument\n", progname);
1327  exit(1);
1328  } else if (argc > optind + 1) {
1329  fprintf(stderr, "%s: extra arguments after the mountpoint\n",
1330  progname);
1331  exit(1);
1332  }
1333 
1334  origmnt = argv[optind];
1335 
1336  drop_privs();
1337  mnt = fuse_mnt_resolve_path(progname, origmnt);
1338  if (mnt != NULL) {
1339  res = chdir("/");
1340  if (res == -1) {
1341  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1342  goto err_out;
1343  }
1344  }
1345  restore_privs();
1346  if (mnt == NULL)
1347  exit(1);
1348 
1349  umask(033);
1350  if (unmount)
1351  goto do_unmount;
1352 
1353  commfd = getenv(FUSE_COMMFD_ENV);
1354  if (commfd == NULL) {
1355  fprintf(stderr, "%s: old style mounting not supported\n",
1356  progname);
1357  goto err_out;
1358  }
1359 
1360  fd = mount_fuse(mnt, opts, &type);
1361  if (fd == -1)
1362  goto err_out;
1363 
1364  cfd = atoi(commfd);
1365  res = send_fd(cfd, fd);
1366  if (res == -1)
1367  goto err_out;
1368  close(fd);
1369 
1370  if (!auto_unmount) {
1371  free(mnt);
1372  return 0;
1373  }
1374 
1375  /* Become a daemon and wait for the parent to exit or die.
1376  ie For the control socket to get closed.
1377  btw We don't want to use daemon() function here because
1378  it forks and messes with the file descriptors. */
1379  setsid();
1380  res = chdir("/");
1381  if (res == -1) {
1382  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1383  goto err_out;
1384  }
1385 
1386  sigfillset(&sigset);
1387  sigprocmask(SIG_BLOCK, &sigset, NULL);
1388 
1389  lazy = 1;
1390  quiet = 1;
1391 
1392  while (1) {
1393  unsigned char buf[16];
1394  int n = recv(cfd, buf, sizeof(buf), 0);
1395  if (!n)
1396  break;
1397 
1398  if (n < 0) {
1399  if (errno == EINTR)
1400  continue;
1401  break;
1402  }
1403  }
1404 
1405  if (!should_auto_unmount(mnt, type)) {
1406  goto success_out;
1407  }
1408 
1409 do_unmount:
1410  if (geteuid() == 0)
1411  res = unmount_fuse(mnt, quiet, lazy);
1412  else {
1413  res = umount2(mnt, lazy ? UMOUNT_DETACH : 0);
1414  if (res == -1 && !quiet)
1415  fprintf(stderr,
1416  "%s: failed to unmount %s: %s\n",
1417  progname, mnt, strerror(errno));
1418  }
1419  if (res == -1)
1420  goto err_out;
1421 
1422 success_out:
1423  free(mnt);
1424  return 0;
1425 
1426 err_out:
1427  free(mnt);
1428  exit(1);
1429 }