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