|
34 | 34 | #include <linux/init.h>
|
35 | 35 | #include <linux/flat.h>
|
36 | 36 | #include <linux/uaccess.h>
|
| 37 | +#include <linux/vmalloc.h> |
37 | 38 |
|
38 | 39 | #include <asm/byteorder.h>
|
39 | 40 | #include <asm/unaligned.h>
|
@@ -628,20 +629,59 @@ static int load_flat_file(struct linux_binprm *bprm,
|
628 | 629 | * load it all in and treat it like a RAM load from now on
|
629 | 630 | */
|
630 | 631 | if (flags & FLAT_FLAG_GZIP) {
|
| 632 | +#ifndef CONFIG_MMU |
631 | 633 | result = decompress_exec(bprm, sizeof(struct flat_hdr),
|
632 | 634 | (((char *)textpos) + sizeof(struct flat_hdr)),
|
633 | 635 | (text_len + full_data
|
634 | 636 | - sizeof(struct flat_hdr)),
|
635 | 637 | 0);
|
636 | 638 | memmove((void *) datapos, (void *) realdatastart,
|
637 | 639 | full_data);
|
| 640 | +#else |
| 641 | + /* |
| 642 | + * This is used on MMU systems mainly for testing. |
| 643 | + * Let's use a kernel buffer to simplify things. |
| 644 | + */ |
| 645 | + long unz_text_len = text_len - sizeof(struct flat_hdr); |
| 646 | + long unz_len = unz_text_len + full_data; |
| 647 | + char *unz_data = vmalloc(unz_len); |
| 648 | + if (!unz_data) { |
| 649 | + result = -ENOMEM; |
| 650 | + } else { |
| 651 | + result = decompress_exec(bprm, sizeof(struct flat_hdr), |
| 652 | + unz_data, unz_len, 0); |
| 653 | + if (result == 0 && |
| 654 | + (copy_to_user((void __user *)textpos + sizeof(struct flat_hdr), |
| 655 | + unz_data, unz_text_len) || |
| 656 | + copy_to_user((void __user *)datapos, |
| 657 | + unz_data + unz_text_len, full_data))) |
| 658 | + result = -EFAULT; |
| 659 | + vfree(unz_data); |
| 660 | + } |
| 661 | +#endif |
638 | 662 | } else if (flags & FLAT_FLAG_GZDATA) {
|
639 | 663 | result = read_code(bprm->file, textpos, 0, text_len);
|
640 |
| - if (!IS_ERR_VALUE(result)) |
| 664 | + if (!IS_ERR_VALUE(result)) { |
| 665 | +#ifndef CONFIG_MMU |
641 | 666 | result = decompress_exec(bprm, text_len, (char *) datapos,
|
642 | 667 | full_data, 0);
|
643 |
| - } else |
| 668 | +#else |
| 669 | + char *unz_data = vmalloc(full_data); |
| 670 | + if (!unz_data) { |
| 671 | + result = -ENOMEM; |
| 672 | + } else { |
| 673 | + result = decompress_exec(bprm, text_len, |
| 674 | + unz_data, full_data, 0); |
| 675 | + if (result == 0 && |
| 676 | + copy_to_user((void __user *)datapos, |
| 677 | + unz_data, full_data)) |
| 678 | + result = -EFAULT; |
| 679 | + vfree(unz_data); |
| 680 | + } |
644 | 681 | #endif
|
| 682 | + } |
| 683 | + } else |
| 684 | +#endif /* CONFIG_BINFMT_ZFLAT */ |
645 | 685 | {
|
646 | 686 | result = read_code(bprm->file, textpos, 0, text_len);
|
647 | 687 | if (!IS_ERR_VALUE(result))
|
|
0 commit comments