@@ -74,12 +74,18 @@ template ElfIO(Elf_Ehdr, Elf_Shdr, ubyte ELFCLASS)
74
74
*/
75
75
this (int fd)
76
76
{
77
+ import core.stdc.stdio : SEEK_END ;
78
+
77
79
this .fd = fd;
78
- if (fd != - 1 )
79
- {
80
- // memory map header
81
- this .ehdr = TypedMMapRegion! Elf_Ehdr(fd, 0 );
82
- }
80
+ if (fd == - 1 )
81
+ return ;
82
+
83
+ const fsize = lseek(fd, 0 , SEEK_END );
84
+ if (fsize == - 1 || fsize < Elf_Ehdr.sizeof)
85
+ return ;
86
+
87
+ // okay, memory map header
88
+ this .ehdr = TypedMMapRegion! Elf_Ehdr(fd, 0 );
83
89
}
84
90
85
91
@disable this (this );
@@ -98,6 +104,9 @@ template ElfIO(Elf_Ehdr, Elf_Shdr, ubyte ELFCLASS)
98
104
// / Returns true if the ELF file header matches the ElfIO template parameters.
99
105
bool isValid () const
100
106
{
107
+ if (fd == - 1 || ehdr.data is null ) // invalid file descriptor or mmap error
108
+ return false ;
109
+
101
110
enum EI_MAG0 = 0 ;
102
111
enum EI_MAG1 = 1 ;
103
112
enum EI_MAG2 = 2 ;
@@ -110,19 +119,13 @@ template ElfIO(Elf_Ehdr, Elf_Shdr, ubyte ELFCLASS)
110
119
enum ELFMAG2 = ' L' ;
111
120
enum ELFMAG3 = ' F' ;
112
121
113
- enum ELFCLASS32 = 1 ;
114
- enum ELFCLASS64 = 2 ;
115
-
116
122
enum ELFDATA2LSB = 1 ;
117
123
enum ELFDATA2MSB = 2 ;
118
124
119
125
version (LittleEndian ) alias ELFDATA = ELFDATA2LSB ;
120
126
else version (BigEndian ) alias ELFDATA = ELFDATA2MSB ;
121
127
else static assert (0 , " unsupported byte order" );
122
128
123
- if (fd == - 1 )
124
- return false ;
125
-
126
129
const ident = ehdr.e_ident;
127
130
128
131
if (! (ident[EI_MAG0 ] == ELFMAG0 &&
@@ -189,14 +192,23 @@ template ElfIO(Elf_Ehdr, Elf_Shdr, ubyte ELFCLASS)
189
192
int opApply (scope Callback dg)
190
193
{
191
194
const stringSectionHeader = ElfSectionHeader(* file, file.ehdr.e_shstrndx);
195
+ if (stringSectionHeader.shdr.data is null ) // mmap error
196
+ return 0 ;
197
+
192
198
const stringSection = ElfSection(* file, stringSectionHeader);
199
+ const stringSectionData = cast (const char * ) stringSection.data.ptr;
200
+ if (stringSectionData is null ) // mmap error
201
+ return 0 ;
193
202
194
203
foreach (i; 0 .. file.ehdr.e_shnum)
195
204
{
196
205
import core.stdc.string : strlen;
197
206
198
207
auto sectionHeader = ElfSectionHeader(* file, i);
199
- auto sectionName = cast (const (char )* ) (stringSection.data.ptr + sectionHeader.sh_name);
208
+ if (sectionHeader.shdr.data is null ) // mmap error
209
+ return 0 ;
210
+
211
+ const sectionName = stringSectionData + sectionHeader.sh_name;
200
212
const nameLen = strlen(sectionName);
201
213
202
214
const r = dg(i, sectionName[0 .. nameLen], move(sectionHeader));
@@ -241,7 +253,7 @@ template ElfIO(Elf_Ehdr, Elf_Shdr, ubyte ELFCLASS)
241
253
this (ref const ElfFile file, ref const ElfSectionHeader shdr)
242
254
{
243
255
mappedRegion = TypedMMapRegion! void (file.fd, shdr.sh_offset, shdr.sh_size);
244
- size = shdr.sh_size;
256
+ size = mappedRegion.data is null ? 0 : shdr.sh_size;
245
257
}
246
258
247
259
@disable this (this );
@@ -374,3 +386,15 @@ unittest
374
386
}
375
387
}
376
388
}
389
+
390
+ version (LinuxOrBSD)
391
+ unittest
392
+ {
393
+ import core.stdc.stdio : fileno, tmpfile;
394
+
395
+ auto emptyFile = tmpfile();
396
+ assert (emptyFile);
397
+
398
+ const elfFile = ElfFile(fileno(emptyFile));
399
+ assert (! elfFile.isValid()); // no SIGBUS: https://issues.dlang.org/show_bug.cgi?id=21656
400
+ }
0 commit comments