[PATCH] libelf: Only set shdr state when there is at least one shdr

2021-12-19 Thread Mark Wielaard
The elf shdr state only needs to be set when scncnt is at least
one. Otherwise e_shoff can be bogus. Also use unsigned arithmetic for
checking e_shoff alignment.

Signed-off-by: Mark Wielaard 
---
 libelf/ChangeLog   |  5 +
 libelf/elf_begin.c | 16 ++--
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 617d97a5..29a8aae1 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-19  Mark Wielaard  
+
+   * elf_begin.c (file_read_elf): Cast ehdr to uintptr_t before e_shoff
+   alignment check. Only set shdr state when scncnt is larger than zero.
+
 2021-12-16  Mark Wielaard  
 
* libelfP.h (NOTE_ALIGN4): And with negative unsigned long.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index bd3399de..0c9a988d 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -383,7 +383,7 @@ file_read_elf (int fildes, void *map_address, unsigned char 
*e_ident,
   if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
  && (ALLOW_UNALIGNED
- || (((uintptr_t) ((char *) ehdr + e_shoff)
+ || uintptr_t) ehdr + e_shoff)
   & (__alignof__ (Elf32_Shdr) - 1)) == 0)))
{
  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
@@ -395,8 +395,10 @@ file_read_elf (int fildes, void *map_address, unsigned 
char *e_ident,
  __libelf_seterrno (ELF_E_INVALID_ELF);
  return NULL;
}
- elf->state.elf32.shdr
-   = (Elf32_Shdr *) ((char *) ehdr + e_shoff);
+
+ if (scncnt > 0)
+   elf->state.elf32.shdr
+ = (Elf32_Shdr *) ((char *) ehdr + e_shoff);
 
  for (size_t cnt = 0; cnt < scncnt; ++cnt)
{
@@ -485,15 +487,17 @@ file_read_elf (int fildes, void *map_address, unsigned 
char *e_ident,
   if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
  && (ALLOW_UNALIGNED
- || (((uintptr_t) ((char *) ehdr + e_shoff)
+ || uintptr_t) ehdr + e_shoff)
   & (__alignof__ (Elf64_Shdr) - 1)) == 0)))
{
  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
  || unlikely (maxsize - e_shoff
   < scncnt * sizeof (Elf64_Shdr)))
goto free_and_out;
- elf->state.elf64.shdr
-   = (Elf64_Shdr *) ((char *) ehdr + e_shoff);
+
+ if (scncnt > 0)
+   elf->state.elf64.shdr
+ = (Elf64_Shdr *) ((char *) ehdr + e_shoff);
 
  for (size_t cnt = 0; cnt < scncnt; ++cnt)
{
-- 
2.30.2



[PATCH] tests: integrate fuzz-dwfl-core into the test suite

2021-12-19 Thread Evgeny Vereshchagin via Elfutils-devel
[v2]

1) At https://sourceware.org/pipermail/elfutils-devel/2021q4/004541.html
it was pointed out that build-fuzzers.sh is too tied to OSS-Fuzz
and while it was kind of decoupled from it as much as possible
in the sense that it was enough to install clang and run the script to build
the fuzz target with libFuzzer it's true that it can't be integrated smoothly
into buildbot for example where gcc is used and various configure options
control what exactly is tested. To address that, `--enable-honggfuzz` is
introduced. It looks for hfuzz-gcc, hfuzz-g++ and honggfuzz and if
they exist elfutils is built with those wrappers and the fuzz target
is additionally run for a few minutes under honggfuzz to make
regression testing more effective. It was tested on Fedora 35 and
in https://github.com/evverx/elfutils/pull/49 on Ubuntu Focal with both gcc and
clang with and without sanitizers/Valgrind
and with two versions of honggfuzz (including the latest stable version).
To make it work on Ubuntu the following commands should be run
```
apt-get install libbfd-dev libunwind8-dev
git clone https://github.com/google/honggfuzz
cd honggfuzz
git checkout 2.4
make
make PREFIX=/usr install

cd PATH/TO/ELFUTILS
autoreconf -i -f
./configure --enable-maintainer-mode --enable-honggfuzz
make check V=1 VERBOSE=1 # FUZZ_TIME can be optionally passed
```

If hongfuzz is installed elsewhere it's possible to point
configure to it with CC, CXX and HONGGFUZZ
```
./configure CC=path-to-hfuzz-gcc CXX=path-to-hfuzz-g++ 
HONGGFUZZ=path-to-honggfuzz
```

