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 GPL.
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 "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 /* Check whether the kernel supports UMOUNT_NOFOLLOW flag */
401 static int umount_nofollow_support(void)
402 {
403  int res = umount2("", UMOUNT_UNUSED);
404  if (res != -1 || errno != EINVAL)
405  return 0;
406 
407  res = umount2("", UMOUNT_NOFOLLOW);
408  if (res != -1 || errno != ENOENT)
409  return 0;
410 
411  return 1;
412 }
413 
414 static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
415 {
416  int res;
417  char *copy;
418  const char *last;
419  int umount_flags = lazy ? UMOUNT_DETACH : 0;
420 
421  if (getuid() != 0) {
422  res = may_unmount(mnt, quiet);
423  if (res == -1)
424  return -1;
425  }
426 
427  copy = strdup(mnt);
428  if (copy == NULL) {
429  fprintf(stderr, "%s: failed to allocate memory\n", progname);
430  return -1;
431  }
432 
433  drop_privs();
434  res = chdir_to_parent(copy, &last);
435  restore_privs();
436  if (res == -1)
437  goto out;
438 
439  if (umount_nofollow_support()) {
440  umount_flags |= UMOUNT_NOFOLLOW;
441  } else {
442  res = check_is_mount(last, mnt, NULL);
443  if (res == -1)
444  goto out;
445  }
446 
447  res = umount2(last, umount_flags);
448  if (res == -1 && !quiet) {
449  fprintf(stderr, "%s: failed to unmount %s: %s\n",
450  progname, mnt, strerror(errno));
451  }
452 
453 out:
454  free(copy);
455  if (res == -1)
456  return -1;
457 
458  res = chdir("/");
459  if (res == -1) {
460  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
461  return -1;
462  }
463 
464  return fuse_mnt_remove_mount(progname, mnt);
465 }
466 
467 static int unmount_fuse(const char *mnt, int quiet, int lazy)
468 {
469  int res;
470  int mtablock = lock_umount();
471 
472  res = unmount_fuse_locked(mnt, quiet, lazy);
473  unlock_umount(mtablock);
474 
475  return res;
476 }
477 
478 static int count_fuse_fs(void)
479 {
480  struct mntent *entp;
481  int count = 0;
482  const char *mtab = _PATH_MOUNTED;
483  FILE *fp = setmntent(mtab, "r");
484  if (fp == NULL) {
485  fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
486  strerror(errno));
487  return -1;
488  }
489  while ((entp = getmntent(fp)) != NULL) {
490  if (strcmp(entp->mnt_type, "fuse") == 0 ||
491  strncmp(entp->mnt_type, "fuse.", 5) == 0)
492  count ++;
493  }
494  endmntent(fp);
495  return count;
496 }
497 
498 
499 #else /* IGNORE_MTAB */
500 static int count_fuse_fs(void)
501 {
502  return 0;
503 }
504 
505 static int add_mount(const char *source, const char *mnt, const char *type,
506  const char *opts)
507 {
508  (void) source;
509  (void) mnt;
510  (void) type;
511  (void) opts;
512  return 0;
513 }
514 
515 static int unmount_fuse(const char *mnt, int quiet, int lazy)
516 {
517  (void) quiet;
518  return fuse_mnt_umount(progname, mnt, mnt, lazy);
519 }
520 #endif /* IGNORE_MTAB */
521 
522 static void strip_line(char *line)
523 {
524  char *s = strchr(line, '#');
525  if (s != NULL)
526  s[0] = '\0';
527  for (s = line + strlen(line) - 1;
528  s >= line && isspace((unsigned char) *s); s--);
529  s[1] = '\0';
530  for (s = line; isspace((unsigned char) *s); s++);
531  if (s != line)
532  memmove(line, s, strlen(s)+1);
533 }
534 
535 static void parse_line(char *line, int linenum)
536 {
537  int tmp;
538  if (strcmp(line, "user_allow_other") == 0)
539  user_allow_other = 1;
540  else if (sscanf(line, "mount_max = %i", &tmp) == 1)
541  mount_max = tmp;
542  else if(line[0])
543  fprintf(stderr,
544  "%s: unknown parameter in %s at line %i: '%s'\n",
545  progname, FUSE_CONF, linenum, line);
546 }
547 
548 static void read_conf(void)
549 {
550  FILE *fp = fopen(FUSE_CONF, "r");
551  if (fp != NULL) {
552  int linenum = 1;
553  char line[256];
554  int isnewline = 1;
555  while (fgets(line, sizeof(line), fp) != NULL) {
556  if (isnewline) {
557  if (line[strlen(line)-1] == '\n') {
558  strip_line(line);
559  parse_line(line, linenum);
560  } else {
561  isnewline = 0;
562  }
563  } else if(line[strlen(line)-1] == '\n') {
564  fprintf(stderr, "%s: reading %s: line %i too long\n", progname, FUSE_CONF, linenum);
565 
566  isnewline = 1;
567  }
568  if (isnewline)
569  linenum ++;
570  }
571  if (!isnewline) {
572  fprintf(stderr, "%s: reading %s: missing newline at end of file\n", progname, FUSE_CONF);
573 
574  }
575  if (ferror(fp)) {
576  fprintf(stderr, "%s: reading %s: read failed\n", progname, FUSE_CONF);
577  exit(1);
578  }
579  fclose(fp);
580  } else if (errno != ENOENT) {
581  bool fatal = (errno != EACCES && errno != ELOOP &&
582  errno != ENAMETOOLONG && errno != ENOTDIR &&
583  errno != EOVERFLOW);
584  fprintf(stderr, "%s: failed to open %s: %s\n",
585  progname, FUSE_CONF, strerror(errno));
586  if (fatal)
587  exit(1);
588  }
589 }
590 
591 static int begins_with(const char *s, const char *beg)
592 {
593  if (strncmp(s, beg, strlen(beg)) == 0)
594  return 1;
595  else
596  return 0;
597 }
598 
599 struct mount_flags {
600  const char *opt;
601  unsigned long flag;
602  int on;
603  int safe;
604 };
605 
606 static struct mount_flags mount_flags[] = {
607  {"rw", MS_RDONLY, 0, 1},
608  {"ro", MS_RDONLY, 1, 1},
609  {"suid", MS_NOSUID, 0, 0},
610  {"nosuid", MS_NOSUID, 1, 1},
611  {"dev", MS_NODEV, 0, 0},
612  {"nodev", MS_NODEV, 1, 1},
613  {"exec", MS_NOEXEC, 0, 1},
614  {"noexec", MS_NOEXEC, 1, 1},
615  {"async", MS_SYNCHRONOUS, 0, 1},
616  {"sync", MS_SYNCHRONOUS, 1, 1},
617  {"atime", MS_NOATIME, 0, 1},
618  {"noatime", MS_NOATIME, 1, 1},
619  {"dirsync", MS_DIRSYNC, 1, 1},
620  {NULL, 0, 0, 0}
621 };
622 
623 static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
624 {
625  int i;
626 
627  for (i = 0; mount_flags[i].opt != NULL; i++) {
628  const char *opt = mount_flags[i].opt;
629  if (strlen(opt) == len && strncmp(opt, s, len) == 0) {
630  *on = mount_flags[i].on;
631  *flag = mount_flags[i].flag;
632  if (!mount_flags[i].safe && getuid() != 0) {
633  *flag = 0;
634  fprintf(stderr,
635  "%s: unsafe option %s ignored\n",
636  progname, opt);
637  }
638  return 1;
639  }
640  }
641  return 0;
642 }
643 
644 static int add_option(char **optsp, const char *opt, unsigned expand)
645 {
646  char *newopts;
647  if (*optsp == NULL)
648  newopts = strdup(opt);
649  else {
650  unsigned oldsize = strlen(*optsp);
651  unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;
652  newopts = (char *) realloc(*optsp, newsize);
653  if (newopts)
654  sprintf(newopts + oldsize, ",%s", opt);
655  }
656  if (newopts == NULL) {
657  fprintf(stderr, "%s: failed to allocate memory\n", progname);
658  return -1;
659  }
660  *optsp = newopts;
661  return 0;
662 }
663 
664 static int get_mnt_opts(int flags, char *opts, char **mnt_optsp)
665 {
666  int i;
667  int l;
668 
669  if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1)
670  return -1;
671 
672  for (i = 0; mount_flags[i].opt != NULL; i++) {
673  if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
674  add_option(mnt_optsp, mount_flags[i].opt, 0) == -1)
675  return -1;
676  }
677 
678  if (add_option(mnt_optsp, opts, 0) == -1)
679  return -1;
680  /* remove comma from end of opts*/
681  l = strlen(*mnt_optsp);
682  if ((*mnt_optsp)[l-1] == ',')
683  (*mnt_optsp)[l-1] = '\0';
684  if (getuid() != 0) {
685  const char *user = get_user_name();
686  if (user == NULL)
687  return -1;
688 
689  if (add_option(mnt_optsp, "user=", strlen(user)) == -1)
690  return -1;
691  strcat(*mnt_optsp, user);
692  }
693  return 0;
694 }
695 
696 static int opt_eq(const char *s, unsigned len, const char *opt)
697 {
698  if(strlen(opt) == len && strncmp(s, opt, len) == 0)
699  return 1;
700  else
701  return 0;
702 }
703 
704 static int get_string_opt(const char *s, unsigned len, const char *opt,
705  char **val)
706 {
707  int i;
708  unsigned opt_len = strlen(opt);
709  char *d;
710 
711  if (*val)
712  free(*val);
713  *val = (char *) malloc(len - opt_len + 1);
714  if (!*val) {
715  fprintf(stderr, "%s: failed to allocate memory\n", progname);
716  return 0;
717  }
718 
719  d = *val;
720  s += opt_len;
721  len -= opt_len;
722  for (i = 0; i < len; i++) {
723  if (s[i] == '\\' && i + 1 < len)
724  i++;
725  *d++ = s[i];
726  }
727  *d = '\0';
728  return 1;
729 }
730 
731 /* The kernel silently truncates the "data" argument to PAGE_SIZE-1 characters.
732  * This can be dangerous if it e.g. truncates the option "group_id=1000" to
733  * "group_id=1".
734  * This wrapper detects this case and bails out with an error.
735  */
736 static int mount_notrunc(const char *source, const char *target,
737  const char *filesystemtype, unsigned long mountflags,
738  const char *data) {
739  if (strlen(data) > sysconf(_SC_PAGESIZE) - 1) {
740  fprintf(stderr, "%s: mount options too long\n", progname);
741  errno = EINVAL;
742  return -1;
743  }
744  return mount(source, target, filesystemtype, mountflags, data);
745 }
746 
747 
748 static int do_mount(const char *mnt, const char **typep, mode_t rootmode,
749  int fd, const char *opts, const char *dev, char **sourcep,
750  char **mnt_optsp)
751 {
752  int res;
753  int flags = MS_NOSUID | MS_NODEV;
754  char *optbuf;
755  char *mnt_opts = NULL;
756  const char *s;
757  char *d;
758  char *fsname = NULL;
759  char *subtype = NULL;
760  char *source = NULL;
761  char *type = NULL;
762  int blkdev = 0;
763 
764  optbuf = (char *) malloc(strlen(opts) + 128);
765  if (!optbuf) {
766  fprintf(stderr, "%s: failed to allocate memory\n", progname);
767  return -1;
768  }
769 
770  for (s = opts, d = optbuf; *s;) {
771  unsigned len;
772  const char *fsname_str = "fsname=";
773  const char *subtype_str = "subtype=";
774  bool escape_ok = begins_with(s, fsname_str) ||
775  begins_with(s, subtype_str);
776  for (len = 0; s[len]; len++) {
777  if (escape_ok && s[len] == '\\' && s[len + 1])
778  len++;
779  else if (s[len] == ',')
780  break;
781  }
782  if (begins_with(s, fsname_str)) {
783  if (!get_string_opt(s, len, fsname_str, &fsname))
784  goto err;
785  } else if (begins_with(s, subtype_str)) {
786  if (!get_string_opt(s, len, subtype_str, &subtype))
787  goto err;
788  } else if (opt_eq(s, len, "blkdev")) {
789  if (getuid() != 0) {
790  fprintf(stderr,
791  "%s: option blkdev is privileged\n",
792  progname);
793  goto err;
794  }
795  blkdev = 1;
796  } else if (opt_eq(s, len, "auto_unmount")) {
797  auto_unmount = 1;
798  } else if (!begins_with(s, "fd=") &&
799  !begins_with(s, "rootmode=") &&
800  !begins_with(s, "user_id=") &&
801  !begins_with(s, "group_id=")) {
802  int on;
803  int flag;
804  int skip_option = 0;
805  if (opt_eq(s, len, "large_read")) {
806  struct utsname utsname;
807  unsigned kmaj, kmin;
808  res = uname(&utsname);
809  if (res == 0 &&
810  sscanf(utsname.release, "%u.%u",
811  &kmaj, &kmin) == 2 &&
812  (kmaj > 2 || (kmaj == 2 && kmin > 4))) {
813  fprintf(stderr, "%s: note: 'large_read' mount option is deprecated for %i.%i kernels\n", progname, kmaj, kmin);
814  skip_option = 1;
815  }
816  }
817  if (getuid() != 0 && !user_allow_other &&
818  (opt_eq(s, len, "allow_other") ||
819  opt_eq(s, len, "allow_root"))) {
820  fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in %s\n", progname, len, s, FUSE_CONF);
821  goto err;
822  }
823  if (!skip_option) {
824  if (find_mount_flag(s, len, &on, &flag)) {
825  if (on)
826  flags |= flag;
827  else
828  flags &= ~flag;
829  } else if (opt_eq(s, len, "default_permissions") ||
830  opt_eq(s, len, "allow_other") ||
831  begins_with(s, "max_read=") ||
832  begins_with(s, "blksize=")) {
833  memcpy(d, s, len);
834  d += len;
835  *d++ = ',';
836  } else {
837  fprintf(stderr, "%s: unknown option '%.*s'\n", progname, len, s);
838  exit(1);
839  }
840  }
841  }
842  s += len;
843  if (*s)
844  s++;
845  }
846  *d = '\0';
847  res = get_mnt_opts(flags, optbuf, &mnt_opts);
848  if (res == -1)
849  goto err;
850 
851  sprintf(d, "fd=%i,rootmode=%o,user_id=%u,group_id=%u",
852  fd, rootmode, getuid(), getgid());
853 
854  source = malloc((fsname ? strlen(fsname) : 0) +
855  (subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
856 
857  type = malloc((subtype ? strlen(subtype) : 0) + 32);
858  if (!type || !source) {
859  fprintf(stderr, "%s: failed to allocate memory\n", progname);
860  goto err;
861  }
862 
863  if (subtype)
864  sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
865  else
866  strcpy(type, blkdev ? "fuseblk" : "fuse");
867 
868  if (fsname)
869  strcpy(source, fsname);
870  else
871  strcpy(source, subtype ? subtype : dev);
872 
873  res = mount_notrunc(source, mnt, type, flags, optbuf);
874  if (res == -1 && errno == ENODEV && subtype) {
875  /* Probably missing subtype support */
876  strcpy(type, blkdev ? "fuseblk" : "fuse");
877  if (fsname) {
878  if (!blkdev)
879  sprintf(source, "%s#%s", subtype, fsname);
880  } else {
881  strcpy(source, type);
882  }
883 
884  res = mount_notrunc(source, mnt, type, flags, optbuf);
885  }
886  if (res == -1 && errno == EINVAL) {
887  /* It could be an old version not supporting group_id */
888  sprintf(d, "fd=%i,rootmode=%o,user_id=%u",
889  fd, rootmode, getuid());
890  res = mount_notrunc(source, mnt, type, flags, optbuf);
891  }
892  if (res == -1) {
893  int errno_save = errno;
894  if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
895  fprintf(stderr, "%s: 'fuseblk' support missing\n",
896  progname);
897  else
898  fprintf(stderr, "%s: mount failed: %s\n", progname,
899  strerror(errno_save));
900  goto err;
901  }
902  *sourcep = source;
903  *typep = type;
904  *mnt_optsp = mnt_opts;
905  free(fsname);
906  free(optbuf);
907 
908  return 0;
909 
910 err:
911  free(fsname);
912  free(subtype);
913  free(source);
914  free(type);
915  free(mnt_opts);
916  free(optbuf);
917  return -1;
918 }
919 
920 static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd)
921 {
922  int res;
923  const char *mnt = *mntp;
924  const char *origmnt = mnt;
925  struct statfs fs_buf;
926  size_t i;
927 
928  res = lstat(mnt, stbuf);
929  if (res == -1) {
930  fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
931  progname, mnt, strerror(errno));
932  return -1;
933  }
934 
935  /* No permission checking is done for root */
936  if (getuid() == 0)
937  return 0;
938 
939  if (S_ISDIR(stbuf->st_mode)) {
940  res = chdir(mnt);
941  if (res == -1) {
942  fprintf(stderr,
943  "%s: failed to chdir to mountpoint: %s\n",
944  progname, strerror(errno));
945  return -1;
946  }
947  mnt = *mntp = ".";
948  res = lstat(mnt, stbuf);
949  if (res == -1) {
950  fprintf(stderr,
951  "%s: failed to access mountpoint %s: %s\n",
952  progname, origmnt, strerror(errno));
953  return -1;
954  }
955 
956  if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
957  fprintf(stderr, "%s: mountpoint %s not owned by user\n",
958  progname, origmnt);
959  return -1;
960  }
961 
962  res = access(mnt, W_OK);
963  if (res == -1) {
964  fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
965  progname, origmnt);
966  return -1;
967  }
968  } else if (S_ISREG(stbuf->st_mode)) {
969  static char procfile[256];
970  *mountpoint_fd = open(mnt, O_WRONLY);
971  if (*mountpoint_fd == -1) {
972  fprintf(stderr, "%s: failed to open %s: %s\n",
973  progname, mnt, strerror(errno));
974  return -1;
975  }
976  res = fstat(*mountpoint_fd, stbuf);
977  if (res == -1) {
978  fprintf(stderr,
979  "%s: failed to access mountpoint %s: %s\n",
980  progname, mnt, strerror(errno));
981  return -1;
982  }
983  if (!S_ISREG(stbuf->st_mode)) {
984  fprintf(stderr,
985  "%s: mountpoint %s is no longer a regular file\n",
986  progname, mnt);
987  return -1;
988  }
989 
990  sprintf(procfile, "/proc/self/fd/%i", *mountpoint_fd);
991  *mntp = procfile;
992  } else {
993  fprintf(stderr,
994  "%s: mountpoint %s is not a directory or a regular file\n",
995  progname, mnt);
996  return -1;
997  }
998 
999  /* Do not permit mounting over anything in procfs - it has a couple
1000  * places to which we have "write access" without being supposed to be
1001  * able to just put anything we want there.
1002  * Luckily, without allow_other, we can't get other users to actually
1003  * use any fake information we try to put there anyway.
1004  * Use a whitelist to be safe. */
1005  if (statfs(*mntp, &fs_buf)) {
1006  fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
1007  progname, mnt, strerror(errno));
1008  return -1;
1009  }
1010 
1011  /* Define permitted filesystems for the mount target. This was
1012  * originally the same list as used by the ecryptfs mount helper
1013  * (https://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/view/head:/src/utils/mount.ecryptfs_private.c#L225)
1014  * but got expanded as we found more filesystems that needed to be
1015  * overlayed. */
1016  typeof(fs_buf.f_type) f_type_whitelist[] = {
1017  0x61756673 /* AUFS_SUPER_MAGIC */,
1018  0x00000187 /* AUTOFS_SUPER_MAGIC */,
1019  0xCA451A4E /* BCACHEFS_STATFS_MAGIC */,
1020  0x9123683E /* BTRFS_SUPER_MAGIC */,
1021  0x00C36400 /* CEPH_SUPER_MAGIC */,
1022  0xFF534D42 /* CIFS_MAGIC_NUMBER */,
1023  0x0000F15F /* ECRYPTFS_SUPER_MAGIC */,
1024  0x0000EF53 /* EXT[234]_SUPER_MAGIC */,
1025  0xF2F52010 /* F2FS_SUPER_MAGIC */,
1026  0x65735546 /* FUSE_SUPER_MAGIC */,
1027  0x01161970 /* GFS2_MAGIC */,
1028  0x47504653 /* GPFS_SUPER_MAGIC */,
1029  0x0000482b /* HFSPLUS_SUPER_MAGIC */,
1030  0x000072B6 /* JFFS2_SUPER_MAGIC */,
1031  0x3153464A /* JFS_SUPER_MAGIC */,
1032  0x0BD00BD0 /* LL_SUPER_MAGIC */,
1033  0X00004D44 /* MSDOS_SUPER_MAGIC */,
1034  0x0000564C /* NCP_SUPER_MAGIC */,
1035  0x00006969 /* NFS_SUPER_MAGIC */,
1036  0x00003434 /* NILFS_SUPER_MAGIC */,
1037  0x5346544E /* NTFS_SB_MAGIC */,
1038  0x5346414f /* OPENAFS_SUPER_MAGIC */,
1039  0x794C7630 /* OVERLAYFS_SUPER_MAGIC */,
1040  0x52654973 /* REISERFS_SUPER_MAGIC */,
1041  0xFE534D42 /* SMB2_SUPER_MAGIC */,
1042  0x73717368 /* SQUASHFS_MAGIC */,
1043  0x01021994 /* TMPFS_MAGIC */,
1044  0x24051905 /* UBIFS_SUPER_MAGIC */,
1045  0x736675005346544e /* UFSD */,
1046  0x58465342 /* XFS_SB_MAGIC */,
1047  0x2FC12FC1 /* ZFS_SUPER_MAGIC */,
1048  };
1049  for (i = 0; i < sizeof(f_type_whitelist)/sizeof(f_type_whitelist[0]); i++) {
1050  if (f_type_whitelist[i] == fs_buf.f_type)
1051  return 0;
1052  }
1053 
1054  fprintf(stderr, "%s: mounting over filesystem type %#010lx is forbidden\n",
1055  progname, (unsigned long)fs_buf.f_type);
1056  return -1;
1057 }
1058 
1059 static int try_open(const char *dev, char **devp, int silent)
1060 {
1061  int fd = open(dev, O_RDWR);
1062  if (fd != -1) {
1063  *devp = strdup(dev);
1064  if (*devp == NULL) {
1065  fprintf(stderr, "%s: failed to allocate memory\n",
1066  progname);
1067  close(fd);
1068  fd = -1;
1069  }
1070  } else if (errno == ENODEV ||
1071  errno == ENOENT)/* check for ENOENT too, for the udev case */
1072  return -2;
1073  else if (!silent) {
1074  fprintf(stderr, "%s: failed to open %s: %s\n", progname, dev,
1075  strerror(errno));
1076  }
1077  return fd;
1078 }
1079 
1080 static int try_open_fuse_device(char **devp)
1081 {
1082  int fd;
1083 
1084  drop_privs();
1085  fd = try_open(FUSE_DEV, devp, 0);
1086  restore_privs();
1087  return fd;
1088 }
1089 
1090 static int open_fuse_device(char **devp)
1091 {
1092  int fd = try_open_fuse_device(devp);
1093  if (fd >= -1)
1094  return fd;
1095 
1096  fprintf(stderr,
1097  "%s: fuse device not found, try 'modprobe fuse' first\n",
1098  progname);
1099 
1100  return -1;
1101 }
1102 
1103 
1104 static int mount_fuse(const char *mnt, const char *opts, const char **type)
1105 {
1106  int res;
1107  int fd;
1108  char *dev;
1109  struct stat stbuf;
1110  char *source = NULL;
1111  char *mnt_opts = NULL;
1112  const char *real_mnt = mnt;
1113  int mountpoint_fd = -1;
1114 
1115  fd = open_fuse_device(&dev);
1116  if (fd == -1)
1117  return -1;
1118 
1119  drop_privs();
1120  read_conf();
1121 
1122  if (getuid() != 0 && mount_max != -1) {
1123  int mount_count = count_fuse_fs();
1124  if (mount_count >= mount_max) {
1125  fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in %s\n", progname, FUSE_CONF);
1126  goto fail_close_fd;
1127  }
1128  }
1129 
1130  res = check_perm(&real_mnt, &stbuf, &mountpoint_fd);
1131  restore_privs();
1132  if (res != -1)
1133  res = do_mount(real_mnt, type, stbuf.st_mode & S_IFMT,
1134  fd, opts, dev, &source, &mnt_opts);
1135 
1136  if (mountpoint_fd != -1)
1137  close(mountpoint_fd);
1138 
1139  if (res == -1)
1140  goto fail_close_fd;
1141 
1142  res = chdir("/");
1143  if (res == -1) {
1144  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1145  goto fail_close_fd;
1146  }
1147 
1148  if (geteuid() == 0) {
1149  res = add_mount(source, mnt, *type, mnt_opts);
1150  if (res == -1) {
1151  /* Can't clean up mount in a non-racy way */
1152  goto fail_close_fd;
1153  }
1154  }
1155 
1156 out_free:
1157  free(source);
1158  free(mnt_opts);
1159  free(dev);
1160 
1161  return fd;
1162 
1163 fail_close_fd:
1164  close(fd);
1165  fd = -1;
1166  goto out_free;
1167 }
1168 
1169 static int send_fd(int sock_fd, int fd)
1170 {
1171  int retval;
1172  struct msghdr msg;
1173  struct cmsghdr *p_cmsg;
1174  struct iovec vec;
1175  size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
1176  int *p_fds;
1177  char sendchar = 0;
1178 
1179  msg.msg_control = cmsgbuf;
1180  msg.msg_controllen = sizeof(cmsgbuf);
1181  p_cmsg = CMSG_FIRSTHDR(&msg);
1182  p_cmsg->cmsg_level = SOL_SOCKET;
1183  p_cmsg->cmsg_type = SCM_RIGHTS;
1184  p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
1185  p_fds = (int *) CMSG_DATA(p_cmsg);
1186  *p_fds = fd;
1187  msg.msg_controllen = p_cmsg->cmsg_len;
1188  msg.msg_name = NULL;
1189  msg.msg_namelen = 0;
1190  msg.msg_iov = &vec;
1191  msg.msg_iovlen = 1;
1192  msg.msg_flags = 0;
1193  /* "To pass file descriptors or credentials you need to send/read at
1194  * least one byte" (man 7 unix) */
1195  vec.iov_base = &sendchar;
1196  vec.iov_len = sizeof(sendchar);
1197  while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
1198  if (retval != 1) {
1199  perror("sending file descriptor");
1200  return -1;
1201  }
1202  return 0;
1203 }
1204 
1205 /* The parent fuse process has died: decide whether to auto_unmount.
1206  *
1207  * In the normal case (umount or fusermount -u), the filesystem
1208  * has already been unmounted. If we simply unmount again we can
1209  * cause problems with stacked mounts (e.g. autofs).
1210  *
1211  * So we unmount here only in abnormal case where fuse process has
1212  * died without unmount happening. To detect this, we first look in
1213  * the mount table to make sure the mountpoint is still mounted and
1214  * has proper type. If so, we then see if opening the mount dir is
1215  * returning 'Transport endpoint is not connected'.
1216  *
1217  * The order of these is important, because if autofs is in use,
1218  * opening the dir to check for ENOTCONN will cause a new mount
1219  * in the normal case where filesystem has been unmounted cleanly.
1220  */
1221 static int should_auto_unmount(const char *mnt, const char *type)
1222 {
1223  char *copy;
1224  const char *last;
1225  int result = 0;
1226  int fd;
1227 
1228  copy = strdup(mnt);
1229  if (copy == NULL) {
1230  fprintf(stderr, "%s: failed to allocate memory\n", progname);
1231  return 0;
1232  }
1233 
1234  if (chdir_to_parent(copy, &last) == -1)
1235  goto out;
1236  if (check_is_mount(last, mnt, type) == -1)
1237  goto out;
1238 
1239  fd = open(mnt, O_RDONLY);
1240  if (fd != -1) {
1241  close(fd);
1242  } else {
1243  result = errno == ENOTCONN;
1244  }
1245 out:
1246  free(copy);
1247  return result;
1248 }
1249 
1250 static void usage(void)
1251 {
1252  printf("%s: [options] mountpoint\n"
1253  "Options:\n"
1254  " -h print help\n"
1255  " -V print version\n"
1256  " -o opt[,opt...] mount options\n"
1257  " -u unmount\n"
1258  " -q quiet\n"
1259  " -z lazy unmount\n",
1260  progname);
1261  exit(1);
1262 }
1263 
1264 static void show_version(void)
1265 {
1266  printf("fusermount3 version: %s\n", PACKAGE_VERSION);
1267  exit(0);
1268 }
1269 
1270 int main(int argc, char *argv[])
1271 {
1272  sigset_t sigset;
1273  int ch;
1274  int fd;
1275  int res;
1276  char *origmnt;
1277  char *mnt;
1278  static int unmount = 0;
1279  static int lazy = 0;
1280  static int quiet = 0;
1281  char *commfd;
1282  int cfd;
1283  const char *opts = "";
1284  const char *type = NULL;
1285 
1286  static const struct option long_opts[] = {
1287  {"unmount", no_argument, NULL, 'u'},
1288  {"lazy", no_argument, NULL, 'z'},
1289  {"quiet", no_argument, NULL, 'q'},
1290  {"help", no_argument, NULL, 'h'},
1291  {"version", no_argument, NULL, 'V'},
1292  {0, 0, 0, 0}};
1293 
1294  progname = strdup(argv[0]);
1295  if (progname == NULL) {
1296  fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
1297  exit(1);
1298  }
1299 
1300  while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
1301  NULL)) != -1) {
1302  switch (ch) {
1303  case 'h':
1304  usage();
1305  break;
1306 
1307  case 'V':
1308  show_version();
1309  break;
1310 
1311  case 'o':
1312  opts = optarg;
1313  break;
1314 
1315  case 'u':
1316  unmount = 1;
1317  break;
1318 
1319  case 'z':
1320  lazy = 1;
1321  break;
1322 
1323  case 'q':
1324  quiet = 1;
1325  break;
1326 
1327  default:
1328  exit(1);
1329  }
1330  }
1331 
1332  if (lazy && !unmount) {
1333  fprintf(stderr, "%s: -z can only be used with -u\n", progname);
1334  exit(1);
1335  }
1336 
1337  if (optind >= argc) {
1338  fprintf(stderr, "%s: missing mountpoint argument\n", progname);
1339  exit(1);
1340  } else if (argc > optind + 1) {
1341  fprintf(stderr, "%s: extra arguments after the mountpoint\n",
1342  progname);
1343  exit(1);
1344  }
1345 
1346  origmnt = argv[optind];
1347 
1348  drop_privs();
1349  mnt = fuse_mnt_resolve_path(progname, origmnt);
1350  if (mnt != NULL) {
1351  res = chdir("/");
1352  if (res == -1) {
1353  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1354  goto err_out;
1355  }
1356  }
1357  restore_privs();
1358  if (mnt == NULL)
1359  exit(1);
1360 
1361  umask(033);
1362  if (unmount)
1363  goto do_unmount;
1364 
1365  commfd = getenv(FUSE_COMMFD_ENV);
1366  if (commfd == NULL) {
1367  fprintf(stderr, "%s: old style mounting not supported\n",
1368  progname);
1369  goto err_out;
1370  }
1371 
1372  fd = mount_fuse(mnt, opts, &type);
1373  if (fd == -1)
1374  goto err_out;
1375 
1376  cfd = atoi(commfd);
1377  res = send_fd(cfd, fd);
1378  if (res == -1)
1379  goto err_out;
1380  close(fd);
1381 
1382  if (!auto_unmount) {
1383  free(mnt);
1384  return 0;
1385  }
1386 
1387  /* Become a daemon and wait for the parent to exit or die.
1388  ie For the control socket to get closed.
1389  btw We don't want to use daemon() function here because
1390  it forks and messes with the file descriptors. */
1391  setsid();
1392  res = chdir("/");
1393  if (res == -1) {
1394  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1395  goto err_out;
1396  }
1397 
1398  sigfillset(&sigset);
1399  sigprocmask(SIG_BLOCK, &sigset, NULL);
1400 
1401  lazy = 1;
1402  quiet = 1;
1403 
1404  while (1) {
1405  unsigned char buf[16];
1406  int n = recv(cfd, buf, sizeof(buf), 0);
1407  if (!n)
1408  break;
1409 
1410  if (n < 0) {
1411  if (errno == EINTR)
1412  continue;
1413  break;
1414  }
1415  }
1416 
1417  if (!should_auto_unmount(mnt, type)) {
1418  goto success_out;
1419  }
1420 
1421 do_unmount:
1422  if (geteuid() == 0)
1423  res = unmount_fuse(mnt, quiet, lazy);
1424  else {
1425  res = umount2(mnt, lazy ? UMOUNT_DETACH : 0);
1426  if (res == -1 && !quiet)
1427  fprintf(stderr,
1428  "%s: failed to unmount %s: %s\n",
1429  progname, mnt, strerror(errno));
1430  }
1431  if (res == -1)
1432  goto err_out;
1433 
1434 success_out:
1435  free(mnt);
1436  return 0;
1437 
1438 err_out:
1439  free(mnt);
1440  exit(1);
1441 }