1 /*
2  * cook.c - read and translate ELF files.
3  * Copyright (C) 1995 - 2006 Michael Riepe
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include <private.h>
21 
22 #ifndef lint
23 static const char rcsid[] = "@(#) $Id: cook.c,v 1.29 2008/05/23 08:15:34 michael Exp $";
24 #endif /* lint */
25 
26 const Elf_Scn _elf_scn_init = INIT_SCN;
27 const Scn_Data _elf_data_init = INIT_DATA;
28 
29 Elf_Type
_elf_scn_type(unsigned t)30 _elf_scn_type(unsigned t) {
31     switch (t) {
32 	case SHT_DYNAMIC:       return ELF_T_DYN;
33 	case SHT_DYNSYM:        return ELF_T_SYM;
34 	case SHT_HASH:          return ELF_T_WORD;
35 	case SHT_REL:           return ELF_T_REL;
36 	case SHT_RELA:          return ELF_T_RELA;
37 	case SHT_SYMTAB:        return ELF_T_SYM;
38 	case SHT_SYMTAB_SHNDX:	return ELF_T_WORD;	/* XXX: really? */
39 #if __LIBELF_SYMBOL_VERSIONS
40 #if __LIBELF_SUN_SYMBOL_VERSIONS
41 	case SHT_SUNW_verdef:   return ELF_T_VDEF;
42 	case SHT_SUNW_verneed:  return ELF_T_VNEED;
43 	case SHT_SUNW_versym:   return ELF_T_HALF;
44 #else /* __LIBELF_SUN_SYMBOL_VERSIONS */
45 	case SHT_GNU_verdef:    return ELF_T_VDEF;
46 	case SHT_GNU_verneed:   return ELF_T_VNEED;
47 	case SHT_GNU_versym:    return ELF_T_HALF;
48 #endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
49 #endif /* __LIBELF_SYMBOL_VERSIONS */
50     }
51     return ELF_T_BYTE;
52 }
53 
54 /*
55  * Check for overflow on 32-bit systems
56  */
57 #define overflow(a,b,t)	(sizeof(a) < sizeof(t) && (t)(a) != (b))
58 
59 #define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR:	\
60 		    ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR:	\
61 		    ERROR_INTERNAL))
62 #define memerr(t)   ((t)==ELF_T_EHDR?ERROR_MEM_EHDR:	\
63 		    ((t)==ELF_T_PHDR?ERROR_MEM_PHDR:	\
64 		    ERROR_INTERNAL))
65 
66 Elf_Data*
_elf_xlatetom(const Elf * elf,Elf_Data * dst,const Elf_Data * src)67 _elf_xlatetom(const Elf *elf, Elf_Data *dst, const Elf_Data *src) {
68     if (elf->e_class == ELFCLASS32) {
69 	return elf32_xlatetom(dst, src, elf->e_encoding);
70     }
71 #if __LIBELF64
72     else if (elf->e_class == ELFCLASS64) {
73 	return elf64_xlatetom(dst, src, elf->e_encoding);
74     }
75 #endif /* __LIBELF64 */
76     seterr(ERROR_UNIMPLEMENTED);
77     return NULL;
78 }
79 
80 static char*
_elf_item(void * buf,Elf * elf,Elf_Type type,size_t off)81 _elf_item(void *buf, Elf *elf, Elf_Type type, size_t off) {
82     Elf_Data src, dst;
83 
84     elf_assert(valid_type(type));
85     if (off < 0 || off > elf->e_size) {
86 	seterr(ERROR_OUTSIDE);
87 	return NULL;
88     }
89 
90     src.d_type = type;
91     src.d_version = elf->e_version;
92     src.d_size = _fsize(elf->e_class, src.d_version, type);
93     elf_assert(src.d_size);
94     if ((elf->e_size - off) < src.d_size) {
95 	seterr(truncerr(type));
96 	return NULL;
97     }
98 
99     dst.d_version = _elf_version;
100     dst.d_size = _msize(elf->e_class, dst.d_version, type);
101     elf_assert(dst.d_size);
102 
103     if (!(dst.d_buf = buf) && !(dst.d_buf = malloc(dst.d_size))) {
104 	seterr(memerr(type));
105 	return NULL;
106     }
107 
108     elf_assert(elf->e_data);
109     if (elf->e_rawdata) {
110 	src.d_buf = elf->e_rawdata + off;
111     }
112     else {
113 	src.d_buf = elf->e_data + off;
114     }
115 
116     if (_elf_xlatetom(elf, &dst, &src)) {
117 	return (char*)dst.d_buf;
118     }
119     if (dst.d_buf != buf) {
120 	free(dst.d_buf);
121     }
122     return NULL;
123 }
124 
125 static int
_elf_cook_phdr(Elf * elf)126 _elf_cook_phdr(Elf *elf) {
127     size_t num, off, entsz;
128 
129     if (elf->e_class == ELFCLASS32) {
130 	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum;
131 	off = ((Elf32_Ehdr*)elf->e_ehdr)->e_phoff;
132 	entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_phentsize;
133     }
134 #if __LIBELF64
135     else if (elf->e_class == ELFCLASS64) {
136 	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum;
137 	off = ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff;
138 	entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_phentsize;
139 	/*
140 	 * Check for overflow on 32-bit systems
141 	 */
142 	if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff, Elf64_Off)) {
143 	    seterr(ERROR_OUTSIDE);
144 	    return 0;
145 	}
146     }
147 #endif /* __LIBELF64 */
148     else {
149 	seterr(ERROR_UNIMPLEMENTED);
150 	return 0;
151     }
152     if (off) {
153 	Elf_Scn *scn;
154 	size_t size;
155 	unsigned i;
156 	char *p;
157 
158 	if (num == PN_XNUM) {
159 	    /*
160 	     * Overflow in ehdr->e_phnum.
161 	     * Get real value from first SHDR.
162 	     */
163 	    if (!(scn = elf->e_scn_1)) {
164 		seterr(ERROR_NOSUCHSCN);
165 		return 0;
166 	    }
167 	    if (elf->e_class == ELFCLASS32) {
168 		num = scn->s_shdr32.sh_info;
169 	    }
170 #if __LIBELF64
171 	    else if (elf->e_class == ELFCLASS64) {
172 		num = scn->s_shdr64.sh_info;
173 	    }
174 #endif /* __LIBELF64 */
175 	    /* we already had this
176 	    else {
177 		seterr(ERROR_UNIMPLEMENTED);
178 		return 0;
179 	    }
180 	    */
181 	}
182 
183 	size = _fsize(elf->e_class, elf->e_version, ELF_T_PHDR);
184 	elf_assert(size);
185 #if ENABLE_EXTENDED_FORMAT
186 	if (entsz < size) {
187 #else /* ENABLE_EXTENDED_FORMAT */
188 	if (entsz != size) {
189 #endif /* ENABLE_EXTENDED_FORMAT */
190 	    seterr(ERROR_EHDR_PHENTSIZE);
191 	    return 0;
192 	}
193 	size = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
194 	elf_assert(size);
195 	if (!(p = malloc(num * size))) {
196 	    seterr(memerr(ELF_T_PHDR));
197 	    return 0;
198 	}
199 	for (i = 0; i < num; i++) {
200 	    if (!_elf_item(p + i * size, elf, ELF_T_PHDR, off + i * entsz)) {
201 		free(p);
202 		return 0;
203 	    }
204 	}
205 	elf->e_phdr = p;
206 	elf->e_phnum = num;
207     }
208     return 1;
209 }
210 
211 static int
212 _elf_cook_shdr(Elf *elf) {
213     size_t num, off, entsz;
214 
215     if (elf->e_class == ELFCLASS32) {
216 	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum;
217 	off = ((Elf32_Ehdr*)elf->e_ehdr)->e_shoff;
218 	entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_shentsize;
219     }
220 #if __LIBELF64
221     else if (elf->e_class == ELFCLASS64) {
222 	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum;
223 	off = ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff;
224 	entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_shentsize;
225 	/*
226 	 * Check for overflow on 32-bit systems
227 	 */
228 	if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff, Elf64_Off)) {
229 	    seterr(ERROR_OUTSIDE);
230 	    return 0;
231 	}
232     }
233 #endif /* __LIBELF64 */
234     else {
235 	seterr(ERROR_UNIMPLEMENTED);
236 	return 0;
237     }
238     if (off) {
239 	struct tmp {
240 	    Elf_Scn	scn;
241 	    Scn_Data	data;
242 	} *head;
243 	Elf_Data src, dst;
244 	Elf_Scn *scn;
245 	Scn_Data *sd;
246 	unsigned i;
247 
248 	if (off < 0 || off > elf->e_size) {
249 	    seterr(ERROR_OUTSIDE);
250 	    return 0;
251 	}
252 
253 	src.d_type = ELF_T_SHDR;
254 	src.d_version = elf->e_version;
255 	src.d_size = _fsize(elf->e_class, src.d_version, ELF_T_SHDR);
256 	elf_assert(src.d_size);
257 #if ENABLE_EXTENDED_FORMAT
258 	if (entsz < src.d_size) {
259 #else /* ENABLE_EXTENDED_FORMAT */
260 	if (entsz != src.d_size) {
261 #endif /* ENABLE_EXTENDED_FORMAT */
262 	    seterr(ERROR_EHDR_SHENTSIZE);
263 	    return 0;
264 	}
265 	dst.d_version = EV_CURRENT;
266 
267 	if (num == 0) {
268 	    union {
269 		Elf32_Shdr sh32;
270 #if __LIBELF64
271 		Elf64_Shdr sh64;
272 #endif /* __LIBELF64 */
273 	    } u;
274 
275 	    /*
276 	     * Overflow in ehdr->e_shnum.
277 	     * Get real value from first SHDR.
278 	     */
279 	    if (elf->e_size - off < entsz) {
280 		seterr(ERROR_TRUNC_SHDR);
281 		return 0;
282 	    }
283 	    if (elf->e_rawdata) {
284 		src.d_buf = elf->e_rawdata + off;
285 	    }
286 	    else {
287 		src.d_buf = elf->e_data + off;
288 	    }
289 	    dst.d_buf = &u;
290 	    dst.d_size = sizeof(u);
291 	    if (!_elf_xlatetom(elf, &dst, &src)) {
292 		return 0;
293 	    }
294 	    elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
295 	    elf_assert(dst.d_type == ELF_T_SHDR);
296 	    if (elf->e_class == ELFCLASS32) {
297 		num = u.sh32.sh_size;
298 	    }
299 #if __LIBELF64
300 	    else if (elf->e_class == ELFCLASS64) {
301 		num = u.sh64.sh_size;
302 		/*
303 		 * Check for overflow on 32-bit systems
304 		 */
305 		if (overflow(num, u.sh64.sh_size, Elf64_Xword)) {
306 		    seterr(ERROR_OUTSIDE);
307 		    return 0;
308 		}
309 	    }
310 #endif /* __LIBELF64 */
311 	}
312 
313 	if ((elf->e_size - off) / entsz < num) {
314 	    seterr(ERROR_TRUNC_SHDR);
315 	    return 0;
316 	}
317 
318 	if (!(head = (struct tmp*)malloc(num * sizeof(struct tmp)))) {
319 	    seterr(ERROR_MEM_SCN);
320 	    return 0;
321 	}
322 	for (scn = NULL, i = num; i-- > 0; ) {
323 	    head[i].scn = _elf_scn_init;
324 	    head[i].data = _elf_data_init;
325 	    head[i].scn.s_link = scn;
326 	    if (!scn) {
327 		elf->e_scn_n = &head[i].scn;
328 	    }
329 	    scn = &head[i].scn;
330 	    sd = &head[i].data;
331 
332 	    if (elf->e_rawdata) {
333 		src.d_buf = elf->e_rawdata + off + i * entsz;
334 	    }
335 	    else {
336 		src.d_buf = elf->e_data + off + i * entsz;
337 	    }
338 	    dst.d_buf = &scn->s_uhdr;
339 	    dst.d_size = sizeof(scn->s_uhdr);
340 	    if (!_elf_xlatetom(elf, &dst, &src)) {
341 		elf->e_scn_n = NULL;
342 		free(head);
343 		return 0;
344 	    }
345 	    elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
346 	    elf_assert(dst.d_type == ELF_T_SHDR);
347 
348 	    scn->s_elf = elf;
349 	    scn->s_index = i;
350 	    scn->s_data_1 = sd;
351 	    scn->s_data_n = sd;
352 
353 	    sd->sd_scn = scn;
354 
355 	    if (elf->e_class == ELFCLASS32) {
356 		Elf32_Shdr *shdr = &scn->s_shdr32;
357 
358 		scn->s_type = shdr->sh_type;
359 		scn->s_size = shdr->sh_size;
360 		scn->s_offset = shdr->sh_offset;
361 		sd->sd_data.d_align = shdr->sh_addralign;
362 		sd->sd_data.d_type = _elf_scn_type(scn->s_type);
363 	    }
364 #if __LIBELF64
365 	    else if (elf->e_class == ELFCLASS64) {
366 		Elf64_Shdr *shdr = &scn->s_shdr64;
367 
368 		scn->s_type = shdr->sh_type;
369 		scn->s_size = shdr->sh_size;
370 		scn->s_offset = shdr->sh_offset;
371 		sd->sd_data.d_align = shdr->sh_addralign;
372 		/*
373 		 * Check for overflow on 32-bit systems
374 		 */
375 		if (overflow(scn->s_size, shdr->sh_size, Elf64_Xword)
376 		 || overflow(scn->s_offset, shdr->sh_offset, Elf64_Off)
377 		 || overflow(sd->sd_data.d_align, shdr->sh_addralign, Elf64_Xword)) {
378 		    seterr(ERROR_OUTSIDE);
379 		    return 0;
380 		}
381 		sd->sd_data.d_type = _elf_scn_type(scn->s_type);
382 		/*
383 		 * QUIRKS MODE:
384 		 *
385 		 * Some 64-bit architectures use 64-bit entries in the
386 		 * .hash section. This violates the ELF standard, and
387 		 * should be fixed. It's mostly harmless as long as the
388 		 * binary and the machine running your program have the
389 		 * same byte order, but you're in trouble if they don't,
390 		 * and if the entry size is wrong.
391 		 *
392 		 * As a workaround, I let libelf guess the right size
393 		 * for the binary. This relies pretty much on the fact
394 		 * that the binary provides correct data in the section
395 		 * headers. If it doesn't, it's probably broken anyway.
396 		 * Therefore, libelf uses a standard conforming value
397 		 * when it's not absolutely sure.
398 		 */
399 		if (scn->s_type == SHT_HASH) {
400 		    int override = 0;
401 
402 		    /*
403 		     * sh_entsize must reflect the entry size
404 		     */
405 		    if (shdr->sh_entsize == ELF64_FSZ_ADDR) {
406 			override++;
407 		    }
408 		    /*
409 		     * sh_size must be a multiple of sh_entsize
410 		     */
411 		    if (shdr->sh_size % ELF64_FSZ_ADDR == 0) {
412 			override++;
413 		    }
414 		    /*
415 		     * There must be room for at least 2 entries
416 		     */
417 		    if (shdr->sh_size >= 2 * ELF64_FSZ_ADDR) {
418 			override++;
419 		    }
420 		    /*
421 		     * sh_addralign must be correctly set
422 		     */
423 		    if (shdr->sh_addralign == ELF64_FSZ_ADDR) {
424 			override++;
425 		    }
426 		    /*
427 		     * The section must be properly aligned
428 		     */
429 		    if (shdr->sh_offset % ELF64_FSZ_ADDR == 0) {
430 			override++;
431 		    }
432 		    /* XXX: also look at the data? */
433 		    /*
434 		     * Make a conservative decision...
435 		     */
436 		    if (override >= 5) {
437 			sd->sd_data.d_type = ELF_T_ADDR;
438 		    }
439 		}
440 		/*
441 		 * END QUIRKS MODE.
442 		 */
443 	    }
444 #endif /* __LIBELF64 */
445 	    /* we already had this
446 	    else {
447 		seterr(ERROR_UNIMPLEMENTED);
448 		return 0;
449 	    }
450 	    */
451 
452 	    sd->sd_data.d_size = scn->s_size;
453 	    sd->sd_data.d_version = _elf_version;
454 	}
455 	elf_assert(scn == &head[0].scn);
456 	elf->e_scn_1 = &head[0].scn;
457 	head[0].scn.s_freeme = 1;
458     }
459     return 1;
460 }
461 
462 static int
463 _elf_cook_file(Elf *elf) {
464     elf->e_ehdr = _elf_item(NULL, elf, ELF_T_EHDR, 0);
465     if (!elf->e_ehdr) {
466 	return 0;
467     }
468     /*
469      * Note: _elf_cook_phdr may require the first section header!
470      */
471     if (!_elf_cook_shdr(elf)) {
472 	return 0;
473     }
474     if (!_elf_cook_phdr(elf)) {
475 	return 0;
476     }
477     return 1;
478 }
479 
480 int
481 _elf_cook(Elf *elf) {
482     elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
483     elf_assert(_elf_data_init.sd_magic == DATA_MAGIC);
484     elf_assert(elf);
485     elf_assert(elf->e_magic == ELF_MAGIC);
486     elf_assert(elf->e_kind == ELF_K_ELF);
487     elf_assert(!elf->e_ehdr);
488     if (!valid_version(elf->e_version)) {
489 	seterr(ERROR_UNKNOWN_VERSION);
490     }
491     else if (!valid_encoding(elf->e_encoding)) {
492 	seterr(ERROR_UNKNOWN_ENCODING);
493     }
494     else if (valid_class(elf->e_class)) {
495 	return _elf_cook_file(elf);
496     }
497     else {
498 	seterr(ERROR_UNKNOWN_CLASS);
499     }
500     return 0;
501 }
502