I decided to use honggfuzz instead of AFL because AFL doesn't seem
to be maintained actively anymore. Other than that I can't seem to
make it work with various combinations of compilers, sanitizers and
so on. But thanks to the way the fuzz target is written it should
be possible to add it eventually by analogy with honggfuzz.

2) fuzz-dwfl-core-corpus was renamed to fuzz-dwfl-core-crashes to
make it more clear that it isn't exaclty a seed corpus.

3) run-strip-g.sh and run-strip-nothing.sh started to compile test programs
using temporary files instead of gcc -xc -. It should address
https://github.com/google/honggfuzz/issues/431 but more generally
autoconf uses temporary files to make sure compiler works so
it seems in general it's safer to rely on compiler features that
are known to work.

4) A comment was added where I tried to expand on why the fuzz target
is written that way.

[v1]
The fuzz target was integrated into OSS-Fuzz in
https://github.com/google/oss-fuzz/pull/6944 and since then it
has been running there continously (uncovering various issues
along the way). It's all well and good but since OSS-Fuzz
is far from the elfutils repository it's unnecessarily hard
to build the fuzz target locally, verify patches and more generally
test new code to make sure that it doesn't introduce new issues (
or reintroduce regressions). This patch aims to address all those
issues by moving the fuzz target into the elfutils repository,
integrating it into the testsuite and also providing a script
that can be used to build full-fledged fuzzers utilizing libFuzzer.
With this patch applied `make check` can be used to make sure
that files kept in tests/fuzz-dwfl-core-corpus don't crash the
code on various architecures.
`--enable-sanitize-{address,undefined}` and/or `--enable-valgrind`
can additionally be used to uncover issues like
https://sourceware.org/bugzilla/show_bug.cgi?id=28685
that don't always manifest themselves in simple segfaults. On top
of all that now the fuzz target can be built and linked against
libFuzzer locally by just running `./tests/build-fuzzers.sh`.

The patch was tested in https://github.com/evverx/elfutils/pull/49 :

* the testsuite was run on aarch64, armhfp, i386, ppc64le, s390x
  and x86_64

* Fedora packages were built on those architectures;

* elfutils was built with both clang and gcc with and without sanitizers
  to make sure the tests pass there;

* `make distcheck` passed;

* coverage reports were built to make sure "static" builds are intact;

* the fuzz target was built and run with ClusterFuzzLite to make sure
  it's still compatible with OSS-Fuzz;

* the code was analyzed by various static analyzers to make sure new alerts
  aren't introduced.

Signed-off-by: Evgeny Vereshchagin 
---
 ChangeLog   |   4 +
 configure.ac|  17 
 tests/.gitignore|   1 +
 tests/ChangeLog |   8 ++
 tests/Makefile.am   |  30 ++-
 tests/build-fuzzers.sh  |  95 
 tests/fuzz-dwfl-core-crashes/bugzilla-28660 | Bin 0 -> 20890 bytes
 tests/fuzz-dwfl-core-crashes/empty  |   0
 tests/fuzz-dwfl-core-crashes/oss-fuzz-41566 | Bin 0 -> 1553 bytes
 tests/fuzz-dwfl-core-crashes/oss-fuzz-41570 | Bin 0 -> 1233 bytes
 tests/fuzz-dwfl-core-crashes/oss-fuzz-41572 | Bin 0 -> 4872 bytes
 tests/fuzz-dwfl-core.c   

[PATCH] libdwfl: Make sure that ph_buffer_size has room for at least one phdr

2021-12-19 Thread Mark Wielaard
dwfl_segment_report_module might otherwise try to handle half a phdr
taking the other half from after the buffer.

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog| 5 +
 libdwfl/dwfl_segment_report_module.c | 7 ++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index d00ce702..38e2bdaa 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-08  Mark Wielaard  
+
+   * dwfl_segment_report_module.c (dwfl_segment_report_module): Make sure
+   that ph_buffer_size has room for at least one phdr.
+
 2021-12-08  Mark Wielaard  
 
* dwfl_segment_report_module.c (dwfl_segment_report_module): Make
diff --git a/libdwfl/dwfl_segment_report_module.c 
b/libdwfl/dwfl_segment_report_module.c
index 89e05103..840d6f44 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -426,7 +426,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const 
char *name,
  buffer, otherwise it will be the size of the new buffer that
  could be read.  */
   if (ph_buffer_size != 0)
