@@ -46,7 +46,10 @@ static uint64_t file64_to_cpu(uint64_t val)
4646static unsigned long read_elf32 (int fd )
4747{
4848 Elf32_Ehdr ehdr32 ;
49+ Elf32_Shdr shdr32 ;
50+ off_t last_shdr_offset ;
4951 ssize_t ret ;
52+ unsigned long sht_end , last_section_end ;
5053
5154 ret = pread (fd , & ehdr32 , sizeof (ehdr32 ), 0 );
5255 if (ret < 0 || (size_t )ret != sizeof (ehdr32 )) {
@@ -59,16 +62,30 @@ static unsigned long read_elf32(int fd)
5962 ehdr .e_shentsize = file16_to_cpu (ehdr32 .e_shentsize );
6063 ehdr .e_shnum = file16_to_cpu (ehdr32 .e_shnum );
6164
62- return (ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum ));
65+ last_shdr_offset = ehdr .e_shoff + (ehdr .e_shentsize * (ehdr .e_shnum - 1 ));
66+ ret = pread (fd , & shdr32 , sizeof (shdr32 ), last_shdr_offset );
67+ if (ret < 0 || (size_t )ret != sizeof (shdr32 )) {
68+ fprintf (stderr , "Read of ELF section header from %s failed: %s\n" ,
69+ fname , strerror (errno ));
70+ exit (10 );
71+ }
72+
73+ /* ELF ends either with the table of section headers (SHT) or with a section. */
74+ sht_end = ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum );
75+ last_section_end = file64_to_cpu (shdr32 .sh_offset ) + file64_to_cpu (shdr32 .sh_size );
76+ return sht_end > last_section_end ? sht_end : last_section_end ;
6377}
6478
6579static unsigned long read_elf64 (int fd )
6680{
6781 Elf64_Ehdr ehdr64 ;
82+ Elf64_Shdr shdr64 ;
83+ off_t last_shdr_offset ;
6884 ssize_t ret ;
85+ unsigned long sht_end , last_section_end ;
6986
7087 ret = pread (fd , & ehdr64 , sizeof (ehdr64 ), 0 );
71- if (ret < 0 || (size_t )ret != sizeof (ehdr )) {
88+ if (ret < 0 || (size_t )ret != sizeof (ehdr64 )) {
7289 fprintf (stderr , "Read of ELF header from %s failed: %s\n" ,
7390 fname , strerror (errno ));
7491 exit (10 );
@@ -78,15 +95,21 @@ static unsigned long read_elf64(int fd)
7895 ehdr .e_shentsize = file16_to_cpu (ehdr64 .e_shentsize );
7996 ehdr .e_shnum = file16_to_cpu (ehdr64 .e_shnum );
8097
81- return (ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum ));
98+ last_shdr_offset = ehdr .e_shoff + (ehdr .e_shentsize * (ehdr .e_shnum - 1 ));
99+ ret = pread (fd , & shdr64 , sizeof (shdr64 ), last_shdr_offset );
100+ if (ret < 0 || (size_t )ret != sizeof (shdr64 )) {
101+ fprintf (stderr , "Read of ELF section header from %s failed: %s\n" ,
102+ fname , strerror (errno ));
103+ exit (10 );
104+ }
105+
106+ /* ELF ends either with the table of section headers (SHT) or with a section. */
107+ sht_end = ehdr .e_shoff + (ehdr .e_shentsize * ehdr .e_shnum );
108+ last_section_end = file64_to_cpu (shdr64 .sh_offset ) + file64_to_cpu (shdr64 .sh_size );
109+ return sht_end > last_section_end ? sht_end : last_section_end ;
82110}
83111
84112unsigned long get_elf_size (const char * fname )
85- /* TODO, FIXME: This assumes that the section header table (SHT) is
86- the last part of the ELF. This is usually the case but
87- it could also be that the last section is the last part
88- of the ELF. This should be checked for.
89- */
90113{
91114 ssize_t ret ;
92115 int fd ;
0 commit comments