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  0x58465342 /* XFS_SB_MAGIC */,
1046  0x2FC12FC1 /* ZFS_SUPER_MAGIC */,
1047  };
1048  for (i = 0; i < sizeof(f_type_whitelist)/sizeof(f_type_whitelist[0]); i++) {
1049  if (f_type_whitelist[i] == fs_buf.f_type)
1050  return 0;
1051  }
1052 
1053  fprintf(stderr, "%s: mounting over filesystem type %#010lx is forbidden\n",
1054  progname, (unsigned long)fs_buf.f_type);
1055  return -1;
1056 }
1057 
1058 static int try_open(const char *dev, char **devp, int silent)
1059 {
1060  int fd = open(dev, O_RDWR);
1061  if (fd != -1) {
1062  *devp = strdup(dev);
1063  if (*devp == NULL) {
1064  fprintf(stderr, "%s: failed to allocate memory\n",
1065  progname);
1066  close(fd);
1067  fd = -1;
1068  }
1069  } else if (errno == ENODEV ||
1070  errno == ENOENT)/* check for ENOENT too, for the udev case */
1071  return -2;
1072  else if (!silent) {
1073  fprintf(stderr, "%s: failed to open %s: %s\n", progname, dev,
1074  strerror(errno));
1075  }
1076  return fd;
1077 }
1078 
1079 static int try_open_fuse_device(char **devp)
1080 {
1081  int fd;
1082 
1083  drop_privs();
1084  fd = try_open(FUSE_DEV, devp, 0);
1085  restore_privs();
1086  return fd;
1087 }
1088 
1089 static int open_fuse_device(char **devp)
1090 {
1091  int fd = try_open_fuse_device(devp);
1092  if (fd >= -1)
1093  return fd;
1094 
1095  fprintf(stderr,
1096  "%s: fuse device not found, try 'modprobe fuse' first\n",
1097  progname);
1098 
1099  return -1;
1100 }
1101 
1102 
1103 static int mount_fuse(const char *mnt, const char *opts, const char **type)
1104 {
1105  int res;
1106  int fd;
1107  char *dev;
1108  struct stat stbuf;
1109  char *source = NULL;
1110  char *mnt_opts = NULL;
1111  const char *real_mnt = mnt;
1112  int mountpoint_fd = -1;
1113 
1114  fd = open_fuse_device(&dev);
1115  if (fd == -1)
1116  return -1;
1117 
1118  drop_privs();
1119  read_conf();
1120 
1121  if (getuid() != 0 && mount_max != -1) {
1122  int mount_count = count_fuse_fs();
1123  if (mount_count >= mount_max) {
1124  fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in %s\n", progname, FUSE_CONF);
1125  goto fail_close_fd;
1126  }
1127  }
1128 
1129  res = check_perm(&real_mnt, &stbuf, &mountpoint_fd);
1130  restore_privs();
1131  if (res != -1)
1132  res = do_mount(real_mnt, type, stbuf.st_mode & S_IFMT,
1133  fd, opts, dev, &source, &mnt_opts);
1134 
1135  if (mountpoint_fd != -1)
1136  close(mountpoint_fd);
1137 
1138  if (res == -1)
1139  goto fail_close_fd;
1140 
1141  res = chdir("/");
1142  if (res == -1) {
1143  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1144  goto fail_close_fd;
1145  }
1146 
1147  if (geteuid() == 0) {
1148  res = add_mount(source, mnt, *type, mnt_opts);
1149  if (res == -1) {
1150  /* Can't clean up mount in a non-racy way */
1151  goto fail_close_fd;
1152  }
1153  }
1154 
1155 out_free:
1156  free(source);
1157  free(mnt_opts);
1158  free(dev);
1159 
1160  return fd;
1161 
1162 fail_close_fd:
1163  close(fd);
1164  fd = -1;
1165  goto out_free;
1166 }
1167 
1168 static int send_fd(int sock_fd, int fd)
1169 {
1170  int retval;
1171  struct msghdr msg;
1172  struct cmsghdr *p_cmsg;
1173  struct iovec vec;
1174  size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
1175  int *p_fds;
1176  char sendchar = 0;
1177 
1178  msg.msg_control = cmsgbuf;
1179  msg.msg_controllen = sizeof(cmsgbuf);
1180  p_cmsg = CMSG_FIRSTHDR(&msg);
1181  p_cmsg->cmsg_level = SOL_SOCKET;
1182  p_cmsg->cmsg_type = SCM_RIGHTS;
1183  p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
1184  p_fds = (int *) CMSG_DATA(p_cmsg);
1185  *p_fds = fd;
1186  msg.msg_controllen = p_cmsg->cmsg_len;
1187  msg.msg_name = NULL;
1188  msg.msg_namelen = 0;
1189  msg.msg_iov = &vec;
1190  msg.msg_iovlen = 1;
1191  msg.msg_flags = 0;
1192  /* "To pass file descriptors or credentials you need to send/read at
1193  * least one byte" (man 7 unix) */
1194  vec.iov_base = &sendchar;
1195  vec.iov_len = sizeof(sendchar);
1196  while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
1197  if (retval != 1) {
1198  perror("sending file descriptor");
1199  return -1;
1200  }
1201  return 0;
1202 }
1203 
1204 /* The parent fuse process has died: decide whether to auto_unmount.
1205  *
1206  * In the normal case (umount or fusermount -u), the filesystem
1207  * has already been unmounted. If we simply unmount again we can
1208  * cause problems with stacked mounts (e.g. autofs).
1209  *
1210  * So we unmount here only in abnormal case where fuse process has
1211  * died without unmount happening. To detect this, we first look in
1212  * the mount table to make sure the mountpoint is still mounted and
1213  * has proper type. If so, we then see if opening the mount dir is
1214  * returning 'Transport endpoint is not connected'.
1215  *
1216  * The order of these is important, because if autofs is in use,
1217  * opening the dir to check for ENOTCONN will cause a new mount
1218  * in the normal case where filesystem has been unmounted cleanly.
1219  */
1220 static int should_auto_unmount(const char *mnt, const char *type)
1221 {
1222  char *copy;
1223  const char *last;
1224  int result = 0;
1225  int fd;
1226 
1227  copy = strdup(mnt);
1228  if (copy == NULL) {
1229  fprintf(stderr, "%s: failed to allocate memory\n", progname);
1230  return 0;
1231  }
1232 
1233  if (chdir_to_parent(copy, &last) == -1)
1234  goto out;
1235  if (check_is_mount(last, mnt, type) == -1)
1236  goto out;
1237 
1238  fd = open(mnt, O_RDONLY);
1239  if (fd != -1) {
1240  close(fd);
1241  } else {
1242  result = errno == ENOTCONN;
1243  }
1244 out:
1245  free(copy);
1246  return result;
1247 }
1248 
1249 static void usage(void)
1250 {
1251  printf("%s: [options] mountpoint\n"
1252  "Options:\n"
1253  " -h print help\n"
1254  " -V print version\n"
1255  " -o opt[,opt...] mount options\n"
1256  " -u unmount\n"
1257  " -q quiet\n"
1258  " -z lazy unmount\n",
1259  progname);
1260  exit(1);
1261 }
1262 
1263 static void show_version(void)
1264 {
1265  printf("fusermount3 version: %s\n", PACKAGE_VERSION);
1266  exit(0);
1267 }
1268 
1269 int main(int argc, char *argv[])
1270 {
1271  sigset_t sigset;
1272  int ch;
1273  int fd;
1274  int res;
1275  char *origmnt;
1276  char *mnt;
1277  static int unmount = 0;
1278  static int lazy = 0;
1279  static int quiet = 0;
1280  char *commfd;
1281  int cfd;
1282  const char *opts = "";
1283  const char *type = NULL;
1284 
1285  static const struct option long_opts[] = {
1286  {"unmount", no_argument, NULL, 'u'},
1287  {"lazy", no_argument, NULL, 'z'},
1288  {"quiet", no_argument, NULL, 'q'},
1289  {"help", no_argument, NULL, 'h'},
1290  {"version", no_argument, NULL, 'V'},
1291  {0, 0, 0, 0}};
1292 
1293  progname = strdup(argv[0]);
1294  if (progname == NULL) {
1295  fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
1296  exit(1);
1297  }
1298 
1299  while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
1300  NULL)) != -1) {
1301  switch (ch) {
1302  case 'h':
1303  usage();
1304  break;
1305 
1306  case 'V':
1307  show_version();
1308  break;
1309 
1310  case 'o':
1311  opts = optarg;
1312  break;
1313 
1314  case 'u':
1315  unmount = 1;
1316  break;
1317 
1318  case 'z':
1319  lazy = 1;
1320  break;
1321 
1322  case 'q':
1323  quiet = 1;
1324  break;
1325 
1326  default:
1327  exit(1);
1328  }
1329  }
1330 
1331  if (lazy && !unmount) {
1332  fprintf(stderr, "%s: -z can only be used with -u\n", progname);
1333  exit(1);
1334  }
1335 
1336  if (optind >= argc) {
1337  fprintf(stderr, "%s: missing mountpoint argument\n", progname);
1338  exit(1);
1339  } else if (argc > optind + 1) {
1340  fprintf(stderr, "%s: extra arguments after the mountpoint\n",
1341  progname);
1342  exit(1);
1343  }
1344 
1345  origmnt = argv[optind];
1346 
1347  drop_privs();
1348  mnt = fuse_mnt_resolve_path(progname, origmnt);
1349  if (mnt != NULL) {
1350  res = chdir("/");
1351  if (res == -1) {
1352  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1353  goto err_out;
1354  }
1355  }
1356  restore_privs();
1357  if (mnt == NULL)
1358  exit(1);
1359 
1360  umask(033);
1361  if (unmount)
1362  goto do_unmount;
1363 
1364  commfd = getenv(FUSE_COMMFD_ENV);
1365  if (commfd == NULL) {
1366  fprintf(stderr, "%s: old style mounting not supported\n",
1367  progname);
1368  goto err_out;
1369  }
1370 
1371  fd = mount_fuse(mnt, opts, &type);
1372  if (fd == -1)
1373  goto err_out;
1374 
1375  cfd = atoi(commfd);
1376  res = send_fd(cfd, fd);
1377  if (res == -1)
1378  goto err_out;
1379  close(fd);
1380 
1381  if (!auto_unmount) {
1382  free(mnt);
1383  return 0;
1384  }
1385 
1386  /* Become a daemon and wait for the parent to exit or die.
1387  ie For the control socket to get closed.
1388  btw We don't want to use daemon() function here because
1389  it forks and messes with the file descriptors. */
1390  setsid();
1391  res = chdir("/");
1392  if (res == -1) {
1393  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1394  goto err_out;
1395  }
1396 
1397  sigfillset(&sigset);
1398  sigprocmask(SIG_BLOCK, &sigset, NULL);
1399 
1400  lazy = 1;
1401  quiet = 1;
1402 
1403  while (1) {
1404  unsigned char buf[16];
1405  int n = recv(cfd, buf, sizeof(buf), 0);
1406  if (!n)
1407  break;
1408 
1409  if (n < 0) {
1410  if (errno == EINTR)
1411  continue;
1412  break;
1413  }
1414  }
1415 
1416  if (!should_auto_unmount(mnt, type)) {
1417  goto success_out;
1418  }
1419 
1420 do_unmount:
1421  if (geteuid() == 0)
1422  res = unmount_fuse(mnt, quiet, lazy);
1423  else {
1424  res = umount2(mnt, lazy ? UMOUNT_DETACH : 0);
1425  if (res == -1 && !quiet)
1426  fprintf(stderr,
1427  "%s: failed to unmount %s: %s\n",
1428  progname, mnt, strerror(errno));
1429  }
1430  if (res == -1)
1431  goto err_out;
1432 
1433 success_out:
1434  free(mnt);
1435  return 0;
1436 
1437 err_out:
1438  free(mnt);
1439  exit(1);
1440 }