Line
Link Here
|
0 |
-- prelink-cross-20151030/src/gather.c |
0 |
++ prelink-cross-20151030/src/gather.c |
Lines 645-703
Link Here
|
645 |
return 0; |
645 |
return 0; |
646 |
} |
646 |
} |
647 |
|
647 |
|
648 |
/* Determine if a buffer holding an ELF header and program header |
648 |
/* Determine for a buffer holding an ELF header if the program header |
649 |
table may be that of a position-independent executable. */ |
649 |
table in the buffer or in the associated file may be that of a |
|
|
650 |
position-independent executable. */ |
650 |
static int |
651 |
static int |
651 |
maybe_pie (unsigned char *e_ident, int big_endian, int sixty_four) |
652 |
maybe_pie (unsigned char *e_ident, size_t data_length, int fd, |
|
|
653 |
int big_endian, int sixty_four) |
652 |
{ |
654 |
{ |
653 |
uint16_t num_phdrs; |
655 |
uint16_t num_phdrs; |
654 |
uint16_t phdr; |
656 |
uint16_t phdr; |
655 |
size_t p_type_offset; |
657 |
size_t p_type_offset; |
656 |
size_t phnum_offset; |
658 |
size_t phnum_offset; |
|
|
659 |
int64_t phdr_offset; |
660 |
size_t phentsize_offset; |
661 |
uint16_t phentsize; |
662 |
size_t phdr_size; |
657 |
unsigned char *phdr_table; |
663 |
unsigned char *phdr_table; |
658 |
unsigned char *this_phdr; |
664 |
size_t this_offset; |
|
|
665 |
unsigned char buffer[0x1000]; |
659 |
|
666 |
|
660 |
if (sixty_four) |
667 |
if (sixty_four) |
661 |
{ |
668 |
{ |
662 |
uint64_t phdr_offset; |
669 |
unsigned char *phoff = e_ident + offsetof (Elf64_Ehdr, e_phoff); |
663 |
|
670 |
phdr_size = sizeof (Elf64_Phdr); |
664 |
p_type_offset = offsetof (Elf64_Phdr, p_type); |
671 |
p_type_offset = offsetof (Elf64_Phdr, p_type); |
665 |
phnum_offset = offsetof (Elf64_Ehdr, e_phnum); |
672 |
phnum_offset = offsetof (Elf64_Ehdr, e_phnum); |
|
|
673 |
phentsize_offset = offsetof (Elf64_Ehdr, e_phentsize); |
666 |
if (big_endian) |
674 |
if (big_endian) |
667 |
phdr_offset = buf_read_ube64 (&e_ident [offsetof (Elf64_Ehdr, |
675 |
phdr_offset = buf_read_ube64 (phoff); |
668 |
e_phoff)]); |
|
|
669 |
else |
676 |
else |
670 |
phdr_offset = buf_read_ule64 (&e_ident [offsetof (Elf64_Ehdr, |
677 |
phdr_offset = buf_read_ule64 (phoff); |
671 |
e_phoff)]); |
678 |
if (phdr_offset < sizeof (Elf64_Ehdr)) |
|
|
679 |
return 0; |
672 |
phdr_table = e_ident + phdr_offset; |
|
|
673 |
} |
680 |
} |
674 |
else |
681 |
else |
675 |
{ |
682 |
{ |
676 |
uint32_t phdr_offset; |
683 |
unsigned char *phoff = e_ident + offsetof (Elf32_Ehdr, e_phoff); |
677 |
|
684 |
phdr_size = sizeof (Elf32_Phdr); |
678 |
p_type_offset = offsetof (Elf32_Phdr, p_type); |
685 |
p_type_offset = offsetof (Elf32_Phdr, p_type); |
679 |
phnum_offset = offsetof (Elf32_Ehdr, e_phnum); |
686 |
phnum_offset = offsetof (Elf32_Ehdr, e_phnum); |
|
|
687 |
phentsize_offset = offsetof (Elf32_Ehdr, e_phentsize); |
680 |
if (big_endian) |
688 |
if (big_endian) |
681 |
phdr_offset = buf_read_ube32 (&e_ident [offsetof (Elf32_Ehdr, |
689 |
phdr_offset = buf_read_ube32 (phoff); |
682 |
e_phoff)]); |
|
|
683 |
else |
690 |
else |
684 |
phdr_offset = buf_read_ule32 (&e_ident [offsetof (Elf32_Ehdr, |
691 |
phdr_offset = buf_read_ule32 (phoff); |
685 |
e_phoff)]); |
692 |
if (phdr_offset < sizeof (Elf32_Ehdr)) |
|
|
693 |
return 0; |
686 |
phdr_table = e_ident + phdr_offset; |
|
|
687 |
} |
694 |
} |
688 |
|
695 |
|
689 |
this_phdr = phdr_table; |
|
|
690 |
|
691 |
if (big_endian) |
696 |
if (big_endian) |
692 |
num_phdrs = buf_read_ube16 (&e_ident [phnum_offset]); |
697 |
{ |
|
|
698 |
num_phdrs = buf_read_ube16 (e_ident + phnum_offset); |
699 |
phentsize = buf_read_ube16 (e_ident + phentsize_offset); |
700 |
} |
693 |
else |
701 |
else |
694 |
num_phdrs = buf_read_ule16 (&e_ident [phnum_offset]); |
702 |
{ |
|
|
703 |
num_phdrs = buf_read_ule16 (e_ident + phnum_offset); |
704 |
phentsize = buf_read_ule16 (e_ident + phentsize_offset); |
705 |
} |
695 |
|
706 |
|
696 |
for (phdr = 0; phdr < num_phdrs; phdr++) |
707 |
if (num_phdrs == 0 || phentsize < phdr_size) |
|
|
708 |
return 0; |
709 |
else |
710 |
{ |
711 |
struct stat st; |
712 |
if (fstat (fd, &st) != 0 || |
713 |
st.st_size - (int64_t) num_phdrs * phentsize < phdr_offset) |
714 |
return 0; |
715 |
} |
716 |
|
717 |
phdr_table = e_ident; |
718 |
this_offset = phdr_offset < data_length ? phdr_offset : data_length; |
|
|
719 |
for (phdr = 0; phdr < num_phdrs; phdr++, this_offset += phentsize) |
697 |
{ |
720 |
{ |
698 |
unsigned char *p_type_start = this_phdr + p_type_offset; |
721 |
unsigned char *p_type_start; |
699 |
uint32_t p_type; |
722 |
uint32_t p_type; |
700 |
|
723 |
|
|
|
724 |
if (this_offset + p_type_offset + sizeof (int32_t) > data_length) |
725 |
{ |
726 |
/* Read more headers from file */ |
727 |
ssize_t read_bytes = pread (fd, buffer, sizeof(buffer), |
728 |
phdr_offset + phdr * (off_t) phentsize); |
729 |
if (read_bytes < phentsize) |
730 |
return 0; |
731 |
|
732 |
data_length = read_bytes; |
733 |
phdr_table = buffer; |
734 |
this_offset = 0; |
735 |
} |
736 |
|
737 |
p_type_start = phdr_table + this_offset + p_type_offset; |
701 |
if (big_endian) |
738 |
if (big_endian) |
702 |
p_type = buf_read_ube32 (p_type_start); |
739 |
p_type = buf_read_ube32 (p_type_start); |
703 |
else |
740 |
else |
Lines 709-716
Link Here
|
709 |
/* Any PT_PHDR entry must come before any PT_LOAD entry. */ |
746 |
/* Any PT_PHDR entry must come before any PT_LOAD entry. */ |
710 |
if (p_type == PT_LOAD) |
747 |
if (p_type == PT_LOAD) |
711 |
return 0; |
748 |
return 0; |
712 |
|
|
|
713 |
this_phdr += sixty_four ? sizeof (Elf64_Phdr) : sizeof (Elf32_Phdr); |
714 |
} |
749 |
} |
715 |
|
750 |
|
716 |
return 0; |
751 |
return 0; |
Lines 720-726
Link Here
|
720 |
gather_func (const char *name, const struct stat64 *st, int type, |
755 |
gather_func (const char *name, const struct stat64 *st, int type, |
721 |
struct FTW *ftwp) |
756 |
struct FTW *ftwp) |
722 |
{ |
757 |
{ |
723 |
unsigned char e_ident [sizeof (Elf64_Ehdr) + sizeof (Elf64_Phdr)]; |
758 |
unsigned char e_ident [sizeof (Elf64_Ehdr) + sizeof (Elf64_Phdr) + 4]; |
724 |
|
759 |
|
725 |
#ifndef HAVE_FTW_ACTIONRETVAL |
760 |
#ifndef HAVE_FTW_ACTIONRETVAL |
726 |
if (blacklist_dir) |
761 |
if (blacklist_dir) |
Lines 817-823
Link Here
|
817 |
goto make_unprelinkable; |
852 |
goto make_unprelinkable; |
818 |
else if (e_ident [EI_CLASS] == ELFCLASS32) |
853 |
else if (e_ident [EI_CLASS] == ELFCLASS32) |
819 |
{ |
854 |
{ |
820 |
if (maybe_pie (e_ident, 0, 0)) |
855 |
if (maybe_pie (e_ident, sizeof (e_ident), fd, 0, 0)) |
821 |
{ |
856 |
{ |
822 |
maybe_pie: |
857 |
maybe_pie: |
823 |
dso = fdopen_dso (fd, name); |
858 |
dso = fdopen_dso (fd, name); |
Lines 834-840
Link Here
|
834 |
} |
869 |
} |
835 |
else if (e_ident [EI_CLASS] == ELFCLASS64) |
870 |
else if (e_ident [EI_CLASS] == ELFCLASS64) |
836 |
{ |
871 |
{ |
837 |
if (maybe_pie (e_ident, 0, 1)) |
872 |
if (maybe_pie (e_ident, sizeof (e_ident), fd, 0, 1)) |
838 |
goto maybe_pie; |
873 |
goto maybe_pie; |
839 |
goto close_it; |
874 |
goto close_it; |
840 |
} |
875 |
} |
Lines 851-863
Link Here
|
851 |
goto make_unprelinkable; |
886 |
goto make_unprelinkable; |
852 |
else if (e_ident [EI_CLASS] == ELFCLASS32) |
887 |
else if (e_ident [EI_CLASS] == ELFCLASS32) |
853 |
{ |
888 |
{ |
854 |
if (maybe_pie (e_ident, 1, 0)) |
889 |
if (maybe_pie (e_ident, sizeof (e_ident), fd, 1, 0)) |
855 |
goto maybe_pie; |
890 |
goto maybe_pie; |
856 |
goto close_it; |
891 |
goto close_it; |
857 |
} |
892 |
} |
858 |
else if (e_ident [EI_CLASS] == ELFCLASS64) |
893 |
else if (e_ident [EI_CLASS] == ELFCLASS64) |
859 |
{ |
894 |
{ |
860 |
if (maybe_pie (e_ident, 1, 1)) |
895 |
if (maybe_pie (e_ident, sizeof (e_ident), fd, 1, 1)) |
861 |
goto maybe_pie; |
896 |
goto maybe_pie; |
862 |
goto close_it; |
897 |
goto close_it; |
863 |
} |
898 |
} |