aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_flat.c
diff options
context:
space:
mode:
authorLuke Yang <luke.adi@gmail.com>2006-03-25 06:08:24 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 11:23:01 -0500
commit1ad3dcc09c88c6e01d7624398c591ff3aee22fbe (patch)
tree80c1d28cf329a781ac137858eb6c613fb0eb424e /fs/binfmt_flat.c
parentf5163427453bc6ca2dd497eeb3e7a30d1c74b487 (diff)
[PATCH] flat binary loader doesn't check fd table full
In binfmt_flat.c, the flat binary loader should check file descriptor table and install the fd on the file. Convert the function to single-exit and fix this bug. Signed-off-by: "Luke Yang" <luke.adi@gmail.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/binfmt_flat.c')
-rw-r--r--fs/binfmt_flat.c73
1 files changed, 54 insertions, 19 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 108d56bbd0d0..69f44dcdb0b4 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -36,6 +36,7 @@
36#include <linux/personality.h> 36#include <linux/personality.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/flat.h> 38#include <linux/flat.h>
39#include <linux/syscalls.h>
39 40
40#include <asm/byteorder.h> 41#include <asm/byteorder.h>
41#include <asm/system.h> 42#include <asm/system.h>
@@ -426,6 +427,8 @@ static int load_flat_file(struct linux_binprm * bprm,
426 int i, rev, relocs = 0; 427 int i, rev, relocs = 0;
427 loff_t fpos; 428 loff_t fpos;
428 unsigned long start_code, end_code; 429 unsigned long start_code, end_code;
430 int ret;
431 int exec_fileno;
429 432
430 hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ 433 hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */
431 inode = bprm->file->f_dentry->d_inode; 434 inode = bprm->file->f_dentry->d_inode;
@@ -450,7 +453,8 @@ static int load_flat_file(struct linux_binprm * bprm,
450 */ 453 */
451 if (strncmp(hdr->magic, "#!", 2)) 454 if (strncmp(hdr->magic, "#!", 2))
452 printk("BINFMT_FLAT: bad header magic\n"); 455 printk("BINFMT_FLAT: bad header magic\n");
453 return -ENOEXEC; 456 ret = -ENOEXEC;
457 goto err;
454 } 458 }
455 459
456 if (flags & FLAT_FLAG_KTRACE) 460 if (flags & FLAT_FLAG_KTRACE)
@@ -458,14 +462,16 @@ static int load_flat_file(struct linux_binprm * bprm,
458 462
459 if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) { 463 if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {
460 printk("BINFMT_FLAT: bad flat file version 0x%x (supported 0x%x and 0x%x)\n", rev, FLAT_VERSION, OLD_FLAT_VERSION); 464 printk("BINFMT_FLAT: bad flat file version 0x%x (supported 0x%x and 0x%x)\n", rev, FLAT_VERSION, OLD_FLAT_VERSION);
461 return -ENOEXEC; 465 ret = -ENOEXEC;
466 goto err;
462 } 467 }
463 468
464 /* Don't allow old format executables to use shared libraries */ 469 /* Don't allow old format executables to use shared libraries */
465 if (rev == OLD_FLAT_VERSION && id != 0) { 470 if (rev == OLD_FLAT_VERSION && id != 0) {
466 printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n", 471 printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n",
467 (int) FLAT_VERSION); 472 (int) FLAT_VERSION);
468 return -ENOEXEC; 473 ret = -ENOEXEC;
474 goto err;
469 } 475 }
470 476
471 /* 477 /*
@@ -478,7 +484,8 @@ static int load_flat_file(struct linux_binprm * bprm,
478#ifndef CONFIG_BINFMT_ZFLAT 484#ifndef CONFIG_BINFMT_ZFLAT
479 if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) { 485 if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
480 printk("Support for ZFLAT executables is not enabled.\n"); 486 printk("Support for ZFLAT executables is not enabled.\n");
481 return -ENOEXEC; 487 ret = -ENOEXEC;
488 goto err;
482 } 489 }
483#endif 490#endif
484 491
@@ -490,14 +497,27 @@ static int load_flat_file(struct linux_binprm * bprm,
490 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 497 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
491 if (rlim >= RLIM_INFINITY) 498 if (rlim >= RLIM_INFINITY)
492 rlim = ~0; 499 rlim = ~0;
493 if (data_len + bss_len > rlim) 500 if (data_len + bss_len > rlim) {
494 return -ENOMEM; 501 ret = -ENOMEM;
502 goto err;
503 }
504
505 /* check file descriptor */
506 exec_fileno = get_unused_fd();
507 if (exec_fileno < 0) {
508 ret = -EMFILE;
509 goto err;
510 }
511 get_file(bprm->file);
512 fd_install(exec_fileno, bprm->file);
495 513
496 /* Flush all traces of the currently running executable */ 514 /* Flush all traces of the currently running executable */
497 if (id == 0) { 515 if (id == 0) {
498 result = flush_old_exec(bprm); 516 result = flush_old_exec(bprm);
499 if (result) 517 if (result) {
500 return result; 518 ret = result;
519 goto err_close;
520 }
501 521
502 /* OK, This is the point of no return */ 522 /* OK, This is the point of no return */
503 set_personality(PER_LINUX); 523 set_personality(PER_LINUX);
@@ -527,7 +547,8 @@ static int load_flat_file(struct linux_binprm * bprm,
527 if (!textpos) 547 if (!textpos)
528 textpos = (unsigned long) -ENOMEM; 548 textpos = (unsigned long) -ENOMEM;
529 printk("Unable to mmap process text, errno %d\n", (int)-textpos); 549 printk("Unable to mmap process text, errno %d\n", (int)-textpos);
530 return(textpos); 550 ret = textpos;
551 goto err_close;
531 } 552 }
532 553
533 down_write(&current->mm->mmap_sem); 554 down_write(&current->mm->mmap_sem);
@@ -542,7 +563,8 @@ static int load_flat_file(struct linux_binprm * bprm,
542 printk("Unable to allocate RAM for process data, errno %d\n", 563 printk("Unable to allocate RAM for process data, errno %d\n",
543 (int)-datapos); 564 (int)-datapos);
544 do_munmap(current->mm, textpos, text_len); 565 do_munmap(current->mm, textpos, text_len);
545 return realdatastart; 566 ret = realdatastart;
567 goto err_close;
546 } 568 }
547 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); 569 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
548 570
@@ -564,7 +586,8 @@ static int load_flat_file(struct linux_binprm * bprm,
564 printk("Unable to read data+bss, errno %d\n", (int)-result); 586 printk("Unable to read data+bss, errno %d\n", (int)-result);
565 do_munmap(current->mm, textpos, text_len); 587 do_munmap(current->mm, textpos, text_len);
566 do_munmap(current->mm, realdatastart, data_len + extra); 588 do_munmap(current->mm, realdatastart, data_len + extra);
567 return result; 589 ret = result;
590 goto err_close;
568 } 591 }
569 592
570 reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len)); 593 reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
@@ -582,7 +605,8 @@ static int load_flat_file(struct linux_binprm * bprm,
582 textpos = (unsigned long) -ENOMEM; 605 textpos = (unsigned long) -ENOMEM;
583 printk("Unable to allocate RAM for process text/data, errno %d\n", 606 printk("Unable to allocate RAM for process text/data, errno %d\n",
584 (int)-textpos); 607 (int)-textpos);
585 return(textpos); 608 ret = textpos;
609 goto err_close;
586 } 610 }
587 611
588 realdatastart = textpos + ntohl(hdr->data_start); 612 realdatastart = textpos + ntohl(hdr->data_start);
@@ -627,7 +651,8 @@ static int load_flat_file(struct linux_binprm * bprm,
627 printk("Unable to read code+data+bss, errno %d\n",(int)-result); 651 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
628 do_munmap(current->mm, textpos, text_len + data_len + extra + 652 do_munmap(current->mm, textpos, text_len + data_len + extra +
629 MAX_SHARED_LIBS * sizeof(unsigned long)); 653 MAX_SHARED_LIBS * sizeof(unsigned long));
630 return result; 654 ret = result;
655 goto err_close;
631 } 656 }
632 } 657 }
633 658
@@ -690,8 +715,10 @@ static int load_flat_file(struct linux_binprm * bprm,
690 unsigned long addr; 715 unsigned long addr;
691 if (*rp) { 716 if (*rp) {
692 addr = calc_reloc(*rp, libinfo, id, 0); 717 addr = calc_reloc(*rp, libinfo, id, 0);
693 if (addr == RELOC_FAILED) 718 if (addr == RELOC_FAILED) {
694 return -ENOEXEC; 719 ret = -ENOEXEC;
720 goto err_close;
721 }
695 *rp = addr; 722 *rp = addr;
696 } 723 }
697 } 724 }
@@ -718,8 +745,10 @@ static int load_flat_file(struct linux_binprm * bprm,
718 relval = ntohl(reloc[i]); 745 relval = ntohl(reloc[i]);
719 addr = flat_get_relocate_addr(relval); 746 addr = flat_get_relocate_addr(relval);
720 rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1); 747 rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
721 if (rp == (unsigned long *)RELOC_FAILED) 748 if (rp == (unsigned long *)RELOC_FAILED) {
722 return -ENOEXEC; 749 ret = -ENOEXEC;
750 goto err_close;
751 }
723 752
724 /* Get the pointer's value. */ 753 /* Get the pointer's value. */
725 addr = flat_get_addr_from_rp(rp, relval, flags); 754 addr = flat_get_addr_from_rp(rp, relval, flags);
@@ -731,8 +760,10 @@ static int load_flat_file(struct linux_binprm * bprm,
731 if ((flags & FLAT_FLAG_GOTPIC) == 0) 760 if ((flags & FLAT_FLAG_GOTPIC) == 0)
732 addr = ntohl(addr); 761 addr = ntohl(addr);
733 addr = calc_reloc(addr, libinfo, id, 0); 762 addr = calc_reloc(addr, libinfo, id, 0);
734 if (addr == RELOC_FAILED) 763 if (addr == RELOC_FAILED) {
735 return -ENOEXEC; 764 ret = -ENOEXEC;
765 goto err_close;
766 }
736 767
737 /* Write back the relocated pointer. */ 768 /* Write back the relocated pointer. */
738 flat_put_addr_at_rp(rp, addr, relval); 769 flat_put_addr_at_rp(rp, addr, relval);
@@ -752,6 +783,10 @@ static int load_flat_file(struct linux_binprm * bprm,
752 stack_len); 783 stack_len);
753 784
754 return 0; 785 return 0;
786err_close:
787 sys_close(exec_fileno);
788err:
789 return ret;
755} 790}
756 791
757 792