debuggers.hg

view xen/common/libelf/libelf-tools.c @ 22855:1d1eec7e1fb4

xl: Perform minimal validation of virtual disk file while parsing config file

This patch performs some very basic validation on the virtual disk
file passed through the config file. This validation ensures that we
don't go too far with the initialization like spawn qemu and more
while there could be some potentially fundamental issues.

[ Patch fixed up to work with PHYSTYPE_EMPTY 22808:6ec61438713a -iwj ]

Signed-off-by: Kamala Narasimhan <kamala.narasimhan@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Kamala Narasimhan <kamala.narasimhan@gmail.com>
date Tue Jan 25 18:09:49 2011 +0000 (2011-01-25)
parents eccfdeb41b80
children
line source
1 /*
2 * various helper functions to access elf structures
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation;
7 * version 2.1 of the License.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
19 #include "libelf-private.h"
21 /* ------------------------------------------------------------------------ */
23 uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr,
24 uint64_t offset, size_t size)
25 {
26 int need_swap = elf_swap(elf);
27 const uint8_t *u8;
28 const uint16_t *u16;
29 const uint32_t *u32;
30 const uint64_t *u64;
32 switch ( size )
33 {
34 case 1:
35 u8 = ptr + offset;
36 return *u8;
37 case 2:
38 u16 = ptr + offset;
39 return need_swap ? bswap_16(*u16) : *u16;
40 case 4:
41 u32 = ptr + offset;
42 return need_swap ? bswap_32(*u32) : *u32;
43 case 8:
44 u64 = ptr + offset;
45 return need_swap ? bswap_64(*u64) : *u64;
46 default:
47 return 0;
48 }
49 }
51 int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
52 uint64_t offset, size_t size)
53 {
54 int need_swap = elf_swap(elf);
55 const int8_t *s8;
56 const int16_t *s16;
57 const int32_t *s32;
58 const int64_t *s64;
60 switch ( size )
61 {
62 case 1:
63 s8 = ptr + offset;
64 return *s8;
65 case 2:
66 s16 = ptr + offset;
67 return need_swap ? bswap_16(*s16) : *s16;
68 case 4:
69 s32 = ptr + offset;
70 return need_swap ? bswap_32(*s32) : *s32;
71 case 8:
72 s64 = ptr + offset;
73 return need_swap ? bswap_64(*s64) : *s64;
74 default:
75 return 0;
76 }
77 }
79 uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
80 {
81 int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
83 return (addr + elf_round) & ~elf_round;
84 }
86 /* ------------------------------------------------------------------------ */
88 int elf_shdr_count(struct elf_binary *elf)
89 {
90 return elf_uval(elf, elf->ehdr, e_shnum);
91 }
93 int elf_phdr_count(struct elf_binary *elf)
94 {
95 return elf_uval(elf, elf->ehdr, e_phnum);
96 }
98 const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name)
99 {
100 uint64_t count = elf_shdr_count(elf);
101 const elf_shdr *shdr;
102 const char *sname;
103 int i;
105 for ( i = 0; i < count; i++ )
106 {
107 shdr = elf_shdr_by_index(elf, i);
108 sname = elf_section_name(elf, shdr);
109 if ( sname && !strcmp(sname, name) )
110 return shdr;
111 }
112 return NULL;
113 }
115 const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index)
116 {
117 uint64_t count = elf_shdr_count(elf);
118 const void *ptr;
120 if ( index >= count )
121 return NULL;
123 ptr = (elf->image
124 + elf_uval(elf, elf->ehdr, e_shoff)
125 + elf_uval(elf, elf->ehdr, e_shentsize) * index);
126 return ptr;
127 }
129 const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index)
130 {
131 uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
132 const void *ptr;
134 if ( index >= count )
135 return NULL;
137 ptr = (elf->image
138 + elf_uval(elf, elf->ehdr, e_phoff)
139 + elf_uval(elf, elf->ehdr, e_phentsize) * index);
140 return ptr;
141 }
143 const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr)
144 {
145 if ( elf->sec_strtab == NULL )
146 return "unknown";
147 return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
148 }
150 const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr)
151 {
152 return elf->image + elf_uval(elf, shdr, sh_offset);
153 }
155 const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr)
156 {
157 return elf->image
158 + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
159 }
161 const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr)
162 {
163 return elf->image + elf_uval(elf, phdr, p_offset);
164 }
166 const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr)
167 {
168 return elf->image
169 + elf_uval(elf, phdr, p_offset) + elf_uval(elf, phdr, p_filesz);
170 }
172 const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol)
173 {
174 const void *ptr = elf_section_start(elf, elf->sym_tab);
175 const void *end = elf_section_end(elf, elf->sym_tab);
176 const elf_sym *sym;
177 uint64_t info, name;
179 for ( ; ptr < end; ptr += elf_size(elf, sym) )
180 {
181 sym = ptr;
182 info = elf_uval(elf, sym, st_info);
183 name = elf_uval(elf, sym, st_name);
184 if ( ELF32_ST_BIND(info) != STB_GLOBAL )
185 continue;
186 if ( strcmp(elf->sym_strtab + name, symbol) )
187 continue;
188 return sym;
189 }
190 return NULL;
191 }
193 const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index)
194 {
195 const void *ptr = elf_section_start(elf, elf->sym_tab);
196 const elf_sym *sym;
198 sym = ptr + index * elf_size(elf, sym);
199 return sym;
200 }
202 const char *elf_note_name(struct elf_binary *elf, const elf_note * note)
203 {
204 return (void *)note + elf_size(elf, note);
205 }
207 const void *elf_note_desc(struct elf_binary *elf, const elf_note * note)
208 {
209 int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
211 return (void *)note + elf_size(elf, note) + namesz;
212 }
214 uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note)
215 {
216 const void *desc = elf_note_desc(elf, note);
217 int descsz = elf_uval(elf, note, descsz);
219 switch (descsz)
220 {
221 case 1:
222 case 2:
223 case 4:
224 case 8:
225 return elf_access_unsigned(elf, desc, 0, descsz);
226 default:
227 return 0;
228 }
229 }
230 const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note)
231 {
232 int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
233 int descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
235 return (void *)note + elf_size(elf, note) + namesz + descsz;
236 }
238 /* ------------------------------------------------------------------------ */
240 int elf_is_elfbinary(const void *image)
241 {
242 const Elf32_Ehdr *ehdr = image;
244 return IS_ELF(*ehdr);
245 }
247 int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr)
248 {
249 uint64_t p_type = elf_uval(elf, phdr, p_type);
250 uint64_t p_flags = elf_uval(elf, phdr, p_flags);
252 return ((p_type == PT_LOAD) && (p_flags & (PF_R | PF_W | PF_X)) != 0);
253 }
255 /*
256 * Local variables:
257 * mode: C
258 * c-set-style: "BSD"
259 * c-basic-offset: 4
260 * tab-width: 4
261 * indent-tabs-mode: nil
262 * End:
263 */