-xlatefrom.d_size = ph_buffer_size;
+{
+  phnum = ph_buffer_size / phentsize;
+  if (phnum == 0)
+   goto out;
+  xlatefrom.d_size = ph_buffer_size;
+}
 
   xlatefrom.d_buf = ph_buffer;
 
-- 
2.30.2



[PATCH] libdwfl: Make sure dyn_filesz has a sane size

2021-12-19 Thread Mark Wielaard
In dwfl_segment_report_module dyn_filesz should be able to hold at
least one Elf_Dyn element, and not be larger than possible.

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog| 6 ++
 libdwfl/dwfl_segment_report_module.c | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 38e2bdaa..1f83576d 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2021-12-08  Mark Wielaard  
+
+   * dwfl_segment_report_module.c (dwfl_segment_report_module): Make sure
+   that dyn_filesz can contain at least one Elf_Dyn and isn't larger than
+   possible.
+
 2021-12-08  Mark Wielaard  
 
* dwfl_segment_report_module.c (dwfl_segment_report_module): Make sure
diff --git a/libdwfl/dwfl_segment_report_module.c 
b/libdwfl/dwfl_segment_report_module.c
index 840d6f44..78c70795 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -787,6 +787,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char 
*name,
   if (dyn_data_size != 0)
dyn_filesz = dyn_data_size;
 
+  if ((dyn_filesz / dyn_entsize) == 0
+ || dyn_filesz > (SIZE_MAX / dyn_entsize))
+   goto out;
   void *dyns = malloc (dyn_filesz);
   Elf32_Dyn *d32 = dyns;
   Elf64_Dyn *d64 = dyns;
-- 
2.30.2



[PATCH] libdwfl: Rewrite GElf_Nhdr reading in dwfl_segment_report_module

2021-12-19 Thread Mark Wielaard
Make sure that the notes filesz is not too big. Rewrite reading of the
notes to check for overflow at every step. Also limit the size of the
buildid bytes.

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog|  5 ++
 libdwfl/dwfl_segment_report_module.c | 79 
 2 files changed, 49 insertions(+), 35 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 1f83576d..18ffc347 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-19  Mark Wielaard  
+
+   * dwfl_segment_report_module.c (dwfl_segment_report_module): Check
+   notes filesz. Rewrite reading of GElf_Nhdr.
+
 2021-12-08  Mark Wielaard  
 
* dwfl_segment_report_module.c (dwfl_segment_report_module): Make sure
diff --git a/libdwfl/dwfl_segment_report_module.c 
b/libdwfl/dwfl_segment_report_module.c
index 78c70795..a6d6be85 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -520,6 +520,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char 
*name,
   if (data_size != 0)
 filesz = data_size;
 
+ if (filesz > SIZE_MAX / sizeof (Elf32_Nhdr))
+   continue;
+
   assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
 
   void *notes;
