jail: ignore missing .dynamic sect
[project/procd.git] / jail / elf.c
index 136789e1300dce1b924c13edd91931082d767bd0..978fc6e113514578d302e343b9bb7807f53bb941 100644 (file)
@@ -81,7 +81,7 @@ int lib_open(char **fullpath, const char *file)
 
        list_for_each_entry(p, &library_paths, list) {
                snprintf(path, sizeof(path), "%s/%s", p->path, file);
-               fd = open(path, O_RDONLY);
+               fd = open(path, O_RDONLY|O_CLOEXEC);
                if (fd >= 0) {
                        *fullpath = strdup(path);
                        break;
@@ -102,7 +102,7 @@ const char* find_lib(const char *file)
        return l->path;
 }
 
-static int elf64_find_section(const char *map, unsigned int type, unsigned int *offset, unsigned int *size, unsigned int *vaddr)
+static int elf64_find_section(const char *map, unsigned int type, unsigned long *offset, unsigned long *size, unsigned long *vaddr)
 {
        Elf64_Ehdr *e;
        Elf64_Phdr *ph;
@@ -125,7 +125,7 @@ static int elf64_find_section(const char *map, unsigned int type, unsigned int *
        return -1;
 }
 
-static int elf32_find_section(const char *map, unsigned int type, unsigned int *offset, unsigned int *size, unsigned int *vaddr)
+static int elf32_find_section(const char *map, unsigned int type, unsigned long *offset, unsigned long *size, unsigned long *vaddr)
 {
        Elf32_Ehdr *e;
        Elf32_Phdr *ph;
@@ -148,7 +148,7 @@ static int elf32_find_section(const char *map, unsigned int type, unsigned int *
        return -1;
 }
 
-static int elf_find_section(const char *map, unsigned int type, unsigned int *offset, unsigned int *size, unsigned int *vaddr)
+static int elf_find_section(const char *map, unsigned int type, unsigned long *offset, unsigned long *size, unsigned long *vaddr)
 {
        int clazz = map[EI_CLASS];
 
@@ -162,7 +162,7 @@ static int elf_find_section(const char *map, unsigned int type, unsigned int *of
        return -1;
 }
 
-static int elf32_scan_dynamic(const char *map, int dyn_offset, int dyn_size, int load_offset)
+static int elf32_scan_dynamic(const char *map, unsigned long dyn_offset, unsigned long dyn_size, long load_offset)
 {
        Elf32_Dyn *dynamic = (Elf32_Dyn *) (map + dyn_offset);
        const char *strtab = NULL;
@@ -196,7 +196,7 @@ static int elf32_scan_dynamic(const char *map, int dyn_offset, int dyn_size, int
        return 0;
 }
 
-static int elf64_scan_dynamic(const char *map, int dyn_offset, int dyn_size, int load_offset)
+static int elf64_scan_dynamic(const char *map, unsigned long dyn_offset, unsigned long dyn_size, long load_offset)
 {
        Elf64_Dyn *dynamic = (Elf64_Dyn *) (map + dyn_offset);
        const char *strtab = NULL;
@@ -232,17 +232,22 @@ static int elf64_scan_dynamic(const char *map, int dyn_offset, int dyn_size, int
 
 int elf_load_deps(const char *path, const char *map)
 {
-       unsigned int dyn_offset, dyn_size;
-       unsigned int load_offset, load_vaddr;
+       unsigned long dyn_offset, dyn_size;
+       unsigned long load_offset, load_vaddr;
+       unsigned long interp_offset;
+
+       if (elf_find_section(map, PT_INTERP, &interp_offset, NULL, NULL) == 0) {
+               add_path_and_deps(map+interp_offset, 1, -1, 0);
+       }
 
        if (elf_find_section(map, PT_LOAD, &load_offset, NULL, &load_vaddr)) {
-               ERROR("failed to load the .load section from %s\n", path);
-               return -1;
+               DEBUG("failed to load the .load section from %s\n", path);
+               return 0;
        }
 
        if (elf_find_section(map, PT_DYNAMIC, &dyn_offset, &dyn_size, NULL)) {
-               ERROR("failed to load the .dynamic section from %s\n", path);
-               return -1;
+               DEBUG("failed to load the .dynamic section from %s\n", path);
+               return 0;
        }
 
        int clazz = map[EI_CLASS];
@@ -310,3 +315,15 @@ void init_library_search(void)
        alloc_library_path("/usr/lib");
        load_ldso_conf("/etc/ld.so.conf");
 }
+
+void free_library_search(void)
+{
+       struct library_path *p, *ptmp;
+       struct library *l, *tmp;
+
+       list_for_each_entry_safe(p, ptmp, &library_paths, list)
+               free(p);
+
+       avl_remove_all_elements(&libraries, l, avl, tmp)
+               free(l);
+}