summaryrefslogtreecommitdiff
path: root/libdwfl/open.c
diff options
context:
space:
mode:
authorAleksei Vetrov <vvvvvv@google.com>2022-09-20 13:36:37 +0000
committerMark Wielaard <mark@klomp.org>2022-10-16 17:09:42 +0200
commit64ee2cb792e7b6ba6ad2a5759bff7ce8714e4668 (patch)
treeac911024367364c26a5a557b6aed95aaed3245e9 /libdwfl/open.c
parent6284f4d12ccbc6405e986fd84ac6d4d72dc9c2a7 (diff)
downloadelfutils-64ee2cb792e7b6ba6ad2a5759bff7ce8714e4668.tar.gz
libdwfl: add dwfl_report_offline_memory
This method allows to read and report ELF from memory instead of opening a file. That way arbitrary memory can be worked with, e.g. when coming from a stream without the need to persist. Another useful application is for fuzzing, because fuzzers might be able to track accesses to the memory and change the fuzzer input to cover more edge cases through more targeted input. Hence, add a new function along with a test case. Signed-off-by: Aleksei Vetrov <vvvvvv@google.com>
Diffstat (limited to 'libdwfl/open.c')
-rw-r--r--libdwfl/open.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/libdwfl/open.c b/libdwfl/open.c
index 77bd2bd9..da8b59a3 100644
--- a/libdwfl/open.c
+++ b/libdwfl/open.c
@@ -1,5 +1,6 @@
/* Decompression support for libdwfl: zlib (gzip), bzlib (bzip2) or lzma (xz).
Copyright (C) 2009, 2016 Red Hat, Inc.
+ Copyright (C) 2022 Google LLC
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -53,6 +54,9 @@ static Dwfl_Error
decompress (int fd __attribute__ ((unused)), Elf **elf)
{
Dwfl_Error error = DWFL_E_BADELF;
+ /* ELF cannot be decompressed, if there is no file descriptor. */
+ if (fd == -1)
+ return error;
void *buffer = NULL;
size_t size = 0;
@@ -124,11 +128,12 @@ what_kind (int fd, Elf **elfp, Elf_Kind *kind, bool *may_close_fd)
static Dwfl_Error
libdw_open_elf (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok,
- bool never_close_fd, bool bad_elf_ok)
+ bool never_close_fd, bool bad_elf_ok, bool use_elfp)
{
bool may_close_fd = false;
- Elf *elf = elf_begin (*fdp, ELF_C_READ_MMAP_PRIVATE, NULL);
+ Elf *elf =
+ use_elfp ? *elfp : elf_begin (*fdp, ELF_C_READ_MMAP_PRIVATE, NULL);
Elf_Kind kind;
Dwfl_Error error = what_kind (*fdp, &elf, &kind, &may_close_fd);
@@ -194,11 +199,28 @@ libdw_open_elf (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok,
Dwfl_Error internal_function
__libdw_open_file (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok)
{
- return libdw_open_elf (fdp, elfp, close_on_fail, archive_ok, false, false);
+ return libdw_open_elf (fdp, elfp, close_on_fail, archive_ok, false, false,
+ false);
+}
+
+Dwfl_Error internal_function
+__libdw_open_elf_memory (char *data, size_t size, Elf **elfp, bool archive_ok)
+{
+ /* It is ok to use `fd == -1` here, because libelf uses it as a value for
+ "no file opened" and code supports working with this value, and also
+ `never_close_fd == false` is passed to prevent closing non-existant file.
+ The only caveat is in `decompress` method, which doesn't support
+ decompressing from memory, so reading compressed zImage using this method
+ won't work. */
+ int fd = -1;
+ *elfp = elf_memory (data, size);
+ /* Allow using this ELF as reference for subsequent elf_begin calls. */
+ (*elfp)->cmd = ELF_C_READ_MMAP_PRIVATE;
+ return libdw_open_elf (&fd, elfp, false, archive_ok, true, false, true);
}
Dwfl_Error internal_function
__libdw_open_elf (int fd, Elf **elfp)
{
- return libdw_open_elf (&fd, elfp, false, true, true, true);
+ return libdw_open_elf (&fd, elfp, false, true, true, true, false);
}