1 /* 2 * binfmt_misc.c 3 * 4 * Copyright (C) 1997 Richard Günther 5 * 6 * binfmt_misc detects binaries via a magic or filename extension and invokes 7 * a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and 8 * binfmt_mz. 9 * 10 * 1997-04-25 first version 11 * [...] 12 * 1997-05-19 cleanup 13 * 1997-06-26 hpa: pass the real filename rather than argv[0] 14 * 1997-06-30 minor cleanup 15 * 1997-08-09 removed extension stripping, locking cleanup 16 * 2001-02-28 AV: rewritten into something that resembles C. Original didn't. 17 */ 18 19 #include <linux/module.h> 20 #include <linux/init.h> 21 #include <linux/sched.h> 22 #include <linux/magic.h> 23 #include <linux/binfmts.h> 24 #include <linux/slab.h> 25 #include <linux/ctype.h> 26 #include <linux/file.h> 27 #include <linux/pagemap.h> 28 #include <linux/namei.h> 29 #include <linux/mount.h> 30 #include <linux/syscalls.h> 31 #include <linux/fs.h> 32 33 #include <asm/uaccess.h> 34 35 enum { 36 VERBOSE_STATUS = 1 /* make it zero to save 400 bytes kernel memory */ 37 }; 38 39 static LIST_HEAD(entries); 40 static int enabled = 1; 41 42 enum {Enabled, Magic}; 43 #define MISC_FMT_PRESERVE_ARGV0 (1<<31) 44 #define MISC_FMT_OPEN_BINARY (1<<30) 45 #define MISC_FMT_CREDENTIALS (1<<29) 46 47 typedef struct { 48 struct list_head list; 49 unsigned long flags; /* type, status, etc. */ 50 int offset; /* offset of magic */ 51 int size; /* size of magic/mask */ 52 char *magic; /* magic or filename extension */ 53 char *mask; /* mask, NULL for exact match */ 54 char *interpreter; /* filename of interpreter */ 55 char *name; 56 struct dentry *dentry; 57 } Node; 58 59 static DEFINE_RWLOCK(entries_lock); 60 static struct file_system_type bm_fs_type; 61 static struct vfsmount *bm_mnt; 62 static int entry_count; 63 64 /* 65 * Check if we support the binfmt 66 * if we do, return the node, else NULL 67 * locking is done in load_misc_binary 68 */ 69 static Node *check_file(struct linux_binprm *bprm) 70 { 71 char *p = strrchr(bprm->interp, '.'); 72 struct list_head *l; 73 74 list_for_each(l, &entries) { 75 Node *e = list_entry(l, Node, list); 76 char *s; 77 int j; 78 79 if (!test_bit(Enabled, &e->flags)) 80 continue; 81 82 if (!test_bit(Magic, &e->flags)) { 83 if (p && !strcmp(e->magic, p + 1)) 84 return e; 85 continue; 86 } 87 88 s = bprm->buf + e->offset; 89 if (e->mask) { 90 for (j = 0; j < e->size; j++) 91 if ((*s++ ^ e->magic[j]) & e->mask[j]) 92 break; 93 } else { 94 for (j = 0; j < e->size; j++) 95 if ((*s++ ^ e->magic[j])) 96 break; 97 } 98 if (j == e->size) 99 return e; 100 } 101 return NULL; 102 } 103 104 /* 105 * the loader itself 106 */ 107 static int load_misc_binary(struct linux_binprm *bprm) 108 { 109 Node *fmt; 110 struct file * interp_file = NULL; 111 char iname[BINPRM_BUF_SIZE]; 112 const char *iname_addr = iname; 113 int retval; 114 int fd_binary = -1; 115 116 retval = -ENOEXEC; 117 if (!enabled) 118 goto _ret; 119 120 /* to keep locking time low, we copy the interpreter string */ 121 read_lock(&entries_lock); 122 fmt = check_file(bprm); 123 if (fmt) 124 strlcpy(iname, fmt->interpreter, BINPRM_BUF_SIZE); 125 read_unlock(&entries_lock); 126 if (!fmt) 127 goto _ret; 128 129 if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { 130 retval = remove_arg_zero(bprm); 131 if (retval) 132 goto _ret; 133 } 134 135 if (fmt->flags & MISC_FMT_OPEN_BINARY) { 136 137 /* if the binary should be opened on behalf of the 138 * interpreter than keep it open and assign descriptor 139 * to it */ 140 fd_binary = get_unused_fd(); 141 if (fd_binary < 0) { 142 retval = fd_binary; 143 goto _ret; 144 } 145 fd_install(fd_binary, bprm->file); 146 147 /* if the binary is not readable than enforce mm->dumpable=0 148 regardless of the interpreter's permissions */ 149 would_dump(bprm, bprm->file); 150 151 allow_write_access(bprm->file); 152 bprm->file = NULL; 153 154 /* mark the bprm that fd should be passed to interp */ 155 bprm->interp_flags |= BINPRM_FLAGS_EXECFD; 156 bprm->interp_data = fd_binary; 157 158 } else { 159 allow_write_access(bprm->file); 160 fput(bprm->file); 161 bprm->file = NULL; 162 } 163 /* make argv[1] be the path to the binary */ 164 retval = copy_strings_kernel (1, &bprm->interp, bprm); 165 if (retval < 0) 166 goto _error; 167 bprm->argc++; 168 169 /* add the interp as argv[0] */ 170 retval = copy_strings_kernel (1, &iname_addr, bprm); 171 if (retval < 0) 172 goto _error; 173 bprm->argc ++; 174 175 bprm->interp = iname; /* for binfmt_script */ 176 177 interp_file = open_exec (iname); 178 retval = PTR_ERR (interp_file); 179 if (IS_ERR (interp_file)) 180 goto _error; 181 182 bprm->file = interp_file; 183 if (fmt->flags & MISC_FMT_CREDENTIALS) { 184 /* 185 * No need to call prepare_binprm(), it's already been 186 * done. bprm->buf is stale, update from interp_file. 187 */ 188 memset(bprm->buf, 0, BINPRM_BUF_SIZE); 189 retval = kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE); 190 } else 191 retval = prepare_binprm (bprm); 192 193 if (retval < 0) 194 goto _error; 195 196 retval = search_binary_handler(bprm); 197 if (retval < 0) 198 goto _error; 199 200 _ret: 201 return retval; 202 _error: 203 if (fd_binary > 0) 204 sys_close(fd_binary); 205 bprm->interp_flags = 0; 206 bprm->interp_data = 0; 207 goto _ret; 208 } 209 210 /* Command parsers */ 211 212 /* 213 * parses and copies one argument enclosed in del from *sp to *dp, 214 * recognising the \x special. 215 * returns pointer to the copied argument or NULL in case of an 216 * error (and sets err) or null argument length. 217 */ 218 static char *scanarg(char *s, char del) 219 { 220 char c; 221 222 while ((c = *s++) != del) { 223 if (c == '\\' && *s == 'x') { 224 s++; 225 if (!isxdigit(*s++)) 226 return NULL; 227 if (!isxdigit(*s++)) 228 return NULL; 229 } 230 } 231 return s; 232 } 233 234 static int unquote(char *from) 235 { 236 char c = 0, *s = from, *p = from; 237 238 while ((c = *s++) != '\0') { 239 if (c == '\\' && *s == 'x') { 240 s++; 241 c = toupper(*s++); 242 *p = (c - (isdigit(c) ? '0' : 'A' - 10)) << 4; 243 c = toupper(*s++); 244 *p++ |= c - (isdigit(c) ? '0' : 'A' - 10); 245 continue; 246 } 247 *p++ = c; 248 } 249 return p - from; 250 } 251 252 static char * check_special_flags (char * sfs, Node * e) 253 { 254 char * p = sfs; 255 int cont = 1; 256 257 /* special flags */ 258 while (cont) { 259 switch (*p) { 260 case 'P': 261 p++; 262 e->flags |= MISC_FMT_PRESERVE_ARGV0; 263 break; 264 case 'O': 265 p++; 266 e->flags |= MISC_FMT_OPEN_BINARY; 267 break; 268 case 'C': 269 p++; 270 /* this flags also implies the 271 open-binary flag */ 272 e->flags |= (MISC_FMT_CREDENTIALS | 273 MISC_FMT_OPEN_BINARY); 274 break; 275 default: 276 cont = 0; 277 } 278 } 279 280 return p; 281 } 282 /* 283 * This registers a new binary format, it recognises the syntax 284 * ':name:type:offset:magic:mask:interpreter:flags' 285 * where the ':' is the IFS, that can be chosen with the first char 286 */ 287 static Node *create_entry(const char __user *buffer, size_t count) 288 { 289 Node *e; 290 int memsize, err; 291 char *buf, *p; 292 char del; 293 294 /* some sanity checks */ 295 err = -EINVAL; 296 if ((count < 11) || (count > 256)) 297 goto out; 298 299 err = -ENOMEM; 300 memsize = sizeof(Node) + count + 8; 301 e = kmalloc(memsize, GFP_USER); 302 if (!e) 303 goto out; 304 305 p = buf = (char *)e + sizeof(Node); 306 307 memset(e, 0, sizeof(Node)); 308 if (copy_from_user(buf, buffer, count)) 309 goto Efault; 310 311 del = *p++; /* delimeter */ 312 313 memset(buf+count, del, 8); 314 315 e->name = p; 316 p = strchr(p, del); 317 if (!p) 318 goto Einval; 319 *p++ = '\0'; 320 if (!e->name[0] || 321 !strcmp(e->name, ".") || 322 !strcmp(e->name, "..") || 323 strchr(e->name, '/')) 324 goto Einval; 325 switch (*p++) { 326 case 'E': e->flags = 1<<Enabled; break; 327 case 'M': e->flags = (1<<Enabled) | (1<<Magic); break; 328 default: goto Einval; 329 } 330 if (*p++ != del) 331 goto Einval; 332 if (test_bit(Magic, &e->flags)) { 333 char *s = strchr(p, del); 334 if (!s) 335 goto Einval; 336 *s++ = '\0'; 337 e->offset = simple_strtoul(p, &p, 10); 338 if (*p++) 339 goto Einval; 340 e->magic = p; 341 p = scanarg(p, del); 342 if (!p) 343 goto Einval; 344 p[-1] = '\0'; 345 if (!e->magic[0]) 346 goto Einval; 347 e->mask = p; 348 p = scanarg(p, del); 349 if (!p) 350 goto Einval; 351 p[-1] = '\0'; 352 if (!e->mask[0]) 353 e->mask = NULL; 354 e->size = unquote(e->magic); 355 if (e->mask && unquote(e->mask) != e->size) 356 goto Einval; 357 if (e->size + e->offset > BINPRM_BUF_SIZE) 358 goto Einval; 359 } else { 360 p = strchr(p, del); 361 if (!p) 362 goto Einval; 363 *p++ = '\0'; 364 e->magic = p; 365 p = strchr(p, del); 366 if (!p) 367 goto Einval; 368 *p++ = '\0'; 369 if (!e->magic[0] || strchr(e->magic, '/')) 370 goto Einval; 371 p = strchr(p, del); 372 if (!p) 373 goto Einval; 374 *p++ = '\0'; 375 } 376 e->interpreter = p; 377 p = strchr(p, del); 378 if (!p) 379 goto Einval; 380 *p++ = '\0'; 381 if (!e->interpreter[0]) 382 goto Einval; 383 384 385 p = check_special_flags (p, e); 386 387 if (*p == '\n') 388 p++; 389 if (p != buf + count) 390 goto Einval; 391 return e; 392 393 out: 394 return ERR_PTR(err); 395 396 Efault: 397 kfree(e); 398 return ERR_PTR(-EFAULT); 399 Einval: 400 kfree(e); 401 return ERR_PTR(-EINVAL); 402 } 403 404 /* 405 * Set status of entry/binfmt_misc: 406 * '1' enables, '0' disables and '-1' clears entry/binfmt_misc 407 */ 408 static int parse_command(const char __user *buffer, size_t count) 409 { 410 char s[4]; 411 412 if (!count) 413 return 0; 414 if (count > 3) 415 return -EINVAL; 416 if (copy_from_user(s, buffer, count)) 417 return -EFAULT; 418 if (s[count-1] == '\n') 419 count--; 420 if (count == 1 && s[0] == '0') 421 return 1; 422 if (count == 1 && s[0] == '1') 423 return 2; 424 if (count == 2 && s[0] == '-' && s[1] == '1') 425 return 3; 426 return -EINVAL; 427 } 428 429 /* generic stuff */ 430 431 static void entry_status(Node *e, char *page) 432 { 433 char *dp; 434 char *status = "disabled"; 435 const char * flags = "flags: "; 436 437 if (test_bit(Enabled, &e->flags)) 438 status = "enabled"; 439 440 if (!VERBOSE_STATUS) { 441 sprintf(page, "%s\n", status); 442 return; 443 } 444 445 sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter); 446 dp = page + strlen(page); 447 448 /* print the special flags */ 449 sprintf (dp, "%s", flags); 450 dp += strlen (flags); 451 if (e->flags & MISC_FMT_PRESERVE_ARGV0) { 452 *dp ++ = 'P'; 453 } 454 if (e->flags & MISC_FMT_OPEN_BINARY) { 455 *dp ++ = 'O'; 456 } 457 if (e->flags & MISC_FMT_CREDENTIALS) { 458 *dp ++ = 'C'; 459 } 460 *dp ++ = '\n'; 461 462 463 if (!test_bit(Magic, &e->flags)) { 464 sprintf(dp, "extension .%s\n", e->magic); 465 } else { 466 int i; 467 468 sprintf(dp, "offset %i\nmagic ", e->offset); 469 dp = page + strlen(page); 470 for (i = 0; i < e->size; i++) { 471 sprintf(dp, "%02x", 0xff & (int) (e->magic[i])); 472 dp += 2; 473 } 474 if (e->mask) { 475 sprintf(dp, "\nmask "); 476 dp += 6; 477 for (i = 0; i < e->size; i++) { 478 sprintf(dp, "%02x", 0xff & (int) (e->mask[i])); 479 dp += 2; 480 } 481 } 482 *dp++ = '\n'; 483 *dp = '\0'; 484 } 485 } 486 487 static struct inode *bm_get_inode(struct super_block *sb, int mode) 488 { 489 struct inode * inode = new_inode(sb); 490 491 if (inode) { 492 inode->i_ino = get_next_ino(); 493 inode->i_mode = mode; 494 inode->i_atime = inode->i_mtime = inode->i_ctime = 495 current_fs_time(inode->i_sb); 496 } 497 return inode; 498 } 499 500 static void bm_evict_inode(struct inode *inode) 501 { 502 clear_inode(inode); 503 kfree(inode->i_private); 504 } 505 506 static void kill_node(Node *e) 507 { 508 struct dentry *dentry; 509 510 write_lock(&entries_lock); 511 dentry = e->dentry; 512 if (dentry) { 513 list_del_init(&e->list); 514 e->dentry = NULL; 515 } 516 write_unlock(&entries_lock); 517 518 if (dentry) { 519 drop_nlink(dentry->d_inode); 520 d_drop(dentry); 521 dput(dentry); 522 simple_release_fs(&bm_mnt, &entry_count); 523 } 524 } 525 526 /* /<entry> */ 527 528 static ssize_t 529 bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos) 530 { 531 Node *e = file->f_path.dentry->d_inode->i_private; 532 ssize_t res; 533 char *page; 534 535 if (!(page = (char*) __get_free_page(GFP_KERNEL))) 536 return -ENOMEM; 537 538 entry_status(e, page); 539 540 res = simple_read_from_buffer(buf, nbytes, ppos, page, strlen(page)); 541 542 free_page((unsigned long) page); 543 return res; 544 } 545 546 static ssize_t bm_entry_write(struct file *file, const char __user *buffer, 547 size_t count, loff_t *ppos) 548 { 549 struct dentry *root; 550 Node *e = file->f_path.dentry->d_inode->i_private; 551 int res = parse_command(buffer, count); 552 553 switch (res) { 554 case 1: clear_bit(Enabled, &e->flags); 555 break; 556 case 2: set_bit(Enabled, &e->flags); 557 break; 558 case 3: root = dget(file->f_path.dentry->d_sb->s_root); 559 mutex_lock(&root->d_inode->i_mutex); 560 561 kill_node(e); 562 563 mutex_unlock(&root->d_inode->i_mutex); 564 dput(root); 565 break; 566 default: return res; 567 } 568 return count; 569 } 570 571 static const struct file_operations bm_entry_operations = { 572 .read = bm_entry_read, 573 .write = bm_entry_write, 574 .llseek = default_llseek, 575 }; 576 577 /* /register */ 578 579 static ssize_t bm_register_write(struct file *file, const char __user *buffer, 580 size_t count, loff_t *ppos) 581 { 582 Node *e; 583 struct inode *inode; 584 struct dentry *root, *dentry; 585 struct super_block *sb = file->f_path.dentry->d_sb; 586 int err = 0; 587 588 e = create_entry(buffer, count); 589 590 if (IS_ERR(e)) 591 return PTR_ERR(e); 592 593 root = dget(sb->s_root); 594 mutex_lock(&root->d_inode->i_mutex); 595 dentry = lookup_one_len(e->name, root, strlen(e->name)); 596 err = PTR_ERR(dentry); 597 if (IS_ERR(dentry)) 598 goto out; 599 600 err = -EEXIST; 601 if (dentry->d_inode) 602 goto out2; 603 604 inode = bm_get_inode(sb, S_IFREG | 0644); 605 606 err = -ENOMEM; 607 if (!inode) 608 goto out2; 609 610 err = simple_pin_fs(&bm_fs_type, &bm_mnt, &entry_count); 611 if (err) { 612 iput(inode); 613 inode = NULL; 614 goto out2; 615 } 616 617 e->dentry = dget(dentry); 618 inode->i_private = e; 619 inode->i_fop = &bm_entry_operations; 620 621 d_instantiate(dentry, inode); 622 write_lock(&entries_lock); 623 list_add(&e->list, &entries); 624 write_unlock(&entries_lock); 625 626 err = 0; 627 out2: 628 dput(dentry); 629 out: 630 mutex_unlock(&root->d_inode->i_mutex); 631 dput(root); 632 633 if (err) { 634 kfree(e); 635 return -EINVAL; 636 } 637 return count; 638 } 639 640 static const struct file_operations bm_register_operations = { 641 .write = bm_register_write, 642 .llseek = noop_llseek, 643 }; 644 645 /* /status */ 646 647 static ssize_t 648 bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 649 { 650 char *s = enabled ? "enabled\n" : "disabled\n"; 651 652 return simple_read_from_buffer(buf, nbytes, ppos, s, strlen(s)); 653 } 654 655 static ssize_t bm_status_write(struct file * file, const char __user * buffer, 656 size_t count, loff_t *ppos) 657 { 658 int res = parse_command(buffer, count); 659 struct dentry *root; 660 661 switch (res) { 662 case 1: enabled = 0; break; 663 case 2: enabled = 1; break; 664 case 3: root = dget(file->f_path.dentry->d_sb->s_root); 665 mutex_lock(&root->d_inode->i_mutex); 666 667 while (!list_empty(&entries)) 668 kill_node(list_entry(entries.next, Node, list)); 669 670 mutex_unlock(&root->d_inode->i_mutex); 671 dput(root); 672 default: return res; 673 } 674 return count; 675 } 676 677 static const struct file_operations bm_status_operations = { 678 .read = bm_status_read, 679 .write = bm_status_write, 680 .llseek = default_llseek, 681 }; 682 683 /* Superblock handling */ 684 685 static const struct super_operations s_ops = { 686 .statfs = simple_statfs, 687 .evict_inode = bm_evict_inode, 688 }; 689 690 static int bm_fill_super(struct super_block * sb, void * data, int silent) 691 { 692 static struct tree_descr bm_files[] = { 693 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, 694 [3] = {"register", &bm_register_operations, S_IWUSR}, 695 /* last one */ {""} 696 }; 697 int err = simple_fill_super(sb, BINFMTFS_MAGIC, bm_files); 698 if (!err) 699 sb->s_op = &s_ops; 700 return err; 701 } 702 703 static struct dentry *bm_mount(struct file_system_type *fs_type, 704 int flags, const char *dev_name, void *data) 705 { 706 return mount_single(fs_type, flags, data, bm_fill_super); 707 } 708 709 static struct linux_binfmt misc_format = { 710 .module = THIS_MODULE, 711 .load_binary = load_misc_binary, 712 }; 713 714 static struct file_system_type bm_fs_type = { 715 .owner = THIS_MODULE, 716 .name = "binfmt_misc", 717 .mount = bm_mount, 718 .kill_sb = kill_litter_super, 719 }; 720 721 static int __init init_misc_binfmt(void) 722 { 723 int err = register_filesystem(&bm_fs_type); 724 if (!err) 725 insert_binfmt(&misc_format); 726 return err; 727 } 728 729 static void __exit exit_misc_binfmt(void) 730 { 731 unregister_binfmt(&misc_format); 732 unregister_filesystem(&bm_fs_type); 733 } 734 735 core_initcall(init_misc_binfmt); 736 module_exit(exit_misc_binfmt); 737 MODULE_LICENSE("GPL"); 738