1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * binfmt_misc.c 4 * 5 * Copyright (C) 1997 Richard Günther 6 * 7 * binfmt_misc detects binaries via a magic or filename extension and invokes 8 * a specified wrapper. See Documentation/admin-guide/binfmt-misc.rst for more details. 9 */ 10 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/sched/mm.h> 17 #include <linux/magic.h> 18 #include <linux/binfmts.h> 19 #include <linux/slab.h> 20 #include <linux/ctype.h> 21 #include <linux/string_helpers.h> 22 #include <linux/file.h> 23 #include <linux/pagemap.h> 24 #include <linux/namei.h> 25 #include <linux/mount.h> 26 #include <linux/fs_context.h> 27 #include <linux/syscalls.h> 28 #include <linux/fs.h> 29 #include <linux/uaccess.h> 30 31 #include "internal.h" 32 33 #ifdef DEBUG 34 # define USE_DEBUG 1 35 #else 36 # define USE_DEBUG 0 37 #endif 38 39 enum { 40 VERBOSE_STATUS = 1 /* make it zero to save 400 bytes kernel memory */ 41 }; 42 43 static LIST_HEAD(entries); 44 static int enabled = 1; 45 46 enum {Enabled, Magic}; 47 #define MISC_FMT_PRESERVE_ARGV0 (1 << 31) 48 #define MISC_FMT_OPEN_BINARY (1 << 30) 49 #define MISC_FMT_CREDENTIALS (1 << 29) 50 #define MISC_FMT_OPEN_FILE (1 << 28) 51 52 typedef struct { 53 struct list_head list; 54 unsigned long flags; /* type, status, etc. */ 55 int offset; /* offset of magic */ 56 int size; /* size of magic/mask */ 57 char *magic; /* magic or filename extension */ 58 char *mask; /* mask, NULL for exact match */ 59 const char *interpreter; /* filename of interpreter */ 60 char *name; 61 struct dentry *dentry; 62 struct file *interp_file; 63 } Node; 64 65 static DEFINE_RWLOCK(entries_lock); 66 static struct file_system_type bm_fs_type; 67 static struct vfsmount *bm_mnt; 68 static int entry_count; 69 70 /* 71 * Max length of the register string. Determined by: 72 * - 7 delimiters 73 * - name: ~50 bytes 74 * - type: 1 byte 75 * - offset: 3 bytes (has to be smaller than BINPRM_BUF_SIZE) 76 * - magic: 128 bytes (512 in escaped form) 77 * - mask: 128 bytes (512 in escaped form) 78 * - interp: ~50 bytes 79 * - flags: 5 bytes 80 * Round that up a bit, and then back off to hold the internal data 81 * (like struct Node). 82 */ 83 #define MAX_REGISTER_LENGTH 1920 84 85 /* 86 * Check if we support the binfmt 87 * if we do, return the node, else NULL 88 * locking is done in load_misc_binary 89 */ 90 static Node *check_file(struct linux_binprm *bprm) 91 { 92 char *p = strrchr(bprm->interp, '.'); 93 struct list_head *l; 94 95 /* Walk all the registered handlers. */ 96 list_for_each(l, &entries) { 97 Node *e = list_entry(l, Node, list); 98 char *s; 99 int j; 100 101 /* Make sure this one is currently enabled. */ 102 if (!test_bit(Enabled, &e->flags)) 103 continue; 104 105 /* Do matching based on extension if applicable. */ 106 if (!test_bit(Magic, &e->flags)) { 107 if (p && !strcmp(e->magic, p + 1)) 108 return e; 109 continue; 110 } 111 112 /* Do matching based on magic & mask. */ 113 s = bprm->buf + e->offset; 114 if (e->mask) { 115 for (j = 0; j < e->size; j++) 116 if ((*s++ ^ e->magic[j]) & e->mask[j]) 117 break; 118 } else { 119 for (j = 0; j < e->size; j++) 120 if ((*s++ ^ e->magic[j])) 121 break; 122 } 123 if (j == e->size) 124 return e; 125 } 126 return NULL; 127 } 128 129 /* 130 * the loader itself 131 */ 132 static int load_misc_binary(struct linux_binprm *bprm) 133 { 134 Node *fmt; 135 struct file *interp_file = NULL; 136 int retval; 137 138 retval = -ENOEXEC; 139 if (!enabled) 140 return retval; 141 142 /* to keep locking time low, we copy the interpreter string */ 143 read_lock(&entries_lock); 144 fmt = check_file(bprm); 145 if (fmt) 146 dget(fmt->dentry); 147 read_unlock(&entries_lock); 148 if (!fmt) 149 return retval; 150 151 /* Need to be able to load the file after exec */ 152 retval = -ENOENT; 153 if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) 154 goto ret; 155 156 if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) { 157 bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0; 158 } else { 159 retval = remove_arg_zero(bprm); 160 if (retval) 161 goto ret; 162 } 163 164 if (fmt->flags & MISC_FMT_OPEN_BINARY) 165 bprm->have_execfd = 1; 166 167 /* make argv[1] be the path to the binary */ 168 retval = copy_string_kernel(bprm->interp, bprm); 169 if (retval < 0) 170 goto ret; 171 bprm->argc++; 172 173 /* add the interp as argv[0] */ 174 retval = copy_string_kernel(fmt->interpreter, bprm); 175 if (retval < 0) 176 goto ret; 177 bprm->argc++; 178 179 /* Update interp in case binfmt_script needs it. */ 180 retval = bprm_change_interp(fmt->interpreter, bprm); 181 if (retval < 0) 182 goto ret; 183 184 if (fmt->flags & MISC_FMT_OPEN_FILE) { 185 interp_file = file_clone_open(fmt->interp_file); 186 if (!IS_ERR(interp_file)) 187 deny_write_access(interp_file); 188 } else { 189 interp_file = open_exec(fmt->interpreter); 190 } 191 retval = PTR_ERR(interp_file); 192 if (IS_ERR(interp_file)) 193 goto ret; 194 195 bprm->interpreter = interp_file; 196 if (fmt->flags & MISC_FMT_CREDENTIALS) 197 bprm->execfd_creds = 1; 198 199 retval = 0; 200 ret: 201 dput(fmt->dentry); 202 return retval; 203 } 204 205 /* Command parsers */ 206 207 /* 208 * parses and copies one argument enclosed in del from *sp to *dp, 209 * recognising the \x special. 210 * returns pointer to the copied argument or NULL in case of an 211 * error (and sets err) or null argument length. 212 */ 213 static char *scanarg(char *s, char del) 214 { 215 char c; 216 217 while ((c = *s++) != del) { 218 if (c == '\\' && *s == 'x') { 219 s++; 220 if (!isxdigit(*s++)) 221 return NULL; 222 if (!isxdigit(*s++)) 223 return NULL; 224 } 225 } 226 s[-1] ='\0'; 227 return s; 228 } 229 230 static char *check_special_flags(char *sfs, Node *e) 231 { 232 char *p = sfs; 233 int cont = 1; 234 235 /* special flags */ 236 while (cont) { 237 switch (*p) { 238 case 'P': 239 pr_debug("register: flag: P (preserve argv0)\n"); 240 p++; 241 e->flags |= MISC_FMT_PRESERVE_ARGV0; 242 break; 243 case 'O': 244 pr_debug("register: flag: O (open binary)\n"); 245 p++; 246 e->flags |= MISC_FMT_OPEN_BINARY; 247 break; 248 case 'C': 249 pr_debug("register: flag: C (preserve creds)\n"); 250 p++; 251 /* this flags also implies the 252 open-binary flag */ 253 e->flags |= (MISC_FMT_CREDENTIALS | 254 MISC_FMT_OPEN_BINARY); 255 break; 256 case 'F': 257 pr_debug("register: flag: F: open interpreter file now\n"); 258 p++; 259 e->flags |= MISC_FMT_OPEN_FILE; 260 break; 261 default: 262 cont = 0; 263 } 264 } 265 266 return p; 267 } 268 269 /* 270 * This registers a new binary format, it recognises the syntax 271 * ':name:type:offset:magic:mask:interpreter:flags' 272 * where the ':' is the IFS, that can be chosen with the first char 273 */ 274 static Node *create_entry(const char __user *buffer, size_t count) 275 { 276 Node *e; 277 int memsize, err; 278 char *buf, *p; 279 char del; 280 281 pr_debug("register: received %zu bytes\n", count); 282 283 /* some sanity checks */ 284 err = -EINVAL; 285 if ((count < 11) || (count > MAX_REGISTER_LENGTH)) 286 goto out; 287 288 err = -ENOMEM; 289 memsize = sizeof(Node) + count + 8; 290 e = kmalloc(memsize, GFP_KERNEL); 291 if (!e) 292 goto out; 293 294 p = buf = (char *)e + sizeof(Node); 295 296 memset(e, 0, sizeof(Node)); 297 if (copy_from_user(buf, buffer, count)) 298 goto efault; 299 300 del = *p++; /* delimeter */ 301 302 pr_debug("register: delim: %#x {%c}\n", del, del); 303 304 /* Pad the buffer with the delim to simplify parsing below. */ 305 memset(buf + count, del, 8); 306 307 /* Parse the 'name' field. */ 308 e->name = p; 309 p = strchr(p, del); 310 if (!p) 311 goto einval; 312 *p++ = '\0'; 313 if (!e->name[0] || 314 !strcmp(e->name, ".") || 315 !strcmp(e->name, "..") || 316 strchr(e->name, '/')) 317 goto einval; 318 319 pr_debug("register: name: {%s}\n", e->name); 320 321 /* Parse the 'type' field. */ 322 switch (*p++) { 323 case 'E': 324 pr_debug("register: type: E (extension)\n"); 325 e->flags = 1 << Enabled; 326 break; 327 case 'M': 328 pr_debug("register: type: M (magic)\n"); 329 e->flags = (1 << Enabled) | (1 << Magic); 330 break; 331 default: 332 goto einval; 333 } 334 if (*p++ != del) 335 goto einval; 336 337 if (test_bit(Magic, &e->flags)) { 338 /* Handle the 'M' (magic) format. */ 339 char *s; 340 341 /* Parse the 'offset' field. */ 342 s = strchr(p, del); 343 if (!s) 344 goto einval; 345 *s = '\0'; 346 if (p != s) { 347 int r = kstrtoint(p, 10, &e->offset); 348 if (r != 0 || e->offset < 0) 349 goto einval; 350 } 351 p = s; 352 if (*p++) 353 goto einval; 354 pr_debug("register: offset: %#x\n", e->offset); 355 356 /* Parse the 'magic' field. */ 357 e->magic = p; 358 p = scanarg(p, del); 359 if (!p) 360 goto einval; 361 if (!e->magic[0]) 362 goto einval; 363 if (USE_DEBUG) 364 print_hex_dump_bytes( 365 KBUILD_MODNAME ": register: magic[raw]: ", 366 DUMP_PREFIX_NONE, e->magic, p - e->magic); 367 368 /* Parse the 'mask' field. */ 369 e->mask = p; 370 p = scanarg(p, del); 371 if (!p) 372 goto einval; 373 if (!e->mask[0]) { 374 e->mask = NULL; 375 pr_debug("register: mask[raw]: none\n"); 376 } else if (USE_DEBUG) 377 print_hex_dump_bytes( 378 KBUILD_MODNAME ": register: mask[raw]: ", 379 DUMP_PREFIX_NONE, e->mask, p - e->mask); 380 381 /* 382 * Decode the magic & mask fields. 383 * Note: while we might have accepted embedded NUL bytes from 384 * above, the unescape helpers here will stop at the first one 385 * it encounters. 386 */ 387 e->size = string_unescape_inplace(e->magic, UNESCAPE_HEX); 388 if (e->mask && 389 string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size) 390 goto einval; 391 if (e->size > BINPRM_BUF_SIZE || 392 BINPRM_BUF_SIZE - e->size < e->offset) 393 goto einval; 394 pr_debug("register: magic/mask length: %i\n", e->size); 395 if (USE_DEBUG) { 396 print_hex_dump_bytes( 397 KBUILD_MODNAME ": register: magic[decoded]: ", 398 DUMP_PREFIX_NONE, e->magic, e->size); 399 400 if (e->mask) { 401 int i; 402 char *masked = kmalloc(e->size, GFP_KERNEL); 403 404 print_hex_dump_bytes( 405 KBUILD_MODNAME ": register: mask[decoded]: ", 406 DUMP_PREFIX_NONE, e->mask, e->size); 407 408 if (masked) { 409 for (i = 0; i < e->size; ++i) 410 masked[i] = e->magic[i] & e->mask[i]; 411 print_hex_dump_bytes( 412 KBUILD_MODNAME ": register: magic[masked]: ", 413 DUMP_PREFIX_NONE, masked, e->size); 414 415 kfree(masked); 416 } 417 } 418 } 419 } else { 420 /* Handle the 'E' (extension) format. */ 421 422 /* Skip the 'offset' field. */ 423 p = strchr(p, del); 424 if (!p) 425 goto einval; 426 *p++ = '\0'; 427 428 /* Parse the 'magic' field. */ 429 e->magic = p; 430 p = strchr(p, del); 431 if (!p) 432 goto einval; 433 *p++ = '\0'; 434 if (!e->magic[0] || strchr(e->magic, '/')) 435 goto einval; 436 pr_debug("register: extension: {%s}\n", e->magic); 437 438 /* Skip the 'mask' field. */ 439 p = strchr(p, del); 440 if (!p) 441 goto einval; 442 *p++ = '\0'; 443 } 444 445 /* Parse the 'interpreter' field. */ 446 e->interpreter = p; 447 p = strchr(p, del); 448 if (!p) 449 goto einval; 450 *p++ = '\0'; 451 if (!e->interpreter[0]) 452 goto einval; 453 pr_debug("register: interpreter: {%s}\n", e->interpreter); 454 455 /* Parse the 'flags' field. */ 456 p = check_special_flags(p, e); 457 if (*p == '\n') 458 p++; 459 if (p != buf + count) 460 goto einval; 461 462 return e; 463 464 out: 465 return ERR_PTR(err); 466 467 efault: 468 kfree(e); 469 return ERR_PTR(-EFAULT); 470 einval: 471 kfree(e); 472 return ERR_PTR(-EINVAL); 473 } 474 475 /* 476 * Set status of entry/binfmt_misc: 477 * '1' enables, '0' disables and '-1' clears entry/binfmt_misc 478 */ 479 static int parse_command(const char __user *buffer, size_t count) 480 { 481 char s[4]; 482 483 if (count > 3) 484 return -EINVAL; 485 if (copy_from_user(s, buffer, count)) 486 return -EFAULT; 487 if (!count) 488 return 0; 489 if (s[count - 1] == '\n') 490 count--; 491 if (count == 1 && s[0] == '0') 492 return 1; 493 if (count == 1 && s[0] == '1') 494 return 2; 495 if (count == 2 && s[0] == '-' && s[1] == '1') 496 return 3; 497 return -EINVAL; 498 } 499 500 /* generic stuff */ 501 502 static void entry_status(Node *e, char *page) 503 { 504 char *dp = page; 505 const char *status = "disabled"; 506 507 if (test_bit(Enabled, &e->flags)) 508 status = "enabled"; 509 510 if (!VERBOSE_STATUS) { 511 sprintf(page, "%s\n", status); 512 return; 513 } 514 515 dp += sprintf(dp, "%s\ninterpreter %s\n", status, e->interpreter); 516 517 /* print the special flags */ 518 dp += sprintf(dp, "flags: "); 519 if (e->flags & MISC_FMT_PRESERVE_ARGV0) 520 *dp++ = 'P'; 521 if (e->flags & MISC_FMT_OPEN_BINARY) 522 *dp++ = 'O'; 523 if (e->flags & MISC_FMT_CREDENTIALS) 524 *dp++ = 'C'; 525 if (e->flags & MISC_FMT_OPEN_FILE) 526 *dp++ = 'F'; 527 *dp++ = '\n'; 528 529 if (!test_bit(Magic, &e->flags)) { 530 sprintf(dp, "extension .%s\n", e->magic); 531 } else { 532 dp += sprintf(dp, "offset %i\nmagic ", e->offset); 533 dp = bin2hex(dp, e->magic, e->size); 534 if (e->mask) { 535 dp += sprintf(dp, "\nmask "); 536 dp = bin2hex(dp, e->mask, e->size); 537 } 538 *dp++ = '\n'; 539 *dp = '\0'; 540 } 541 } 542 543 static struct inode *bm_get_inode(struct super_block *sb, int mode) 544 { 545 struct inode *inode = new_inode(sb); 546 547 if (inode) { 548 inode->i_ino = get_next_ino(); 549 inode->i_mode = mode; 550 inode->i_atime = inode->i_mtime = inode->i_ctime = 551 current_time(inode); 552 } 553 return inode; 554 } 555 556 static void bm_evict_inode(struct inode *inode) 557 { 558 Node *e = inode->i_private; 559 560 if (e && e->flags & MISC_FMT_OPEN_FILE) 561 filp_close(e->interp_file, NULL); 562 563 clear_inode(inode); 564 kfree(e); 565 } 566 567 static void kill_node(Node *e) 568 { 569 struct dentry *dentry; 570 571 write_lock(&entries_lock); 572 list_del_init(&e->list); 573 write_unlock(&entries_lock); 574 575 dentry = e->dentry; 576 drop_nlink(d_inode(dentry)); 577 d_drop(dentry); 578 dput(dentry); 579 simple_release_fs(&bm_mnt, &entry_count); 580 } 581 582 /* /<entry> */ 583 584 static ssize_t 585 bm_entry_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 586 { 587 Node *e = file_inode(file)->i_private; 588 ssize_t res; 589 char *page; 590 591 page = (char *) __get_free_page(GFP_KERNEL); 592 if (!page) 593 return -ENOMEM; 594 595 entry_status(e, page); 596 597 res = simple_read_from_buffer(buf, nbytes, ppos, page, strlen(page)); 598 599 free_page((unsigned long) page); 600 return res; 601 } 602 603 static ssize_t bm_entry_write(struct file *file, const char __user *buffer, 604 size_t count, loff_t *ppos) 605 { 606 struct dentry *root; 607 Node *e = file_inode(file)->i_private; 608 int res = parse_command(buffer, count); 609 610 switch (res) { 611 case 1: 612 /* Disable this handler. */ 613 clear_bit(Enabled, &e->flags); 614 break; 615 case 2: 616 /* Enable this handler. */ 617 set_bit(Enabled, &e->flags); 618 break; 619 case 3: 620 /* Delete this handler. */ 621 root = file_inode(file)->i_sb->s_root; 622 inode_lock(d_inode(root)); 623 624 if (!list_empty(&e->list)) 625 kill_node(e); 626 627 inode_unlock(d_inode(root)); 628 break; 629 default: 630 return res; 631 } 632 633 return count; 634 } 635 636 static const struct file_operations bm_entry_operations = { 637 .read = bm_entry_read, 638 .write = bm_entry_write, 639 .llseek = default_llseek, 640 }; 641 642 /* /register */ 643 644 static ssize_t bm_register_write(struct file *file, const char __user *buffer, 645 size_t count, loff_t *ppos) 646 { 647 Node *e; 648 struct inode *inode; 649 struct super_block *sb = file_inode(file)->i_sb; 650 struct dentry *root = sb->s_root, *dentry; 651 int err = 0; 652 struct file *f = NULL; 653 654 e = create_entry(buffer, count); 655 656 if (IS_ERR(e)) 657 return PTR_ERR(e); 658 659 if (e->flags & MISC_FMT_OPEN_FILE) { 660 f = open_exec(e->interpreter); 661 if (IS_ERR(f)) { 662 pr_notice("register: failed to install interpreter file %s\n", 663 e->interpreter); 664 kfree(e); 665 return PTR_ERR(f); 666 } 667 e->interp_file = f; 668 } 669 670 inode_lock(d_inode(root)); 671 dentry = lookup_one_len(e->name, root, strlen(e->name)); 672 err = PTR_ERR(dentry); 673 if (IS_ERR(dentry)) 674 goto out; 675 676 err = -EEXIST; 677 if (d_really_is_positive(dentry)) 678 goto out2; 679 680 inode = bm_get_inode(sb, S_IFREG | 0644); 681 682 err = -ENOMEM; 683 if (!inode) 684 goto out2; 685 686 err = simple_pin_fs(&bm_fs_type, &bm_mnt, &entry_count); 687 if (err) { 688 iput(inode); 689 inode = NULL; 690 goto out2; 691 } 692 693 e->dentry = dget(dentry); 694 inode->i_private = e; 695 inode->i_fop = &bm_entry_operations; 696 697 d_instantiate(dentry, inode); 698 write_lock(&entries_lock); 699 list_add(&e->list, &entries); 700 write_unlock(&entries_lock); 701 702 err = 0; 703 out2: 704 dput(dentry); 705 out: 706 inode_unlock(d_inode(root)); 707 708 if (err) { 709 if (f) 710 filp_close(f, NULL); 711 kfree(e); 712 return err; 713 } 714 return count; 715 } 716 717 static const struct file_operations bm_register_operations = { 718 .write = bm_register_write, 719 .llseek = noop_llseek, 720 }; 721 722 /* /status */ 723 724 static ssize_t 725 bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 726 { 727 char *s = enabled ? "enabled\n" : "disabled\n"; 728 729 return simple_read_from_buffer(buf, nbytes, ppos, s, strlen(s)); 730 } 731 732 static ssize_t bm_status_write(struct file *file, const char __user *buffer, 733 size_t count, loff_t *ppos) 734 { 735 int res = parse_command(buffer, count); 736 struct dentry *root; 737 738 switch (res) { 739 case 1: 740 /* Disable all handlers. */ 741 enabled = 0; 742 break; 743 case 2: 744 /* Enable all handlers. */ 745 enabled = 1; 746 break; 747 case 3: 748 /* Delete all handlers. */ 749 root = file_inode(file)->i_sb->s_root; 750 inode_lock(d_inode(root)); 751 752 while (!list_empty(&entries)) 753 kill_node(list_first_entry(&entries, Node, list)); 754 755 inode_unlock(d_inode(root)); 756 break; 757 default: 758 return res; 759 } 760 761 return count; 762 } 763 764 static const struct file_operations bm_status_operations = { 765 .read = bm_status_read, 766 .write = bm_status_write, 767 .llseek = default_llseek, 768 }; 769 770 /* Superblock handling */ 771 772 static const struct super_operations s_ops = { 773 .statfs = simple_statfs, 774 .evict_inode = bm_evict_inode, 775 }; 776 777 static int bm_fill_super(struct super_block *sb, struct fs_context *fc) 778 { 779 int err; 780 static const struct tree_descr bm_files[] = { 781 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, 782 [3] = {"register", &bm_register_operations, S_IWUSR}, 783 /* last one */ {""} 784 }; 785 786 err = simple_fill_super(sb, BINFMTFS_MAGIC, bm_files); 787 if (!err) 788 sb->s_op = &s_ops; 789 return err; 790 } 791 792 static int bm_get_tree(struct fs_context *fc) 793 { 794 return get_tree_single(fc, bm_fill_super); 795 } 796 797 static const struct fs_context_operations bm_context_ops = { 798 .get_tree = bm_get_tree, 799 }; 800 801 static int bm_init_fs_context(struct fs_context *fc) 802 { 803 fc->ops = &bm_context_ops; 804 return 0; 805 } 806 807 static struct linux_binfmt misc_format = { 808 .module = THIS_MODULE, 809 .load_binary = load_misc_binary, 810 }; 811 812 static struct file_system_type bm_fs_type = { 813 .owner = THIS_MODULE, 814 .name = "binfmt_misc", 815 .init_fs_context = bm_init_fs_context, 816 .kill_sb = kill_litter_super, 817 }; 818 MODULE_ALIAS_FS("binfmt_misc"); 819 820 static struct ctl_table_header *binfmt_misc_header; 821 822 static int __init init_misc_binfmt(void) 823 { 824 int err = register_filesystem(&bm_fs_type); 825 if (!err) 826 insert_binfmt(&misc_format); 827 binfmt_misc_header = register_sysctl_mount_point("fs/binfmt_misc"); 828 return 0; 829 } 830 831 static void __exit exit_misc_binfmt(void) 832 { 833 unregister_sysctl_table(binfmt_misc_header); 834 unregister_binfmt(&misc_format); 835 unregister_filesystem(&bm_fs_type); 836 } 837 838 core_initcall(init_misc_binfmt); 839 module_exit(exit_misc_binfmt); 840 MODULE_LICENSE("GPL"); 841