Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ all:
$(CC) -O0 -g -fPIC -pie elfparse.c ../src/libelfmaster.a -o elfparse
$(CC) -O0 -g merged.c ../src/libelfmaster.a -o merged
$(CC) -O0 -g ldd.c ../src/libelfmaster.a -o ldd
$(CC) -O0 -g ldd2.c ../src/libelfmaster.a -o ldd2
$(CC) -O2 -g read_mem.c ../src/libelfmaster.a -o read_mem
$(CC) -O2 -g plt_dump.c ../src/libelfmaster.a -o plt_dump
$(CC) -O2 -g plt_dump2.c ../src/libelfmaster.a -o plt_dump2
Expand Down
5 changes: 3 additions & 2 deletions examples/ldd.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ int main(int argc, char **argv)
exit(EXIT_SUCCESS);
}

if (elf_open_object(argv[1], &obj, ELF_LOAD_F_FORENSICS, &error) == false) {
if (elf_open_object(argv[1], &obj, ELF_LOAD_F_LXC_MODE|ELF_LOAD_F_FORENSICS, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}

elf_lxc_set_rootfs(&obj, "/cont/arch/rootfs");
if (elf_shared_object_iterator_init(&obj, &so_iter,
NULL, ELF_SO_LDSO_FAST_F|ELF_SO_IGNORE_VDSO_F|ELF_SO_RESOLVE_F, &error) == false) {
"/cont/arch/rootfs/etc/ld.so.cache", /*ELF_SO_LDSO_FAST_F|ELF_SO_IGNORE_VDSO_F|*/ELF_SO_RESOLVE_F|ELF_SO_RESOLVE_ALL_F, &error) == false) {
fprintf(stderr, "elf_shared_object_iterator_init failed: %s\n",
elf_error_msg(&error));
return -1;
Expand Down
12 changes: 12 additions & 0 deletions include/libelfmaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
#define ELF_ERRNO_INVALMAGIC 0
#define ELF_ERRNO_INVALSHDRS 1

#define ELF_LXC_ROOTFS_VAR "LXC_ROOTFS_VAR_LIBELFMASTER"

typedef struct elf_error {
char string[MAX_ERROR_STR_LEN];
int _errno;
Expand Down Expand Up @@ -560,6 +562,7 @@ typedef struct elf_shared_object_iterator {
#define ELF_LOAD_F_MODIFY (1UL << 3) //Used for modifying binaries
#define ELF_LOAD_F_ULEXEC (1UL << 4) //Used for ulexec based debugging API
#define ELF_LOAD_F_MAP_WRITE (1UL << 5)
#define ELF_LOAD_F_LXC_MODE (1UL << 6) // Used when scanning binaries within an LXC container

/*
* Loads an ELF object of any type, for reading or modifying.
Expand Down Expand Up @@ -977,4 +980,13 @@ bool elf_dynsym_commit(elfobj_t *);
* freeing the existing internal representation and then sorting a new array of strings.
*/
bool elf_section_commit(elfobj_t *);

/*
* Set the environment variable that libelfmaster reads to get
* the LXC containers rootfs in order to resolve shared libaries
* from this location internally.
*/
bool elf_lxc_set_rootfs(elfobj_t *, const char *);
bool elf_lxc_get_rootfs(elfobj_t *, char *, const size_t);

#endif
19 changes: 16 additions & 3 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include "dwarf.h"
#include "misc.h"

static char *
ldso_strdup(struct elf_shared_object_iterator *, const char *);

/*
* TODO Why is this defined in internal.c?
Expand Down Expand Up @@ -508,6 +510,18 @@ ldso_cache_bsearch(struct elf_shared_object_iterator *iter,
right = middle - 1;
}
}

if (iter->obj->load_flags & ELF_LOAD_F_LXC_MODE) {
char lxc_path[PATH_MAX];

if (elf_lxc_get_rootfs(iter->obj, lxc_path, PATH_MAX / 2) == false) {
if (strlen(lxc_path) + strlen(best) >= PATH_MAX)
return false;
}
strcat(lxc_path, best);
best = ldso_strdup(iter, lxc_path);
}

return best;
}

Expand Down Expand Up @@ -660,10 +674,9 @@ ldso_recursive_cache_resolve(struct elf_shared_object_iterator *iter,
* object iterator will use the linked list cache.
*/
current->path = ldso_strdup(iter, path);
if (current->path == NULL) {
if (current->path == NULL)
goto err;
}
if (ldso_insert_yield_entry(iter, current->path) == false){
if (ldso_insert_yield_entry(iter, current->path) == false) {
goto err;
}
if (ldso_recursive_cache_resolve(iter, current->basename) == false){
Expand Down
33 changes: 30 additions & 3 deletions src/libelfmaster.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,33 @@
(((addr) + __alignof__ (struct cache_file_new) -1) \
& (~(__alignof__ (struct cache_file_new) - 1)))

bool
elf_lxc_set_rootfs(elfobj_t *obj, const char *lxcpath)
{
if ((obj->load_flags & ELF_LOAD_F_LXC_MODE) == false) {
return true;
}
if (setenv(ELF_LXC_ROOTFS_VAR, lxcpath, 1) == 0)
return true;
return false;
}

bool
elf_lxc_get_rootfs(elfobj_t *obj, char *out, const size_t maxlen)
{
char *v = secure_getenv(ELF_LXC_ROOTFS_VAR);

(void) obj;

if (maxlen > PATH_MAX)
return false;
if (strlen(v) > maxlen - 1)
return false;
strncpy(out, v, maxlen);
out[maxlen - 1] = '\0';
return true;
}

bool
elf_symtab_count(elfobj_t *obj, uint64_t *count)
{
Expand Down Expand Up @@ -1520,17 +1547,17 @@ elf_shared_object_iterator_init(struct elfobj *obj,
}
iter->fd = open(cache_file, O_RDONLY);
if (iter->fd < 0) {
return elf_error_set(error, "open %s: %s", CACHE_FILE,
return elf_error_set(error, "open %s: %s", cache_file,
strerror(errno));
}
if (fstat(iter->fd, &iter->st) < 0) {
return elf_error_set(error, "fstat %s: %s", CACHE_FILE,
return elf_error_set(error, "fstat %s: %s", cache_file,
strerror(errno));
}
iter->mem = mmap(NULL, iter->st.st_size, PROT_READ, MAP_PRIVATE,
iter->fd, 0);
if (iter->mem == MAP_FAILED) {
return elf_error_set(error, "mmap %s: %s", CACHE_FILE,
return elf_error_set(error, "mmap %s: %s", cache_file,
strerror(errno));
}
iter->cache = iter->mem;
Expand Down