1 /*
2  * Copyright (C) 2016 Citrix Systems R&D Ltd.
3  */
4 
5 #include <xen/errno.h>
6 #include <xen/lib.h>
7 #include <xen/symbols.h>
8 #include <xen/livepatch_elf.h>
9 #include <xen/livepatch.h>
10 
11 const struct livepatch_elf_sec *
livepatch_elf_sec_by_name(const struct livepatch_elf * elf,const char * name)12 livepatch_elf_sec_by_name(const struct livepatch_elf *elf,
13                           const char *name)
14 {
15     unsigned int i;
16 
17     for ( i = 1; i < elf->hdr->e_shnum; i++ )
18     {
19         if ( !strcmp(name, elf->sec[i].name) )
20             return &elf->sec[i];
21     }
22 
23     return NULL;
24 }
25 
elf_verify_strtab(const struct livepatch_elf_sec * sec)26 static int elf_verify_strtab(const struct livepatch_elf_sec *sec)
27 {
28     const Elf_Shdr *s;
29     const char *contents;
30 
31     s = sec->sec;
32 
33     if ( s->sh_type != SHT_STRTAB )
34         return -EINVAL;
35 
36     if ( !s->sh_size )
37         return -EINVAL;
38 
39     contents = sec->data;
40 
41     if ( contents[0] || contents[s->sh_size - 1] )
42         return -EINVAL;
43 
44     return 0;
45 }
46 
elf_resolve_sections(struct livepatch_elf * elf,const void * data)47 static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
48 {
49     struct livepatch_elf_sec *sec;
50     unsigned int i;
51     Elf_Off delta;
52     int rc;
53 
54     /* livepatch_elf_load sanity checked e_shnum. */
55     sec = xzalloc_array(struct livepatch_elf_sec, elf->hdr->e_shnum);
56     if ( !sec )
57     {
58         printk(XENLOG_ERR LIVEPATCH"%s: Could not allocate memory for section table\n",
59                elf->name);
60         return -ENOMEM;
61     }
62 
63     elf->sec = sec;
64 
65     /* e_shoff and e_shnum overflow checks are done in livepatch_header_check. */
66     delta = elf->hdr->e_shoff + elf->hdr->e_shnum * elf->hdr->e_shentsize;
67     ASSERT(delta <= elf->len);
68 
69     for ( i = 1; i < elf->hdr->e_shnum; i++ )
70     {
71         delta = elf->hdr->e_shoff + i * elf->hdr->e_shentsize;
72 
73         sec[i].sec = data + delta;
74 
75         delta = sec[i].sec->sh_offset;
76         /*
77          * N.B. elf_resolve_section_names, elf_get_sym skip this check as
78          * we do it here.
79          */
80         if ( delta < sizeof(Elf_Ehdr) ||
81              (sec[i].sec->sh_type != SHT_NOBITS && /* Skip SHT_NOBITS */
82               (delta > elf->len || (delta + sec[i].sec->sh_size > elf->len))) )
83         {
84             printk(XENLOG_ERR LIVEPATCH "%s: Section [%u] data %s of payload\n",
85                    elf->name, i,
86                    delta < sizeof(Elf_Ehdr) ? "at ELF header" : "is past end");
87             return -EINVAL;
88         }
89         else if ( sec[i].sec->sh_addralign & (sec[i].sec->sh_addralign - 1) )
90         {
91             printk(XENLOG_ERR LIVEPATCH "%s: Section [%u] alignment (%#"PRIxElfAddr") is not supported\n",
92                    elf->name, i, sec[i].sec->sh_addralign);
93             return -EOPNOTSUPP;
94         }
95         else if ( sec[i].sec->sh_addralign &&
96                   sec[i].sec->sh_addr % sec[i].sec->sh_addralign )
97         {
98             printk(XENLOG_ERR LIVEPATCH "%s: Section [%u] addr (%#"PRIxElfAddr") is not aligned properly (%#"PRIxElfAddr")\n",
99                    elf->name, i, sec[i].sec->sh_addr, sec[i].sec->sh_addralign);
100             return -EINVAL;
101         }
102         else if ( (sec[i].sec->sh_flags & (SHF_WRITE | SHF_ALLOC)) &&
103                   sec[i].sec->sh_type == SHT_NOBITS &&
104                   sec[i].sec->sh_size > LIVEPATCH_MAX_SIZE )
105             return -EINVAL;
106 
107         sec[i].data = data + delta;
108         /* Name is populated in elf_resolve_section_names. */
109         sec[i].name = NULL;
110 
111         if ( sec[i].sec->sh_type == SHT_SYMTAB )
112         {
113             if ( elf->symtab )
114             {
115                 printk(XENLOG_ERR LIVEPATCH "%s: Unsupported multiple symbol tables\n",
116                        elf->name);
117                 return -EOPNOTSUPP;
118             }
119 
120             elf->symtab = &sec[i];
121 
122             elf->symtab_idx = i;
123             /*
124              * elf->symtab->sec->sh_link would point to the right section
125              * but we hadn't finished parsing all the sections.
126              */
127             if ( elf->symtab->sec->sh_link >= elf->hdr->e_shnum )
128             {
129                 printk(XENLOG_ERR LIVEPATCH
130                        "%s: Symbol table idx (%u) to strtab past end (%u)\n",
131                        elf->name, elf->symtab->sec->sh_link,
132                        elf->hdr->e_shnum);
133                 return -EINVAL;
134             }
135         }
136     }
137 
138     if ( !elf->symtab )
139     {
140         printk(XENLOG_ERR LIVEPATCH "%s: No symbol table found\n",
141                elf->name);
142         return -EINVAL;
143     }
144 
145     if ( !elf->symtab->sec->sh_size ||
146          elf->symtab->sec->sh_entsize < sizeof(Elf_Sym) ||
147          elf->symtab->sec->sh_size % elf->symtab->sec->sh_entsize )
148     {
149         printk(XENLOG_ERR LIVEPATCH "%s: Symbol table header is corrupted\n",
150                elf->name);
151         return -EINVAL;
152     }
153 
154     /*
155      * There can be multiple SHT_STRTAB (.shstrtab, .strtab) so pick the one
156      * associated with the symbol table.
157      */
158     elf->strtab = &sec[elf->symtab->sec->sh_link];
159 
160     rc = elf_verify_strtab(elf->strtab);
161     if ( rc )
162     {
163         printk(XENLOG_ERR LIVEPATCH "%s: String table section is corrupted\n",
164                elf->name);
165     }
166 
167     return rc;
168 }
169 
elf_resolve_section_names(struct livepatch_elf * elf,const void * data)170 static int elf_resolve_section_names(struct livepatch_elf *elf, const void *data)
171 {
172     const char *shstrtab;
173     unsigned int i;
174     Elf_Off offset, delta;
175     struct livepatch_elf_sec *sec;
176     int rc;
177 
178     /*
179      * The elf->sec[0 -> e_shnum] structures have been verified by
180      * elf_resolve_sections. Find file offset for section string table
181      * (normally called .shstrtab)
182      */
183     sec = &elf->sec[elf->hdr->e_shstrndx];
184 
185     rc = elf_verify_strtab(sec);
186     if ( rc )
187     {
188         printk(XENLOG_ERR LIVEPATCH "%s: Section string table is corrupted\n",
189                elf->name);
190         return rc;
191     }
192 
193     /* Verified in elf_resolve_sections but just in case. */
194     offset = sec->sec->sh_offset;
195     ASSERT(offset < elf->len && (offset + sec->sec->sh_size <= elf->len));
196 
197     shstrtab = data + offset;
198 
199     for ( i = 1; i < elf->hdr->e_shnum; i++ )
200     {
201         delta = elf->sec[i].sec->sh_name;
202 
203         /* Boundary check on offset of name within the .shstrtab. */
204         if ( delta >= sec->sec->sh_size )
205         {
206             printk(XENLOG_ERR LIVEPATCH "%s: Section %u name is not within .shstrtab\n",
207                    elf->name, i);
208             return -EINVAL;
209         }
210 
211         elf->sec[i].name = shstrtab + delta;
212     }
213 
214     return 0;
215 }
216 
elf_get_sym(struct livepatch_elf * elf,const void * data)217 static int elf_get_sym(struct livepatch_elf *elf, const void *data)
218 {
219     const struct livepatch_elf_sec *symtab_sec, *strtab_sec;
220     struct livepatch_elf_sym *sym;
221     unsigned int i, nsym;
222     Elf_Off offset;
223     Elf_Word delta;
224 
225     symtab_sec = elf->symtab;
226     strtab_sec = elf->strtab;
227 
228     /* Pointers arithmetic to get file offset. */
229     offset = strtab_sec->data - data;
230 
231     /* Checked already in elf_resolve_sections, but just in case. */
232     ASSERT(offset == strtab_sec->sec->sh_offset);
233     ASSERT(offset < elf->len && (offset + strtab_sec->sec->sh_size <= elf->len));
234 
235     /* symtab_sec->data was computed in elf_resolve_sections. */
236     ASSERT((symtab_sec->sec->sh_offset + data) == symtab_sec->data);
237 
238     /* No need to check values as elf_resolve_sections did it. */
239     nsym = symtab_sec->sec->sh_size / symtab_sec->sec->sh_entsize;
240 
241     sym = xzalloc_array(struct livepatch_elf_sym, nsym);
242     if ( !sym )
243     {
244         printk(XENLOG_ERR LIVEPATCH "%s: Could not allocate memory for symbols\n",
245                elf->name);
246         return -ENOMEM;
247     }
248 
249     /* So we don't leak memory. */
250     elf->sym = sym;
251 
252     for ( i = 1; i < nsym; i++ )
253     {
254         const Elf_Sym *s = symtab_sec->data + symtab_sec->sec->sh_entsize * i;
255 
256         delta = s->st_name;
257         /* Boundary check within the .strtab. */
258         if ( delta >= strtab_sec->sec->sh_size )
259         {
260             printk(XENLOG_ERR LIVEPATCH "%s: Symbol [%u] name is not within .strtab\n",
261                    elf->name, i);
262             return -EINVAL;
263         }
264 
265         sym[i].sym = s;
266         sym[i].name = strtab_sec->data + delta;
267         if ( arch_livepatch_symbol_deny(elf, &sym[i]) )
268         {
269             printk(XENLOG_ERR LIVEPATCH "%s: Symbol '%s' should not be in payload\n",
270                    elf->name, sym[i].name);
271             return -EINVAL;
272         }
273     }
274     elf->nsym = nsym;
275 
276     return 0;
277 }
278 
livepatch_elf_resolve_symbols(struct livepatch_elf * elf)279 int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
280 {
281     unsigned int i;
282     int rc = 0;
283 
284     ASSERT(elf->sym);
285 
286     for ( i = 1; i < elf->nsym; i++ )
287     {
288         unsigned int idx = elf->sym[i].sym->st_shndx;
289         const Elf_Sym *sym = elf->sym[i].sym;
290         Elf_Addr st_value = sym->st_value;
291 
292         switch ( idx )
293         {
294         case SHN_COMMON:
295             printk(XENLOG_ERR LIVEPATCH "%s: Unexpected common symbol: %s\n",
296                    elf->name, elf->sym[i].name);
297             rc = -EINVAL;
298             break;
299 
300         case SHN_UNDEF:
301             st_value = symbols_lookup_by_name(elf->sym[i].name);
302             if ( !st_value )
303             {
304                 st_value = livepatch_symbols_lookup_by_name(elf->sym[i].name);
305                 if ( !st_value )
306                 {
307                     printk(XENLOG_ERR LIVEPATCH "%s: Unknown symbol: %s\n",
308                            elf->name, elf->sym[i].name);
309                     rc = -ENOENT;
310                     break;
311                 }
312             }
313             dprintk(XENLOG_DEBUG, LIVEPATCH "%s: Undefined symbol resolved: %s => %#"PRIxElfAddr"\n",
314                     elf->name, elf->sym[i].name, st_value);
315             break;
316 
317         case SHN_ABS:
318             dprintk(XENLOG_DEBUG, LIVEPATCH "%s: Absolute symbol: %s => %#"PRIxElfAddr"\n",
319                     elf->name, elf->sym[i].name, sym->st_value);
320             break;
321 
322         default:
323             /* SHN_COMMON and SHN_ABS are above. */
324             if ( idx >= SHN_LORESERVE )
325                 rc = -EOPNOTSUPP;
326             else if ( idx >= elf->hdr->e_shnum )
327                 rc = -EINVAL;
328 
329             if ( rc )
330             {
331                 printk(XENLOG_ERR LIVEPATCH "%s: Out of bounds symbol section %#x\n",
332                        elf->name, idx);
333                 break;
334             }
335 
336             if ( livepatch_elf_ignore_section(elf->sec[idx].sec) )
337                 break;
338 
339             st_value += (unsigned long)elf->sec[idx].load_addr;
340             if ( elf->sym[i].name )
341                 dprintk(XENLOG_DEBUG, LIVEPATCH "%s: Symbol resolved: %s => %#"PRIxElfAddr" (%s)\n",
342                        elf->name, elf->sym[i].name,
343                        st_value, elf->sec[idx].name);
344         }
345 
346         if ( rc )
347             break;
348 
349         ((Elf_Sym *)sym)->st_value = st_value;
350     }
351 
352     return rc;
353 }
354 
livepatch_elf_perform_relocs(struct livepatch_elf * elf)355 int livepatch_elf_perform_relocs(struct livepatch_elf *elf)
356 {
357     struct livepatch_elf_sec *r, *base;
358     unsigned int i;
359     int rc = 0;
360     size_t sz;
361 
362     ASSERT(elf->sym);
363 
364     for ( i = 1; i < elf->hdr->e_shnum; i++ )
365     {
366         r = &elf->sec[i];
367 
368         if ( (r->sec->sh_type != SHT_RELA) &&
369              (r->sec->sh_type != SHT_REL) )
370             continue;
371 
372          /* Is it a valid relocation section? */
373          if ( r->sec->sh_info >= elf->hdr->e_shnum )
374             continue;
375 
376          base = &elf->sec[r->sec->sh_info];
377 
378          /* Don't relocate non-allocated sections. */
379          if ( !(base->sec->sh_flags & SHF_ALLOC) )
380             continue;
381 
382         if ( r->sec->sh_link != elf->symtab_idx )
383         {
384             printk(XENLOG_ERR LIVEPATCH "%s: Relative link of %s is incorrect (%d, expected=%d)\n",
385                    elf->name, r->name, r->sec->sh_link, elf->symtab_idx);
386             rc = -EINVAL;
387             break;
388         }
389 
390         if ( r->sec->sh_type == SHT_RELA )
391             sz = sizeof(Elf_RelA);
392         else
393             sz = sizeof(Elf_Rel);
394 
395         if ( !r->sec->sh_size )
396             continue;
397 
398         if ( r->sec->sh_entsize < sz || r->sec->sh_size % r->sec->sh_entsize )
399         {
400             printk(XENLOG_ERR LIVEPATCH "%s: Section relative header is corrupted\n",
401                    elf->name);
402             rc = -EINVAL;
403             break;
404         }
405 
406         if ( r->sec->sh_type == SHT_RELA )
407             rc = arch_livepatch_perform_rela(elf, base, r);
408         else /* SHT_REL */
409             rc = arch_livepatch_perform_rel(elf, base, r);
410 
411         if ( rc )
412             break;
413     }
414 
415     return rc;
416 }
417 
livepatch_header_check(const struct livepatch_elf * elf)418 static int livepatch_header_check(const struct livepatch_elf *elf)
419 {
420     const Elf_Ehdr *hdr = elf->hdr;
421     int rc;
422 
423     if ( sizeof(*elf->hdr) > elf->len )
424     {
425         printk(XENLOG_ERR LIVEPATCH "%s: Section header is bigger than payload\n",
426                elf->name);
427         return -EINVAL;
428     }
429 
430     if ( !IS_ELF(*hdr) )
431     {
432         printk(XENLOG_ERR LIVEPATCH "%s: Not an ELF payload\n", elf->name);
433         return -EINVAL;
434     }
435 
436     /* EI_CLASS, EI_DATA, and e_flags are platform specific. */
437     if ( hdr->e_version != EV_CURRENT ||
438          hdr->e_ident[EI_VERSION] != EV_CURRENT ||
439          hdr->e_ident[EI_ABIVERSION] != 0 ||
440          (hdr->e_ident[EI_OSABI] != ELFOSABI_NONE &&
441           hdr->e_ident[EI_OSABI] != ELFOSABI_FREEBSD) ||
442          hdr->e_type != ET_REL ||
443          hdr->e_phnum != 0 )
444     {
445         printk(XENLOG_ERR LIVEPATCH "%s: Invalid ELF payload\n", elf->name);
446         return -EOPNOTSUPP;
447     }
448 
449     rc = arch_livepatch_verify_elf(elf);
450     if ( rc )
451         return rc;
452 
453     if ( elf->hdr->e_shstrndx == SHN_UNDEF )
454     {
455         printk(XENLOG_ERR LIVEPATCH "%s: Section name idx is undefined\n",
456                elf->name);
457         return -EINVAL;
458     }
459 
460     /* Arbitrary boundary limit. */
461     if ( elf->hdr->e_shnum >= 1024 )
462     {
463         printk(XENLOG_ERR LIVEPATCH "%s: Too many (%u) sections\n",
464                elf->name, elf->hdr->e_shnum);
465         return -EOPNOTSUPP;
466     }
467 
468     /* Check that section name index is within the sections. */
469     if ( elf->hdr->e_shstrndx >= elf->hdr->e_shnum )
470     {
471         printk(XENLOG_ERR LIVEPATCH "%s: Section name idx (%u) is past end of sections (%u)\n",
472                elf->name, elf->hdr->e_shstrndx, elf->hdr->e_shnum);
473         return -EINVAL;
474     }
475 
476     if ( elf->hdr->e_shoff >= elf->len )
477     {
478         printk(XENLOG_ERR LIVEPATCH "%s: Bogus e_shoff\n", elf->name);
479         return -EINVAL;
480     }
481 
482     if ( elf->hdr->e_shentsize < sizeof(Elf_Shdr) )
483     {
484         printk(XENLOG_ERR LIVEPATCH "%s: Section header size is %u! Expected %zu.\n",
485                elf->name, elf->hdr->e_shentsize, sizeof(Elf_Shdr));
486         return -EINVAL;
487     }
488 
489     if ( ((elf->len - elf->hdr->e_shoff) / elf->hdr->e_shentsize) <
490          elf->hdr->e_shnum )
491     {
492         printk(XENLOG_ERR LIVEPATCH "%s: Section header size is corrupted\n",
493                elf->name);
494         return -EINVAL;
495     }
496 
497     return 0;
498 }
499 
livepatch_elf_load(struct livepatch_elf * elf,const void * data)500 int livepatch_elf_load(struct livepatch_elf *elf, const void *data)
501 {
502     int rc;
503 
504     elf->hdr = data;
505 
506     rc = livepatch_header_check(elf);
507     if ( rc )
508         return rc;
509 
510     rc = elf_resolve_sections(elf, data);
511     if ( rc )
512         return rc;
513 
514     rc = elf_resolve_section_names(elf, data);
515     if ( rc )
516         return rc;
517 
518     rc = elf_get_sym(elf, data);
519     if ( rc )
520         return rc;
521 
522     return 0;
523 }
524 
livepatch_elf_free(struct livepatch_elf * elf)525 void livepatch_elf_free(struct livepatch_elf *elf)
526 {
527     xfree(elf->sec);
528     elf->sec = NULL;
529     xfree(elf->sym);
530     elf->sym = NULL;
531     elf->nsym = 0;
532     elf->name = NULL;
533     elf->len = 0;
534 }
535 
536 /*
537  * Local variables:
538  * mode: C
539  * c-file-style: "BSD"
540  * c-basic-offset: 4
541  * tab-width: 4
542  * indent-tabs-mode: nil
543  * End:
544  */
545