tats / w3m

Debian's w3m: WWW browsable pager
https://tracker.debian.org/pkg/w3m
Other
872 stars 93 forks source link

oss-fuzz-gen: wild-addr-read #303

Open ghost opened 3 months ago

ghost commented 3 months ago

Fuzz driver generated by oss-fuzz-gen

#include "wc.h"
#include "wtf.h"
#include <gc.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

static void *die_oom(size_t bytes) {
  fprintf(stderr, "Out of memory: %lu bytes unavailable!\n", (unsigned long)bytes);
  exit(1);
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  static int init_done = 0;

  if (!init_done) {
    setenv("GC_LARGE_ALLOC_WARN_INTERVAL", "30000", 1);
    GC_INIT();
#if (GC_VERSION_MAJOR > 7) || ((GC_VERSION_MAJOR == 7) && (GC_VERSION_MINOR >= 2))
    GC_set_oom_fn(die_oom);
#else
    GC_oom_fn = die_oom;
#endif
#ifdef USE_M17N
#ifdef USE_UNICODE
    wtf_init(WC_CES_UTF_8, WC_CES_UTF_8);
#else
    wtf_init(WC_CES_EUC_JP, WC_CES_EUC_JP);
#endif
#endif
    init_done = 1;
  }

  if (size == 0)
    return 0;

  Str s = Strnew_size(size + 1); // Allocate space for null terminator
  memcpy(s->ptr, data, size);
  s->ptr[size] = '\0'; // Null-terminate the string
  s->length = size;

  wc_ces ces = WC_CES_UTF_8;
  Str result = wc_conv_from_utf7(s, ces);

  if (result && result->ptr) {
    Strfree(result);
  }
  Strfree(s);

  return 0;
}

Wild-addr-read

Sanitizer output

==17==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x55faa67dada3 bp 0x7ffc6d4081d0 sp 0x7ffc6d4081b0 T0)
==17==The signal is caused by a READ memory access.
==17==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
SCARINESS: 20 (wild-addr-read)
    #0 0x55faa67dada3 in LLVMFuzzerTestOneInput /src/w3m/libwc/../fuzz/fuzz-conv.c:45:25
    #1 0x55faa668d620 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #2 0x55faa668ce45 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:516:7
    #3 0x55faa668ec96 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, std::__Fuzzer::allocator<fuzzer::SizedFile>>&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:812:5
    #4 0x55faa668f107 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, std::__Fuzzer::allocator<fuzzer::SizedFile>>&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:867:3
    #5 0x55faa667d716 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:914:6
    #6 0x55faa66a9c42 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #7 0x7fe513da8082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
    #8 0x55faa666e88d in _start (out/libfuzzer-address-x86_64/fuzz_conv+0x6088d)

DEDUP_TOKEN: LLVMFuzzerTestOneInput--fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long)--fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /src/w3m/libwc/../fuzz/fuzz-conv.c:45:25 in LLVMFuzzerTestOneInput

Artifacts

crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc

Target binary

fuzz_conv

Preliminary analysis

(gdb) print (void *)result
$2 = (void *) 0x7ffff7e6c620 <result>
(gdb) x/4xw 0x7ffff7e6c620
0x7ffff7e6c620 <result>:        0x00000000      0x00000000      0x00000000      0x00000000

The address 0x7ffff7e6c620 is not NULL. The address of result is valid, but it may not point to valid data as expected. The memory contents of result are all zeros, which means that result points to an invalid memory area or an uninitialized pointer.

rkta commented 3 months ago

On Fri, Jul 26, 2024 at 11:39:18PM -0700, fdt622 wrote:

Fuzz driver generated by oss-fuzz-gen

[...]
  Str result = wc_conv_from_utf7(s, ces);

  if (result && result->ptr) {
    Strfree(result);
  }
  Strfree(s);

  return 0;
}

Wild-addr-read

Sanitizer output


==17==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x55faa67dada3 bp 0x7ffc6d4081d0 sp 0x7ffc6d4081b0 T0)
==17==The signal is caused by a READ memory access.
==17==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
SCARINESS: 20 (wild-addr-read)
    #0 0x55faa67dada3 in LLVMFuzzerTestOneInput /src/w3m/libwc/../fuzz/fuzz-conv.c:45:25

What is your line 25?

Preliminary analysis

(gdb) print (void *)result
$2 = (void *) 0x7ffff7e6c620 <result>
(gdb) x/4xw 0x7ffff7e6c620
0x7ffff7e6c620 <result>:        0x00000000      0x00000000      0x00000000      0x00000000

The address 0x7ffff7e6c620 is not NULL. The address of result is valid, but it may not point to valid data as expected. The memory contents of result are all zeros, which means that result points to an invalid memory area or an uninitialized pointer.

result is a struct _Str. It's totally valid to have a struct whose memory is all zeros. What outcome did you expect?

Also, what is your input? And can you please provide an minimal working example with such an report? Without being able to reproduce this issue we will not be able to fix it.

ghost commented 3 months ago

Hi, thank you for viewing this issue. Line 45: if (result && result->ptr) { Input: crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc To reproduce this crash, you can simply run

fuzz_conv crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
rkta commented 3 months ago

On Sat, Jul 27, 2024 at 04:47:47AM -0700, fdt622 wrote:

Hi, thank you for viewing this issue. Line 45: if (result && result->ptr) { Input: crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc To reproduce this crash, you can simply run

fuzz_conv crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc

When I say reproducible example, I mean something I can compile, change and debug - not some pre-compiled binary.

Does your code work with other input?