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