@@ -532,6 +535,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char 
*name,
 {
   const unsigned int xencoding = ehdr.e32.e_ident[EI_DATA];
 
+ if (filesz > SIZE_MAX / sizeof (Elf32_Nhdr))
+   continue;
   notes = malloc (filesz);
   if (unlikely (notes == NULL))
 continue; /* Next header */
@@ -552,44 +557,48 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const 
char *name,
 
   const GElf_Nhdr *nh = notes;
   size_t len = 0;
-  size_t last_len;
-  while (filesz > len + sizeof (*nh))
+  while (filesz - len > sizeof (*nh))
 {
-  const void *note_name;
-  const void *note_desc;
-  last_len = len;
-
-  len += sizeof (*nh);
-  note_name = notes + len;
-
-  len += nh->n_namesz;
-  len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len);
-  note_desc = notes + len;
-
-  if (unlikely (filesz < len + nh->n_descsz
-|| len <= last_len
-|| len + nh->n_descsz < last_len))
-break;
-
-  if (nh->n_type == NT_GNU_BUILD_ID
-  && nh->n_descsz > 0
-  && nh->n_namesz == sizeof "GNU"
-  && !memcmp (note_name, "GNU", sizeof "GNU"))
-{
-  build_id.vaddr = (note_desc
+ len += sizeof (*nh);
+
+ size_t namesz = nh->n_namesz;
+ namesz = align == 8 ? NOTE_ALIGN8 (namesz) : NOTE_ALIGN4 
(namesz);
+ if (namesz > filesz - len || len + namesz < namesz)
+   break;
+
+ void *note_name = notes + len;
+ len += namesz;
+
+ size_t descsz = nh->n_descsz;
+ descsz = align == 8 ? NOTE_ALIGN8 (descsz) : NOTE_ALIGN4 
(descsz);
+ if (descsz > filesz - len || len + descsz < descsz)
+   break;
+
+ void *note_desc = notes + len;
+ len += descsz;
+
+ /* We don't handle very short or really large build-ids.  We 
need at
+at least 3 and allow for up to 64 (normally ids are 20 
long).  */
+#define MIN_BUILD_ID_BYTES 3
+#define MAX_BUILD_ID_BYTES 64
+ if (nh->n_type == NT_GNU_BUILD_ID
+ && nh->n_descsz >= MIN_BUILD_ID_BYTES
+ && nh->n_descsz <= MAX_BUILD_ID_BYTES
+ && nh->n_namesz == sizeof "GNU"
+ && !memcmp (note_name, "GNU", sizeof "GNU"))
+   {
+ build_id.vaddr = (note_desc
- (const void *) notes
+ note_vaddr);
-  build_id.len = nh->n_descsz;
-  build_id.memory = malloc (build_id.len);
-  if (likely (build_id.memory != NULL))
-memcpy (build_id.memory, note_desc, build_id.len);
-  break;
-}
-
-  len += nh->n_descsz;
-  len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len);
-  nh = (void *) notes + len;
-}
+ build_id.len = nh->n_descsz;
+ build_id.memory = malloc (build_id.len);
+ if (likely (build_id.memory !

[Bug libdw/28715] New: There seems to be an infinite loop in dwfl_segment_report_module

2021-12-19 Thread evvers at ya dot ru via Elfutils-devel
https://sourceware.org/bugzilla/show_bug.cgi?id=28715

Bug ID: 28715
   Summary: There seems to be an infinite loop in
dwfl_segment_report_module
   Product: elfutils
   Version: unspecified
Status: UNCONFIRMED
  Severity: normal
  Priority: P2
 Component: libdw
  Assignee: unassigned at sourceware dot org
  Reporter: evvers at ya dot ru
CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 13863
  --> https://sourceware.org/bugzilla/attachment.cgi?id=13863&action=edit
File causing an infinite loop

It was reported today in
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=42645 . It can be
reproduced with `./src/stack`:
```
autoreconf -i -f
./configure --enable-maintainer-mode
make -j$(nproc) V=1
LD_LIBRARY_PATH="./libdw;./libelf" ./src/stack --core ../oss-fuzz-42645
```
According to eu-stack it's in dwfl_segment_report_module
```
PID 212089 - process
TID 212089:
#0  0x7f6af3447cd5 dwfl_segment_report_module
#1  0x7f6af344bf88 dwfl_core_file_report@@ELFUTILS_0.158
#2  0x00402ec7 parse_opt
#3  0x7f6af30da472 argp_parse
#4  0x004024eb main
#5  0x7f6af2fe9560 __libc_start_call_main
#6  0x7f6af2fe960c __libc_start_main@@GLIBC_2.34
#7  0x00402725 _start
```
Below is the backtrace OSS-Fuzz attached to the issue (with line numbers):
```
ALARM: working on the last Unit for 61 seconds
   and the timeout value is 60 (use -timeout=N to change)
==822== ERROR: libFuzzer: timeout after 61 seconds
#0 0x4b22d4 in __sanitizer_print_stack_trace
/src/llvm-project/compiler-rt/lib/ubsan/ubsan_diag_standalone.cpp:31:3
#1 0x457438 in fuzzer::PrintStackTrace() cxa_noexception.cpp:0
#2 0x43c329 in fuzzer::Fuzzer::AlarmCallback() cxa_noexception.cpp:0
#3 0x7f1be648c3bf in libpthread.so.0
#4 0x4aea5b in atomic_exchange<__sanitizer::atomic_uint32_t>
/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h:67:7
#5 0x4aea5b in acquire
/src/llvm-project/compiler-rt/lib/ubsan/ubsan_value.h:60:21
#6 0x4aea5b in handleNegateOverflowImpl(__ubsan::OverflowData*, unsigned
long, __ubsan::ReportOptions)
/src/llvm-project/compiler-rt/lib/ubsan/ubsan_handlers.cpp:251:34
#7 0x4aea2d in __ubsan_handle_negate_overflow
/src/llvm-project/compiler-rt/lib/ubsan/ubsan_handlers.cpp:277:3
#8 0x517854 in dwfl_segment_report_module
/src/elfutils/libdwfl/dwfl_segment_report_module.c:581:58
#9 0x4b8937 in dwfl_core_file_report
/src/elfutils/libdwfl/core-file.c:559:17
#10 0x4b388e in LLVMFuzzerTestOneInput /src/fuzz-dwfl-core.c:52:6
#11 0x43d953 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*,
unsigned long) cxa_noexception.cpp:0
#12 0x429592 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned
long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
#13 0x42edec in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char
const*, unsigned long)) cxa_noexception.cpp:0
#14 0x457bf2 in main
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#15 0x7f1be62800b2 in __libc_start_main
/build/glibc-eX1tMB/glibc-2.31/csu/libc-start.c:308:16
#16 0x407d4d in _start
```

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug debuginfod/28708] run-debuginfod-webapi-concurrency.sh seems to be flaky

2021-12-19 Thread evvers at ya dot ru via Elfutils-devel
https://sourceware.org/bugzilla/show_bug.cgi?id=28708

--- Comment #7 from Evgeny Vereshchagin  ---
> Note that packit doesn't use real hardware for various architectures but
> "container emulation" which causes various testcases to fail.
> 

I think I ran into issues like that in
https://github.com/evverx/elfutils/issues/32 and
https://github.com/evverx/elfutils/issues/31. I ignore them for the most part.
Though it would be great if they could be skipped there. Some of them seem to
be easy to skip because they seem to trigger seccomp filters of some kind but
I'm not sure about the rest.

> Although in this case it seems it is overloading the host. Maybe we can tune
> down the number of concurrent request tested, see also:
> https://sourceware.org/pipermail/elfutils-devel/2021q4/thread.html#4488
> If you have a better lower/upper bound or a way to test the limits of the
> machine.
> 

Thanks for the link. I'll take a look.

> We do have somewhat better buildbot workers for various architectures here:
> https://builder.wildebeest.org/buildbot/#/builders?tags=elfutils


As far as I understand the tests are run there on commits to the elfutils
repository but I'm not sure how to test "PRs" there. If it was possible to use
it before commits are merged into the master branch I wouldn't have started
using Packit on GitHub probably.

> Is there some way of finding out the host's actual limits?  Can we detect that
> we're running in an unusually constricted environment and skip this test
> ulimit -u?

I think I can run almost anything there but since I'm not familiar with the
test I'm not sure what I should look for.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug debuginfod/28708] run-debuginfod-webapi-concurrency.sh seems to be flaky

2021-12-19 Thread fche at redhat dot com via Elfutils-devel
https://sourceware.org/bugzilla/show_bug.cgi?id=28708

--- Comment #8 from Frank Ch. Eigler  ---
This test creates up to 100+few threads in debuginfod, and also 100 concurrent
curl processes to talk to debuginfod.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[PATCH] libdwfl: Handle unaligned Ehdr in dwfl_segment_report_module

2021-12-19 Thread Mark Wielaard
The xlate functions only handle correctly aligned buffers. But they do
handle src == dest. So if the source buffer isn't aligned correctly
just copy it first into the destination (which is already correctly
aligned).

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog|  5 +
 libdwfl/dwfl_segment_report_module.c | 14 ++
 2 files changed, 19 insertions(+)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 18ffc347..6c7e0c4a 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-19  Mark Wielaard  
+
+   * dwfl_segment_report_module.c (dwfl_segment_report_module): Copy
+   buffer and set xlatefrom.d_buf to ehdr when buffer is not aligned.
+
 2021-12-19  Mark Wielaard  
 
* dwfl_segment_report_module.c (dwfl_segment_report_module): Check
diff --git a/libdwfl/dwfl_segment_report_module.c 
b/libdwfl/dwfl_segment_report_module.c
index a6d6be85..7f756392 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -367,6 +367,20 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const 
char *name,
   e_ident = ((const unsigned char *) buffer);
   ei_class = e_ident[EI_CLASS];
   ei_data = e_ident[EI_DATA];
+  /* buffer may be unaligned, in which case xlatetom would not work.
+ xlatetom does work when the in and out d_buf are equal (but not
+ for any other overlap).  */
+  size_t ehdr_align = (ei_class == ELFCLASS32
+  ? __alignof__ (Elf32_Ehdr)
+  : __alignof__ (Elf64_Ehdr));
+  if (((uintptr_t) buffer & (ehdr_align - 1)) != 0)
+{
+  memcpy (&ehdr, buffer,
+ (ei_class == ELFCLASS32
+  ? sizeof (Elf32_Ehdr)
+  : sizeof (Elf64_Ehdr)));
+  xlatefrom.d_buf = &ehdr;
+}
   switch (ei_class)
 {
 case ELFCLASS32:
-- 
2.30.2



[PATCH] libdwfl: Handle unaligned Phdr in dwfl_segment_report_module

2021-12-19 Thread Mark Wielaard
The xlate functions only handle correctly aligned buffers. But they do
handle src == dest. So if the source buffer isn't aligned correctly
just copy it first into the destination (which is already correctly
aligned).

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog|  6 ++
 libdwfl/dwfl_segment_report_module.c | 12 
 2 files changed, 18 insertions(+)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 6c7e0c4a..ac0fbe0f 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2021-12-19  Mark Wielaard  
+
+   * dwfl_segment_report_module.c (dwfl_segment_report_module): Copy
+   ph_buffer and set xlatefrom.d_buf to phdrsp when ph_buffer is not
+   aligned.
+
 2021-12-19  Mark Wielaard  
 
* dwfl_segment_report_module.c (dwfl_segment_report_module): Copy
diff --git a/libdwfl/dwfl_segment_report_module.c 
b/libdwfl/dwfl_segment_report_module.c
index 7f756392..de190e90 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -461,6 +461,18 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const 
char *name,
   xlateto.d_buf = phdrsp;
   xlateto.d_size = phdrsp_bytes;
 
+  /* ph_ buffer may be unaligned, in which case xlatetom would not work.
+ xlatetom does work when the in and out d_buf are equal (but not
+ for any other overlap).  */
+  size_t phdr_align = (class32
+  ? __alignof__ (Elf32_Phdr)
+  : __alignof__ (Elf64_Phdr));
+  if (((uintptr_t) ph_buffer & (phdr_align - 1)) != 0)
+{
+  memcpy (phdrsp, ph_buffer, phdrsp_bytes);
+  xlatefrom.d_buf = phdrsp;
+}
+
   /* Track the bounds of the file visible in memory.  */
   GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end.  */
   GElf_Off file_end = 0;/* Rounded up to effective page size.  */
-- 
2.30.2



[Bug libelf/28685] UBSan: member access within misaligned address 0x7ff316818032 for type 'struct Elf32_Phdr'

2021-12-19 Thread mark at klomp dot org via Elfutils-devel
https://sourceware.org/bugzilla/show_bug.cgi?id=28685

--- Comment #3 from Mark Wielaard  ---
(In reply to Evgeny Vereshchagin from comment #2)
> If callers are
> expected to pass correctly aligned buffers it seems
> dwfl_segment_report_module should be fixed. But it seems that callers can
> sometimes assume that it should be fine to pass unaligned data. For example,
> (even though it has nothing to do with the xlateto functions) in one of
> libbpf issues it was pointed out that "I don't see anywhere the requirement
> that bytes passed to the elf_memory() should be aligned, so this does seem
> like libelf bug."

I am not sure I like people explicitly passing in unaligned buffers to
elf_memory (). We'll need to carefully audit that works. It also means lots of
copying data structures around to get a correctly aligned version. Also the
xlate functions work on Elf_Data, I think it is reasonable to assume those
normally come from other libelf functions and that the d_buf pointers are
correctly aligned for the d_type.

For now I just fixed up the code in dwfl_segment_report_module to make sure the
buffers passed to the xlate functions are properly aligned. See the following
proposed patches:

https://sourceware.org/pipermail/elfutils-devel/2021q4/004552.html
https://sourceware.org/pipermail/elfutils-devel/2021q4/004561.html
https://sourceware.org/pipermail/elfutils-devel/2021q4/004562.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug libdw/28710] ERROR: AddressSanitizer: SEGV on unknown address (on i386)

2021-12-19 Thread mark at klomp dot org via Elfutils-devel
https://sourceware.org/bugzilla/show_bug.cgi?id=28710

Mark Wielaard  changed:

   What|Removed |Added

 CC||mark at klomp dot org

--- Comment #1 from Mark Wielaard  ---
I cannot replicate this with my latest proposed patches.
I suspect this proposed patch fixed it:

https://sourceware.org/pipermail/elfutils-devel/2021q4/004557.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[PATCH] libdwfl: Handle unaligned Phdr in dwfl_segment_report_module

2021-12-19 Thread Mark Wielaard
The xlate functions only handle correctly aligned buffers. But they do
handle src == dest. So if the source buffer isn't aligned correctly
just copy it first into the destination (which is already correctly
aligned).

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog|  5 +
 libdwfl/dwfl_segment_report_module.c | 12 
 2 files changed, 17 insertions(+)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index ac0fbe0f..6015f6b7 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-19  Mark Wielaard  
+
+   * dwfl_segment_report_module.c (dwfl_segment_report_module): Copy
+   data and set xlatefrom.d_buf to notes when data is not aligned.
+
 2021-12-19  Mark Wielaard  
 
* dwfl_segment_report_module.c (dwfl_segment_report_module): Copy
diff --git a/libdwfl/dwfl_segment_report_module.c 
b/libdwfl/dwfl_segment_report_module.c
index de190e90..72c85070 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -573,6 +573,18 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const 
char *name,
   xlatefrom.d_size = filesz;
   xlateto.d_buf = notes;
   xlateto.d_size = filesz;
+
+ /* data may be unaligned, in which case xlatetom would not 
work.
+xlatetom does work when the in and out d_buf are equal 
(but not
+for any other overlap).  */
+ if ((uintptr_t) data != (align == 8
+  ? NOTE_ALIGN8 ((uintptr_t) data)
+  : NOTE_ALIGN4 ((uintptr_t) data)))
+   {
+ memcpy (notes, data, filesz);
+ xlatefrom.d_buf = notes;
+   }
+
   if (elf32_xlatetom (&xlateto, &xlatefrom, xencoding) == NULL)
 {
   free (notes);
-- 
2.30.2



[Bug libdw/28715] There seems to be an infinite loop in dwfl_segment_report_module

2021-12-19 Thread mark at klomp dot org via Elfutils-devel
https://sourceware.org/bugzilla/show_bug.cgi?id=28715

Mark Wielaard  changed:

   What|Removed |Added

   Assignee|unassigned at sourceware dot org   |mark at klomp dot org
 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2021-12-20
 Ever confirmed|0   |1
 CC||mark at klomp dot org

--- Comment #1 from Mark Wielaard  ---
I couldn't replicate the infinite loop, which I assume has been fixed by:
https://sourceware.org/pipermail/elfutils-devel/2021q4/004557.html

But I saw it did trigger yet another xlate alignment issue for which I did
submit:
https://sourceware.org/pipermail/elfutils-devel/2021q4/004565.html

P.S. Note that the bugs.chromium.org link doesn't work for me, it apparently
requires a google account with permissions to even just look at that bug.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug libdw/28715] There seems to be an infinite loop in dwfl_segment_report_module

2021-12-19 Thread evvers at ya dot ru via Elfutils-devel
https://sourceware.org/bugzilla/show_bug.cgi?id=28715

--- Comment #2 from Evgeny Vereshchagin  ---
(In reply to Mark Wielaard from comment #1)
> I couldn't replicate the infinite loop, which I assume has been fixed by:
> https://sourceware.org/pipermail/elfutils-devel/2021q4/004557.html
> 
> But I saw it did trigger yet another xlate alignment issue for which I did
> submit:
> https://sourceware.org/pipermail/elfutils-devel/2021q4/004565.html

Thanks! I'll try to take a look tomorrow.

There seem to be quite a few new patches on the mailing list. I wonder if it's
possible to somehow fetch a branch with all of them so that I could just rebase
the fuzzing infrastructure on top of it?

> P.S. Note that the bugs.chromium.org link doesn't work for me, it apparently
> requires a google account with permissions to even just look at that bug.

It's possible to make all the bug reports public by default. For example, in
https://github.com/google/oss-fuzz/pull/6741 the PHP project decided that bug
reports should be no longer restricted and flipped the flag. I can do the same
but I don't think I can do it without your approval.

-- 
You are receiving this mail because:
You are on the CC list for the bug.