1 /* $OpenBSD: fuse.c,v 1.49 2018/07/05 10:57:31 helg Exp $ */ 2 /* 3 * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/wait.h> 19 #include <sys/types.h> 20 #include <sys/ioctl.h> 21 22 #include <miscfs/fuse/fusefs.h> 23 24 #include <errno.h> 25 #include <signal.h> 26 #include <stddef.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <unistd.h> 30 31 #include "fuse_opt.h" 32 #include "fuse_private.h" 33 #include "debug.h" 34 35 static volatile sig_atomic_t sigraised = 0; 36 static volatile sig_atomic_t signum = 0; 37 static struct fuse_context *ictx = NULL; 38 39 enum { 40 KEY_DEBUG, 41 KEY_FOREGROUND, 42 KEY_HELP, 43 KEY_HELP_WITHOUT_HEADER, 44 KEY_VERSION, 45 KEY_MAXREAD, 46 KEY_STUB 47 }; 48 49 /* options supported by fuse_parse_cmdline */ 50 static struct fuse_opt fuse_core_opts[] = { 51 FUSE_OPT_KEY("-d", KEY_DEBUG), 52 FUSE_OPT_KEY("debug", KEY_DEBUG), 53 FUSE_OPT_KEY("-f", KEY_FOREGROUND), 54 FUSE_OPT_KEY("-h", KEY_HELP), 55 FUSE_OPT_KEY("--help", KEY_HELP), 56 FUSE_OPT_KEY("-ho", KEY_HELP_WITHOUT_HEADER), 57 FUSE_OPT_KEY("-s", KEY_STUB), 58 FUSE_OPT_KEY("-V", KEY_VERSION), 59 FUSE_OPT_KEY("--version", KEY_VERSION), 60 FUSE_OPT_END 61 }; 62 63 /* options supported by fuse_new */ 64 #define FUSE_LIB_OPT(o, m) {o, offsetof(struct fuse_config, m), 1} 65 static struct fuse_opt fuse_lib_opts[] = { 66 FUSE_OPT_KEY("ac_attr_timeout=", KEY_STUB), 67 FUSE_OPT_KEY("attr_timeout=", KEY_STUB), 68 FUSE_OPT_KEY("auto_cache", KEY_STUB), 69 FUSE_OPT_KEY("noauto_cache", KEY_STUB), 70 FUSE_OPT_KEY("big_writes", KEY_STUB), 71 FUSE_OPT_KEY("debug", KEY_DEBUG), 72 FUSE_OPT_KEY("-d", KEY_DEBUG), 73 FUSE_OPT_KEY("entry_timeout=", KEY_STUB), 74 FUSE_LIB_OPT("gid=", set_gid), 75 FUSE_LIB_OPT("gid=%u", gid), 76 FUSE_OPT_KEY("hard_remove", KEY_STUB), 77 FUSE_OPT_KEY("intr_signal", KEY_STUB), 78 FUSE_OPT_KEY("kernel_cache", KEY_STUB), 79 FUSE_OPT_KEY("large_read", KEY_STUB), 80 FUSE_OPT_KEY("modules=", KEY_STUB), 81 FUSE_OPT_KEY("negative_timeout=", KEY_STUB), 82 FUSE_OPT_KEY("readdir_ino", KEY_STUB), 83 FUSE_OPT_KEY("relatime", KEY_STUB), 84 FUSE_OPT_KEY("subtype=", KEY_STUB), 85 FUSE_LIB_OPT("uid=", set_uid), 86 FUSE_LIB_OPT("uid=%u", uid), 87 FUSE_LIB_OPT("use_ino", use_ino), 88 FUSE_OPT_KEY("dmask=%o", KEY_STUB), 89 FUSE_OPT_KEY("fmask=%o", KEY_STUB), 90 FUSE_LIB_OPT("umask=", set_mode), 91 FUSE_LIB_OPT("umask=%o", umask), 92 FUSE_OPT_END 93 }; 94 95 /* options supported by fuse_mount */ 96 #define FUSE_MOUNT_OPT(o, m) {o, offsetof(struct fuse_mount_opts, m), 1} 97 static struct fuse_opt fuse_mount_opts[] = { 98 FUSE_MOUNT_OPT("allow_other", allow_other), 99 FUSE_OPT_KEY("allow_root", KEY_STUB), 100 FUSE_OPT_KEY("async_read", KEY_STUB), 101 FUSE_OPT_KEY("blkdev", KEY_STUB), 102 FUSE_OPT_KEY("blksize=", KEY_STUB), 103 FUSE_MOUNT_OPT("default_permissions", def_perms), 104 FUSE_OPT_KEY("direct_io", KEY_STUB), 105 FUSE_MOUNT_OPT("fsname=%s", fsname), 106 FUSE_MOUNT_OPT("max_read=%u", max_read), 107 FUSE_OPT_KEY("max_readahead", KEY_STUB), 108 FUSE_OPT_KEY("max_write", KEY_STUB), 109 FUSE_MOUNT_OPT("noatime", noatime), 110 FUSE_MOUNT_OPT("nonempty", nonempty), 111 FUSE_MOUNT_OPT("-r", rdonly), 112 FUSE_MOUNT_OPT("ro", rdonly), 113 FUSE_OPT_KEY("ro_fallback", KEY_STUB), 114 FUSE_OPT_KEY("sync_read", KEY_STUB), 115 FUSE_OPT_END 116 }; 117 118 static void 119 ifuse_sighdlr(int num) 120 { 121 if (!sigraised || (num == SIGCHLD)) { 122 sigraised = 1; 123 signum = num; 124 } 125 } 126 127 static void 128 ifuse_try_unmount(struct fuse *f) 129 { 130 pid_t child; 131 132 signal(SIGCHLD, ifuse_sighdlr); 133 134 /* unmount in another thread so fuse_loop() doesn't deadlock */ 135 child = fork(); 136 137 if (child < 0) { 138 DPERROR(__func__); 139 return; 140 } 141 142 if (child == 0) { 143 fuse_remove_signal_handlers(fuse_get_session(f)); 144 errno = 0; 145 fuse_unmount(f->fc->dir, f->fc); 146 _exit(errno); 147 } 148 } 149 150 static void 151 ifuse_child_exit(const struct fuse *f) 152 { 153 int status; 154 155 signal(SIGCHLD, SIG_DFL); 156 if (waitpid(WAIT_ANY, &status, WNOHANG) == -1) 157 fprintf(stderr, "fuse: %s\n", strerror(errno)); 158 159 if (WIFEXITED(status) && (WEXITSTATUS(status) != 0)) 160 fprintf(stderr, "fuse: %s: %s\n", 161 f->fc->dir, strerror(WEXITSTATUS(status))); 162 163 sigraised = 0; 164 return; 165 } 166 167 int 168 fuse_loop(struct fuse *fuse) 169 { 170 struct fusebuf fbuf; 171 struct fuse_context ctx; 172 struct fb_ioctl_xch ioexch; 173 struct kevent ev; 174 ssize_t n; 175 int ret; 176 177 if (fuse == NULL) 178 return (-1); 179 180 fuse->fc->kq = kqueue(); 181 if (fuse->fc->kq == -1) 182 return (-1); 183 184 EV_SET(&fuse->fc->event, fuse->fc->fd, EVFILT_READ, EV_ADD | 185 EV_ENABLE, 0, 0, 0); 186 187 while (!fuse->fc->dead) { 188 ret = kevent(fuse->fc->kq, &fuse->fc->event, 1, &ev, 1, NULL); 189 if (ret == -1) { 190 if (errno == EINTR) { 191 switch (signum) { 192 case SIGCHLD: 193 ifuse_child_exit(fuse); 194 break; 195 case SIGHUP: 196 case SIGINT: 197 case SIGTERM: 198 ifuse_try_unmount(fuse); 199 break; 200 default: 201 fprintf(stderr, "%s: %s\n", __func__, 202 strsignal(signum)); 203 } 204 } else 205 DPERROR(__func__); 206 } else if (ret > 0) { 207 n = read(fuse->fc->fd, &fbuf, sizeof(fbuf)); 208 if (n != sizeof(fbuf)) { 209 fprintf(stderr, "%s: bad fusebuf read\n", 210 __func__); 211 return (-1); 212 } 213 214 /* check if there is data something present */ 215 if (fbuf.fb_len) { 216 fbuf.fb_dat = malloc(fbuf.fb_len); 217 if (fbuf.fb_dat == NULL) 218 return (-1); 219 ioexch.fbxch_uuid = fbuf.fb_uuid; 220 ioexch.fbxch_len = fbuf.fb_len; 221 ioexch.fbxch_data = fbuf.fb_dat; 222 223 if (ioctl(fuse->fc->fd, FIOCGETFBDAT, 224 &ioexch)) { 225 free(fbuf.fb_dat); 226 return (-1); 227 } 228 } 229 230 ctx.fuse = fuse; 231 ctx.uid = fbuf.fb_uid; 232 ctx.gid = fbuf.fb_gid; 233 ctx.pid = fbuf.fb_tid; 234 ctx.umask = fbuf.fb_umask; 235 ctx.private_data = fuse->private_data; 236 ictx = &ctx; 237 238 ret = ifuse_exec_opcode(fuse, &fbuf); 239 if (ret) { 240 ictx = NULL; 241 return (-1); 242 } 243 244 n = write(fuse->fc->fd, &fbuf, sizeof(fbuf)); 245 if (fbuf.fb_len) { 246 if (fbuf.fb_dat == NULL) { 247 fprintf(stderr, "%s: fb_dat is Null\n", 248 __func__); 249 return (-1); 250 } 251 ioexch.fbxch_uuid = fbuf.fb_uuid; 252 ioexch.fbxch_len = fbuf.fb_len; 253 ioexch.fbxch_data = fbuf.fb_dat; 254 255 if (ioctl(fuse->fc->fd, FIOCSETFBDAT, &ioexch)) { 256 free(fbuf.fb_dat); 257 return (-1); 258 } 259 free(fbuf.fb_dat); 260 } 261 ictx = NULL; 262 263 if (n != FUSEBUFSIZE) { 264 errno = EINVAL; 265 return (-1); 266 } 267 } 268 } 269 270 return (0); 271 } 272 DEF(fuse_loop); 273 274 struct fuse_chan * 275 fuse_mount(const char *dir, struct fuse_args *args) 276 { 277 struct fusefs_args fargs; 278 struct fuse_mount_opts opts; 279 struct fuse_chan *fc; 280 const char *errcause; 281 int mnt_flags; 282 283 if (dir == NULL) 284 return (NULL); 285 286 fc = calloc(1, sizeof(*fc)); 287 if (fc == NULL) 288 return (NULL); 289 290 fc->dir = realpath(dir, NULL); 291 if (fc->dir == NULL) 292 goto bad; 293 294 if ((fc->fd = open("/dev/fuse0", O_RDWR)) == -1) { 295 perror(__func__); 296 goto bad; 297 } 298 299 memset(&opts, 0, sizeof(opts)); 300 if (fuse_opt_parse(args, &opts, fuse_mount_opts, NULL) == -1) 301 goto bad; 302 303 mnt_flags = 0; 304 if (opts.rdonly) 305 mnt_flags |= MNT_RDONLY; 306 if (opts.noatime) 307 mnt_flags |= MNT_NOATIME; 308 309 if (opts.max_read > FUSEBUFMAXSIZE) { 310 fprintf(stderr, "fuse: invalid max_read (%d > %d)\n", 311 opts.max_read, FUSEBUFMAXSIZE); 312 goto bad; 313 } 314 315 memset(&fargs, 0, sizeof(fargs)); 316 fargs.fd = fc->fd; 317 fargs.max_read = opts.max_read; 318 fargs.allow_other = opts.allow_other; 319 320 if (mount(MOUNT_FUSEFS, fc->dir, mnt_flags, &fargs)) { 321 switch (errno) { 322 case EMFILE: 323 errcause = "mount table full"; 324 break; 325 case EOPNOTSUPP: 326 errcause = "filesystem not supported by kernel"; 327 break; 328 default: 329 errcause = strerror(errno); 330 break; 331 } 332 fprintf(stderr, "%s on %s: %s\n", __func__, dir, errcause); 333 goto bad; 334 } 335 336 return (fc); 337 bad: 338 if (fc->fd != -1) 339 close(fc->fd); 340 free(fc->dir); 341 free(fc); 342 return (NULL); 343 } 344 DEF(fuse_mount); 345 346 void 347 fuse_unmount(const char *dir, struct fuse_chan *ch) 348 { 349 if (ch == NULL || ch->dead) 350 return; 351 352 if (unmount(dir, MNT_UPDATE) == -1) 353 DPERROR(__func__); 354 } 355 DEF(fuse_unmount); 356 357 int 358 fuse_is_lib_option(const char *opt) 359 { 360 return (fuse_opt_match(fuse_lib_opts, opt)); 361 } 362 363 int 364 fuse_chan_fd(struct fuse_chan *ch) 365 { 366 if (ch == NULL) 367 return (-1); 368 369 return (ch->fd); 370 } 371 372 struct fuse_session * 373 fuse_get_session(struct fuse *f) 374 { 375 return (&f->se); 376 } 377 DEF(fuse_get_session); 378 379 int 380 fuse_loop_mt(unused struct fuse *fuse) 381 { 382 return (-1); 383 } 384 385 static int 386 ifuse_lib_opt_proc(void *data, const char *arg, int key, 387 unused struct fuse_args *args) 388 { 389 switch (key) { 390 case KEY_STUB: 391 return (0); 392 case KEY_DEBUG: 393 ifuse_debug_init(); 394 break; 395 default: 396 fprintf(stderr, "fuse: unrecognised option %s\n", arg); 397 return (-1); 398 } 399 400 /* Keep unknown options. */ 401 return (1); 402 } 403 404 struct fuse * 405 fuse_new(struct fuse_chan *fc, struct fuse_args *args, 406 const struct fuse_operations *ops, unused size_t size, 407 void *userdata) 408 { 409 struct fuse *fuse; 410 struct fuse_vnode *root; 411 412 if (fc == NULL || ops == NULL) 413 return (NULL); 414 415 if ((fuse = calloc(1, sizeof(*fuse))) == NULL) 416 return (NULL); 417 418 /* copy fuse ops to their own structure */ 419 memcpy(&fuse->op, ops, sizeof(fuse->op)); 420 421 if (fuse_opt_parse(args, &fuse->conf, fuse_lib_opts, 422 ifuse_lib_opt_proc) == -1) { 423 free(fuse); 424 return (NULL); 425 } 426 427 fuse->fc = fc; 428 fuse->max_ino = FUSE_ROOT_INO; 429 fuse->se.args = fuse; 430 fuse->private_data = userdata; 431 432 if ((root = alloc_vn(fuse, "/", FUSE_ROOT_INO, 0)) == NULL) { 433 free(fuse); 434 return (NULL); 435 } 436 437 tree_init(&fuse->vnode_tree); 438 tree_init(&fuse->name_tree); 439 if (!set_vn(fuse, root)) { 440 free(fuse); 441 return (NULL); 442 } 443 444 return (fuse); 445 } 446 DEF(fuse_new); 447 448 int 449 fuse_daemonize(int foreground) 450 { 451 if (foreground) 452 return (0); 453 454 return (daemon(0, 0)); 455 } 456 DEF(fuse_daemonize); 457 458 void 459 fuse_destroy(struct fuse *f) 460 { 461 if (f == NULL) 462 return; 463 464 /* 465 * Even though these were allocated in fuse_mount(), we can't free them 466 * in fuse_unmount() since fuse_loop() will not have terminated yet so 467 * we free them here. 468 */ 469 close(f->fc->fd); 470 free(f->fc->dir); 471 free(f->fc); 472 free(f); 473 } 474 DEF(fuse_destroy); 475 476 void 477 fuse_remove_signal_handlers(unused struct fuse_session *se) 478 { 479 struct sigaction old_sa; 480 481 if (sigaction(SIGHUP, NULL, &old_sa) == 0) 482 if (old_sa.sa_handler == ifuse_sighdlr) 483 signal(SIGHUP, SIG_DFL); 484 485 if (sigaction(SIGINT, NULL, &old_sa) == 0) 486 if (old_sa.sa_handler == ifuse_sighdlr) 487 signal(SIGINT, SIG_DFL); 488 489 if (sigaction(SIGTERM, NULL, &old_sa) == 0) 490 if (old_sa.sa_handler == ifuse_sighdlr) 491 signal(SIGTERM, SIG_DFL); 492 493 if (sigaction(SIGPIPE, NULL, &old_sa) == 0) 494 if (old_sa.sa_handler == SIG_IGN) 495 signal(SIGPIPE, SIG_DFL); 496 } 497 DEF(fuse_remove_signal_handlers); 498 499 int 500 fuse_set_signal_handlers(unused struct fuse_session *se) 501 { 502 struct sigaction old_sa; 503 504 if (sigaction(SIGHUP, NULL, &old_sa) == -1) 505 return (-1); 506 if (old_sa.sa_handler == SIG_DFL) 507 signal(SIGHUP, ifuse_sighdlr); 508 509 if (sigaction(SIGINT, NULL, &old_sa) == -1) 510 return (-1); 511 if (old_sa.sa_handler == SIG_DFL) 512 signal(SIGINT, ifuse_sighdlr); 513 514 if (sigaction(SIGTERM, NULL, &old_sa) == -1) 515 return (-1); 516 if (old_sa.sa_handler == SIG_DFL) 517 signal(SIGTERM, ifuse_sighdlr); 518 519 if (sigaction(SIGPIPE, NULL, &old_sa) == -1) 520 return (-1); 521 if (old_sa.sa_handler == SIG_DFL) 522 signal(SIGPIPE, SIG_IGN); 523 524 return (0); 525 } 526 527 static void 528 dump_help(void) 529 { 530 fprintf(stderr, "FUSE options:\n" 531 " -d -o debug enable debug output (implies -f)\n" 532 " -f run in foreground\n" 533 " -V --version print fuse version\n" 534 "\n"); 535 } 536 537 static void 538 dump_version(void) 539 { 540 fprintf(stderr, "FUSE library version: %d.%d\n", FUSE_MAJOR_VERSION, 541 FUSE_MINOR_VERSION); 542 } 543 544 static int 545 ifuse_process_opt(void *data, const char *arg, int key, 546 unused struct fuse_args *args) 547 { 548 struct fuse_core_opts *opt = data; 549 struct stat st; 550 int res; 551 552 switch (key) { 553 case KEY_STUB: 554 return (0); 555 case KEY_DEBUG: 556 ifuse_debug_init(); 557 /* falls through */ 558 case KEY_FOREGROUND: 559 opt->foreground = 1; 560 return (0); 561 case KEY_HELP: 562 case KEY_HELP_WITHOUT_HEADER: 563 dump_help(); 564 return (-1); 565 case KEY_VERSION: 566 dump_version(); 567 return (-1); 568 case FUSE_OPT_KEY_NONOPT: 569 if (opt->mp == NULL) { 570 opt->mp = realpath(arg, opt->mp); 571 if (opt->mp == NULL) { 572 fprintf(stderr, "fuse: realpath: " 573 "%s : %s\n", arg, strerror(errno)); 574 return (-1); 575 } 576 577 res = stat(opt->mp, &st); 578 if (res == -1) { 579 fprintf(stderr, "fuse: bad mount point " 580 "%s : %s\n", arg, strerror(errno)); 581 return (-1); 582 } 583 584 if (!S_ISDIR(st.st_mode)) { 585 fprintf(stderr, "fuse: bad mount point " 586 "%s : %s\n", arg, strerror(ENOTDIR)); 587 return (-1); 588 } 589 } 590 return (0); 591 } 592 593 /* Pass through unknown options. */ 594 return (1); 595 } 596 597 int 598 fuse_parse_cmdline(struct fuse_args *args, char **mp, int *mt, int *fg) 599 { 600 struct fuse_core_opts opt; 601 602 memset(&opt, 0, sizeof(opt)); 603 if (fuse_opt_parse(args, &opt, fuse_core_opts, ifuse_process_opt) == -1) 604 return (-1); 605 606 if (opt.mp == NULL) { 607 fprintf(stderr, "fuse: missing mountpoint parameter\n"); 608 return (-1); 609 } 610 611 if (mp != NULL) { 612 *mp = strdup(opt.mp); 613 if (*mp == NULL) 614 return (-1); 615 } 616 617 if (mt != NULL) 618 *mt = 0; 619 620 if (fg != NULL) 621 *fg = opt.foreground; 622 623 return (0); 624 } 625 DEF(fuse_parse_cmdline); 626 627 struct fuse_context * 628 fuse_get_context(void) 629 { 630 return (ictx); 631 } 632 DEF(fuse_get_context); 633 634 int 635 fuse_version(void) 636 { 637 return (FUSE_VERSION); 638 } 639 640 void 641 fuse_teardown(struct fuse *fuse, char *mp) 642 { 643 if (fuse == NULL || mp == NULL) 644 return; 645 646 fuse_remove_signal_handlers(fuse_get_session(fuse)); 647 fuse_unmount(mp, fuse->fc); 648 fuse_destroy(fuse); 649 } 650 651 int 652 fuse_invalidate(unused struct fuse *f, unused const char *path) 653 { 654 return (EINVAL); 655 } 656 657 struct fuse * 658 fuse_setup(int argc, char **argv, const struct fuse_operations *ops, 659 size_t size, char **mp, int *mt, void *data) 660 { 661 struct fuse_args args = FUSE_ARGS_INIT(argc, argv); 662 struct fuse_chan *fc; 663 struct fuse *fuse; 664 char *dir; 665 int fg; 666 667 dir = NULL; 668 if (fuse_parse_cmdline(&args, &dir, mt, &fg)) 669 goto err; 670 671 fuse_daemonize(fg); 672 673 if ((fc = fuse_mount(dir, &args)) == NULL) 674 goto err; 675 676 if ((fuse = fuse_new(fc, &args, ops, size, data)) == NULL) { 677 fuse_unmount(dir, fc); 678 close(fc->fd); 679 free(fc->dir); 680 free(fc); 681 goto err; 682 } 683 684 /* args are no longer needed */ 685 fuse_opt_free_args(&args); 686 687 if (fuse_set_signal_handlers(fuse_get_session(fuse)) == -1) { 688 fuse_unmount(dir, fc); 689 fuse_destroy(fuse); 690 goto err; 691 } 692 693 /* the caller frees dir, but we do it if the caller doesn't want it */ 694 if (mp == NULL) 695 free(dir); 696 else 697 *mp = dir; 698 699 return (fuse); 700 err: 701 free(dir); 702 return (NULL); 703 } 704 DEF(fuse_setup); 705 706 int 707 fuse_main(int argc, char **argv, const struct fuse_operations *ops, void *data) 708 { 709 struct fuse *fuse; 710 711 fuse = fuse_setup(argc, argv, ops, sizeof(*ops), NULL, NULL, data); 712 if (fuse == NULL) 713 return (-1); 714 715 return (fuse_loop(fuse)); 716 } 717