[CRIU] [PATCH 8/9] pie/util-vdso: split parse_elf_dynamic from vdso_fill_symtable
Dmitry Safonov
dsafonov at virtuozzo.com
Wed Mar 30 08:12:29 PDT 2016
Impact: no functional changes, cleanup.
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
criu/pie/util-vdso.c | 98 +++++++++++++++++++++++++++++++++-------------------
1 file changed, 62 insertions(+), 36 deletions(-)
diff --git a/criu/pie/util-vdso.c b/criu/pie/util-vdso.c
index 3b87926d230e..439c7a13c9bf 100644
--- a/criu/pie/util-vdso.c
+++ b/criu/pie/util-vdso.c
@@ -140,6 +140,64 @@ err_oob:
return -EFAULT;
}
+/*
+ * Parse dynamic program header.
+ * Output parameters are:
+ * @dyn_strtab - address of the symbol table
+ * @dyn_symtab - address of the string table section
+ * @dyn_hash - address of the symbol hash table
+ */
+static int parse_elf_dynamic(uintptr_t mem, size_t size, Phdr_t *dynamic,
+ Dyn_t **dyn_strtab, Dyn_t **dyn_symtab, Dyn_t **dyn_hash)
+{
+ Dyn_t *dyn_syment = NULL;
+ Dyn_t *dyn_strsz = NULL;
+ uintptr_t addr;
+ Dyn_t *d;
+ int i;
+
+ addr = mem + dynamic->p_offset;
+ if (__ptr_oob(addr, mem, size))
+ goto err_oob;
+
+ for (i = 0; i < dynamic->p_filesz / sizeof(*d);
+ i++, addr += sizeof(Dyn_t)) {
+ if (__ptr_struct_end_oob(addr, sizeof(Dyn_t), mem, size))
+ goto err_oob;
+ d = (void *)addr;
+
+ if (d->d_tag == DT_NULL) {
+ break;
+ } else if (d->d_tag == DT_STRTAB) {
+ *dyn_strtab = d;
+ pr_debug("DT_STRTAB: %lx\n", (unsigned long)d->d_un.d_ptr);
+ } else if (d->d_tag == DT_SYMTAB) {
+ *dyn_symtab = d;
+ pr_debug("DT_SYMTAB: %lx\n", (unsigned long)d->d_un.d_ptr);
+ } else if (d->d_tag == DT_STRSZ) {
+ dyn_strsz = d;
+ pr_debug("DT_STRSZ: %lx\n", (unsigned long)d->d_un.d_val);
+ } else if (d->d_tag == DT_SYMENT) {
+ dyn_syment = d;
+ pr_debug("DT_SYMENT: %lx\n", (unsigned long)d->d_un.d_val);
+ } else if (d->d_tag == DT_HASH) {
+ *dyn_hash = d;
+ pr_debug("DT_HASH: %lx\n", (unsigned long)d->d_un.d_ptr);
+ }
+ }
+
+ if (!*dyn_strtab || !*dyn_symtab || !dyn_strsz || !dyn_syment || !*dyn_hash) {
+ pr_err("Not all dynamic entries are present\n");
+ return -EINVAL;
+ }
+
+ return 0;
+
+err_oob:
+ pr_err("Corrupted Elf dynamic section\n");
+ return -EFAULT;
+}
+
int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t)
{
const char *vdso_symbols[VDSO_SYMBOL_MAX] = {
@@ -149,11 +207,8 @@ int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t)
Phdr_t *dynamic = NULL, *load = NULL;
Dyn_t *dyn_strtab = NULL;
Dyn_t *dyn_symtab = NULL;
- Dyn_t *dyn_strsz = NULL;
- Dyn_t *dyn_syment = NULL;
Dyn_t *dyn_hash = NULL;
Word_t *hash = NULL;
- Dyn_t *d;
Word_t *bucket, *chain;
Word_t nbucket, nchain;
@@ -183,40 +238,11 @@ int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t)
* Dynamic section tags should provide us the rest of information
* needed. Note that we're interested in a small set of tags.
*/
- addr = mem + dynamic->p_offset;
- if (__ptr_oob(addr, mem, size))
- goto err_oob;
-
- for (i = 0; i < dynamic->p_filesz / sizeof(*d);
- i++, addr += sizeof(Dyn_t)) {
- if (__ptr_struct_end_oob(addr, sizeof(Dyn_t), mem, size))
- goto err_oob;
- d = (void *)addr;
-
- if (d->d_tag == DT_NULL) {
- break;
- } else if (d->d_tag == DT_STRTAB) {
- dyn_strtab = d;
- pr_debug("DT_STRTAB: %lx\n", (unsigned long)d->d_un.d_ptr);
- } else if (d->d_tag == DT_SYMTAB) {
- dyn_symtab = d;
- pr_debug("DT_SYMTAB: %lx\n", (unsigned long)d->d_un.d_ptr);
- } else if (d->d_tag == DT_STRSZ) {
- dyn_strsz = d;
- pr_debug("DT_STRSZ: %lx\n", (unsigned long)d->d_un.d_val);
- } else if (d->d_tag == DT_SYMENT) {
- dyn_syment = d;
- pr_debug("DT_SYMENT: %lx\n", (unsigned long)d->d_un.d_val);
- } else if (d->d_tag == DT_HASH) {
- dyn_hash = d;
- pr_debug("DT_HASH: %lx\n", (unsigned long)d->d_un.d_ptr);
- }
- }
- if (!dyn_strtab || !dyn_symtab || !dyn_strsz || !dyn_syment || !dyn_hash) {
- pr_err("Not all dynamic entries are present\n");
- return -EINVAL;
- }
+ ret = parse_elf_dynamic(mem, size, dynamic,
+ &dyn_strtab, &dyn_symtab, &dyn_hash);
+ if (ret < 0)
+ return ret;
addr = mem + dyn_strtab->d_un.d_val - load->p_vaddr;
if (__ptr_oob(addr, mem, size))
--
2.7.4
More information about the CRIU
mailing list