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