Re: Issue 60887 in oss-fuzz: elfutils:fuzz-libelf: Direct-leak in __libelf_decompress_zlib
Hi, On Sat, Jul 29, 2023 at 03:00:49PM -0700, evv… via monorail via Elfutils-devel wrote: > > Comment #1 on issue 60887 by evv...@gmail.com: elfutils:fuzz-libelf: > Direct-leak in __libelf_decompress_zlib > https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60887#c1 > > The full backtrace is > ``` > ==178009==ERROR: LeakSanitizer: detected memory leaks > Direct leak of 1 byte(s) in 1 object(s) allocated from: > #0 0x52efd6 in __interceptor_malloc > /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3 > #1 0x57a228 in __libelf_decompress_zlib > /src/elfutils/libelf/elf_compress.c:370:19 > #2 0x57a987 in __libelf_decompress > /src/elfutils/libelf/elf_compress.c:440:12 > #3 0x57a987 in __libelf_decompress_elf > /src/elfutils/libelf/elf_compress.c:500:7 > #4 0x57629f in get_zdata /src/elfutils/libelf/elf_strptr.c:45:17 > #5 0x575c5e in elf_strptr /src/elfutils/libelf/elf_strptr.c:135:38 > #6 0x56c5b3 in fuzz_logic_one /src/fuzz-libelf.c:40:26 > #7 0x56cc7f in LLVMFuzzerTestOneInput /src/fuzz-libelf.c:88:3 > ``` > > I haven't figured out how to trigger that memory leak without the fuzz target > but as far as I can tell `fuzz_logic_one` was inspired by the elfgetzdata > test in > the sense that it calls elf_nextscn/elf_strptr/elf_compress. > > The code triggering the memory leak is > https://github.com/google/oss-fuzz/blob/24328c88fd610decaf311020ffc7073aec1db252/projects/elfutils/fuzz-libelf.c#L27C6-L27C20 Thanks, I can replicate it with that and valgrind. The issue is when elf_strptr has (partially) uncompressed the section data (to read the uncompressed string), the program never requests the (uncompressed) section data, but does (re)compress it. Working on a fix. Cheers, Mark
[PATCH] libelf: Free and clear rawdata_base and zdata_base consistently
There could be a leak if a program called elf_strptr on a compressed section, but the program never requests the (uncompressed) section data, but does explicitly (re)compress that same section data. Fix this by explicitly always freeing and clearing the zdata_base and rawdata_base in __libelf_reset_rawdata and elf_compress. Also clear zdata_base in elf_end so the pointer isn't indeterminate when it is being used in a later comparison against rawdata_base. * libelf/elf_compress.c (elf_compress): Explicitly free zdata_base before clearing. (__libelf_reset_rawdata): Free zdata_base if it isn't (going to be) used for rawdata_base. Explicitly clear rawdata_base and zdata_base after free. * libelf/elf_end.c (elf_end): Clear zdata_base after free. Signed-off-by: Mark Wielaard --- libelf/elf_compress.c | 14 +- libelf/elf_end.c | 5 - 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c index f13b41ba..c7283c6a 100644 --- a/libelf/elf_compress.c +++ b/libelf/elf_compress.c @@ -1,5 +1,6 @@ /* Compress or decompress a section. Copyright (C) 2015, 2016 Red Hat, Inc. + Copyright (C) 2023, Mark J. Wielaard This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -523,10 +524,20 @@ __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align, if (scn->data_base != scn->rawdata_base) free (scn->data_base); scn->data_base = NULL; + if (scn->zdata_base != buf + && scn->zdata_base != scn->rawdata_base) +{ + free (scn->zdata_base); + scn->zdata_base = NULL; +} if (scn->elf->map_address == NULL || scn->rawdata_base == scn->zdata_base || (scn->flags & ELF_F_MALLOCED) != 0) -free (scn->rawdata_base); +{ + free (scn->rawdata_base); + scn->rawdata_base = NULL; + scn->zdata_base = NULL; +} scn->rawdata_base = buf; scn->flags |= ELF_F_MALLOCED; @@ -677,6 +688,7 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags) data around, but since that might have been multiple Elf_Data buffers let the user uncompress it explicitly again if they want it to simplify bookkeeping. */ + free (scn->zdata_base); scn->zdata_base = NULL; return 1; diff --git a/libelf/elf_end.c b/libelf/elf_end.c index 3e5d4c86..89727cb3 100644 --- a/libelf/elf_end.c +++ b/libelf/elf_end.c @@ -157,7 +157,10 @@ elf_end (Elf *elf) rawdata_base. If it is already used it will be freed below. */ if (scn->zdata_base != scn->rawdata_base) - free (scn->zdata_base); + { + free (scn->zdata_base); + scn->zdata_base = NULL; + } /* If the file has the same byte order and the architecture doesn't require overly stringent -- 2.39.3
Fwd: Anton Baltser, bug with libdebuginfod
-- Forwarded message - From: anton baltser Date: Sun, 30 Jul 2023 at 17:02 Subject: Anton Baltser, bug with libdebuginfod To: Hello, nice to meet you! I need to install I tried to install elfutils - 0.189 version , and I could solve installing libdebuginfod. My system ubuntu 20.04/wsl2 I used ./configure --prefix=/usr\ --disable-debuginfod \ --enable-libdebuginfod=dummy \ --libdir=/lib And it didn't help me. result ./configure : = elfutils: 0.189 (eu_version: 189) = Prefix : /usr Program prefix ("eu-" recommended) : eu- Source code location : . Maintainer mode: build arch : x86_64-pc-linux-gnu CFLAGS=-D_FORTIFY_SOURCE=2 -g -O2 CXXFLAGS=-D_FORTIFY_SOURCE=2 -g -O2 RECOMMENDED FEATURES (should all be yes) gzip support : yes bzip2 support : yes lzma/xz support: no zstd support : yes zstd compression support : no libstdc++ demangle support : yes File textrel check : yes Symbol versioning : yes NOT RECOMMENDED FEATURES (should all be no) Experimental thread safety : no install elf.h : no OTHER FEATURES Deterministic archives by default : false Native language support: yes Extra Valgrind annotations : no libdebuginfod client support : dummy Debuginfod server support : no Default DEBUGINFOD_URLS: EXTRA TEST FEATURES (used with make check) have bunzip2 installed (required) : yes have zstd installed: yes C++11 : yes debug branch prediction: no gprof support : no gcov support : no run all tests under valgrind : no gcc undefined behaviour sanitizer : no gcc address sanitizer : no clang memory sanitizer : no use rpath in tests : no test biarch: no make result: Making all in po make[2]: Nothing to be done for 'all'. Making all in doc make[2]: Nothing to be done for 'all'. Making all in tests make[2]: Nothing to be done for 'all'. I added logs in the txt file. Could you help me please to fix it? ./configure --prefix=/usr\ > --disable-debuginfod \ > --enable-libdebuginfod=dummy \ > --libdir=/lib configure: No --program-prefix given, using "eu-" checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a race-free mkdir -p... /usr/bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking whether to enable maintainer-specific portions of Makefiles... no checking whether make supports nested variables... (cached) yes checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether the compiler supports GNU C... yes checking whether gcc accepts -g... yes checking for gcc option to enable C11 features... none needed checking whether gcc understands -c and -o together... yes checking whether make supports the include directive... yes (GNU style) checking dependency style of gcc... gcc3 checking for g++... g++ checking whether the compiler supports GNU C++... yes checking whether g++ accepts -g... yes checking for g++ option to enable C++11 features... none needed checking dependency style of g++... gcc3 checking for ranlib... ranlib checking for bison... no checking for byacc... no checking for flex... no checking for lex... no checking for ar... ar checking the archiver (ar) interface... ar checking for readelf... readelf checking for nm... nm checking whether gcc supports __attribute__((visibility()))... yes checking whether gcc supports __attribute__((gcc_struct))... yes checking whether gcc supports -fPIC... yes checking whether gcc supports -fPIE... yes checking whether gcc supports -Wl,-z,defs... yes checking whether the compiler generates build-ids... yes checking whether gcc supports -Wl,-z,relro... yes checking for __thread support... yes checking whether gcc provides stdatomic.h... yes checking for special C compiler options needed for large files... no checki
Re: Fwd: Anton Baltser, bug with libdebuginfod
Hi - > I need to install > I tried to install elfutils - 0.189 version , and I could solve installing > libdebuginfod. > My system ubuntu 20.04/wsl2 > > I used ./configure --prefix=/usr\ > --disable-debuginfod \ > --enable-libdebuginfod=dummy \ > --libdir=/lib debuginfod/Makefile.am says: if LIBDEBUGINFOD pkginclude_HEADERS = debuginfod.h endif which is active with =dummy. Just tried this same configure here, and after a "make install", the header file does get installed. - FChE
Re: Fwd: Anton Baltser, bug with libdebuginfod
Thanks for the quick response. I did: $ ./configure --prefix=/usr\ > --disable-debuginfod \ > --enable-libdebuginfod=dummy \ > --libdir=/libm $ make install : Making install in tests make[2]: Nothing to be done for 'install-exec-am'. make[2]: Nothing to be done for 'install-data-am'. make[2]: Nothing to be done for 'install-exec-am'. /usr/bin/mkdir -p '/usr/include/elfutils' /usr/bin/install -c -m 644 version.h '/usr/include/elfutils' $ make check : Testsuite summary for elfutils 0.189 # TOTAL: 236 # PASS: 232 # SKIP: 4 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 make[1]: Nothing to be done for 'check-am'. Is that right result? On Sun, Jul 30, 2023, 21:26 Frank Ch. Eigler wrote: > Hi - > > > I need to install > > I tried to install elfutils - 0.189 version , and I could solve > installing > > libdebuginfod. > > My system ubuntu 20.04/wsl2 > > > > I used ./configure --prefix=/usr\ > > --disable-debuginfod \ > > --enable-libdebuginfod=dummy \ > > --libdir=/lib > > debuginfod/Makefile.am says: > > if LIBDEBUGINFOD > pkginclude_HEADERS = debuginfod.h > endif > > which is active with =dummy. Just tried this same configure here, and > after a "make install", the header file does get installed. > > - FChE > >