Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demangle API: SEGV on unknown address #816

Closed
autofuzzoss opened this issue Apr 11, 2022 · 0 comments · Fixed by #955
Closed

Demangle API: SEGV on unknown address #816

autofuzzoss opened this issue Apr 11, 2022 · 0 comments · Fixed by #955
Labels
Milestone

Comments

@autofuzzoss
Copy link

autofuzzoss commented Apr 11, 2022

Bug Report

Found SEGV on Demangle() API Function, that may cause security vulnerabilities such as 'Invalid Memory Access'.

PoC Code

#include "demangle.h"
 
using namespace GOOGLE_NAMESPACE;
 
const char *Poc = "_Z5\3435Dfuzzvaemanzz4f[ZZ6vaema6666666666666666666666666nzz3\264f[ZZ8nz\347z2f[ZZ8vaemanz:3f[ZZ8\"Dfufuzz3nzzvf[ZZ8nz\347z2f[DfufuzzvaemDemafuzzvaem4\"\n";
 
int main() {
  char demangled[4096];
  Demangle(Poc, demangled, sizeof(demangled));
  return 0;
}

Address Sanitizer Report

!!!! AVASFUZZ_TEST: Add Pre Function:fuzz_test_AVASFUZZ_TestAutoFuzz_Demangle_Test-0x500560, Pre-Func size:1, TCs size:1 !!!!
!!!! AVASFUZZ_TEST: Add Fuzz Test Case Function:fuzz_test_AVASFUZZ_TestAutoFuzz_Demangle_Test-0x500740, TCs size:1 !!!!
!!!! AVASFUZZ_TEST: Add Post Function:fuzz_test_AVASFUZZ_TestAutoFuzz_Demangle_Test-0x500c90, Post-Func size:1, TCs size:1 !!!!
INFO: Seed: 1725690318
INFO: Loaded 1 modules   (1482 inline 8-bit counters): 1482 [0x93d988, 0x93df52),
INFO: Loaded 1 PC tables (1482 PCs): 1482 [0x93df58,0x943bf8),
INFO:        1 files found in crash
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: seed corpus: files: 1 min: 167b max: 167b total: 167b rss: 29Mb
!!!! RUN_ALL_AVASFUZZ_TESTS : Fuzz TC size: 1. It should be same with added count !!!!
!!!! AVASFUZZ_TEST: START 1 PRE-ACTIONS, fuzz_test_AVASFUZZ_TestAutoFuzz_Demangle_Test
!!!! AVASFUZZ_TEST: SRART TC, fuzz_test_AVASFUZZ_TestAutoFuzz_Demangle_Test
AddressSanitizer:DEADLYSIGNAL
=================================================================
==28497==ERROR: AddressSanitizer: SEGV on unknown address 0x60cfc0aab1a0 (pc 0x00000050479c bp 0x7ffec9ac7040 sp 0x7ffec9ac7000 T0)
==28497==The signal is caused by a READ memory access.
    #0 0x50479c in google::ParseOneCharToken(google::State*, char) /root/fuzz-test-generation/exp/glog/src/demangle.cc:211:7
    #1 0x50bc19 in google::ParseAbiTag(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:723:10
    #2 0x506519 in google::OneOrMore(bool (*)(google::State*), google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:251:7
    #3 0x50b7de in google::ParseAbiTags(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:713:7
    #4 0x50b0a4 in google::ParseUnqualifiedName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:605:47
    #5 0x50457f in google::ParseUnscopedName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:530:7
    #6 0x5040d4 in google::ParseUnscopedTemplateName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:547:10
    #7 0x502b65 in google::ParseName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:514:7
    #8 0x508ac4 in google::ParseClassEnumType(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1044:10
    #9 0x50700e in google::ParseType(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:965:7
    #10 0x50654d in google::OneOrMore(bool (*)(google::State*), google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:252:12
    #11 0x502e1e in google::ParseBareFunctionType(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1033:7
    #12 0x502870 in google::ParseEncoding(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:493:27
    #13 0x501f53 in google::ParseMangledName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:485:44
    #14 0x501ca4 in google::ParseTopLevelMangledName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1306:7
    #15 0x501873 in google::Demangle(char const*, char*, unsigned long) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1360:10
    #16 0x500260 in DemangleIt(char const*) /root/fuzz-test-generation/exp/glog/src/autofuzz_unittest.cc:22:7
    #17 0x4fff31 in TestAutoFuzz_Demangle_Test::TestBody() /root/fuzz-test-generation/exp/glog/src/autofuzz_unittest.cc:30:3
    #18 0x5009f9 in AVASGtestTest::runTest() /root/fuzz-test-generation/exp/glog/src/autofuzz_unittest.cc:44:7
    #19 0x50078b in fuzz_test_AVASFUZZ_TestAutoFuzz_Demangle_Test() /root/fuzz-test-generation/exp/glog/src/autofuzz_unittest.cc:64:13
    #20 0x55a48e in RUN_ALL_AVASFUZZ_TESTS() /root/fuzz-test-generation/exp/glog/src/avasfuzz_common/0avasfuzz.cpp:125:5
    #21 0x555858 in TestOneProtoInput(mutation::APIArgument const&) /root/fuzz-test-generation/exp/glog/src/fuzz_entry.cc:20:3
    #22 0x5556da in LLVMFuzzerTestOneInput /root/fuzz-test-generation/exp/glog/src/fuzz_entry.cc:17:1
    #23 0x43cb22 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /home/bjeong/2020_aiva/llvm/llvm-project/compiler-rt/lib/fuzzer/./Fu                                                                                                                                                                zzerLoop.cpp:556:15
    #24 0x43c19b in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /home/bjeong/2020_aiva/llvm/llvm-project/com                                                                                                                                                                piler-rt/lib/fuzzer/./FuzzerLoop.cpp:470:3
    #25 0x43dc43 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/bjeong/202                                                                                                                                                                0_aiva/llvm/llvm-project/compiler-rt/lib/fuzzer/./FuzzerLoop.cpp:765:7
    #26 0x43e139 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /home/bjeong/2020_aiva/llvm/llvm-proj                                                                                                                                                                ect/compiler-rt/lib/fuzzer/./FuzzerLoop.cpp:792:3
    #27 0x42dbe9 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /home/bjeong/2020_aiva/llvm/llvm-project/compiler-rt/li                                                                                                                                                                b/fuzzer/./FuzzerDriver.cpp:829:6
    #28 0x4441b0 in main /home/bjeong/2020_aiva/llvm/llvm-project/compiler-rt/lib/fuzzer/./FuzzerMain.cpp:19:10
    #29 0x7fa761cb0bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #30 0x4235c9 in _start (/root/fuzz-test-generation/AutoFuzz_Exp/test/glog_demangle_1/TestAutoFuzz_Demangle_Test+0x4235c9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/fuzz-test-generation/exp/glog/src/demangle.cc:211:7 in google::ParseOneCharToken(google::State*, char)
==28497==ABORTING
MS: 0 ; base unit: 0000000000000000000000000000000000000000
0x66,0x75,0x7a,0x7a,0x76,0x61,0x72,0x32,0x3a,0x20,0x22,0x5f,0x5a,0x35,0x5c,0x33,0x34,0x33,0x35,0x44,0x66,0x75,0x7a,0x7a,0x76,0x61,0x65,0x6d,0x61,0x6e,0x7a,0x                                                                                                                                                                7a,0x34,0x66,0x5b,0x5a,0x5a,0x36,0x76,0x61,0x65,0x6d,0x61,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36                                                                                                                                                                ,0x36,0x36,0x36,0x36,0x36,0x6e,0x7a,0x7a,0x33,0x5c,0x32,0x36,0x34,0x66,0x5b,0x5a,0x5a,0x38,0x6e,0x7a,0x5c,0x33,0x34,0x37,0x7a,0x32,0x66,0x5b,0x5a,0x5a,0x38,0                                                                                                                                                                x76,0x61,0x65,0x6d,0x61,0x6e,0x7a,0x3a,0x33,0x66,0x5b,0x5a,0x5a,0x38,0x5c,0x22,0x44,0x66,0x75,0x66,0x75,0x7a,0x7a,0x33,0x6e,0x7a,0x7a,0x76,0x66,0x5b,0x5a,0x5                                                                                                                                                                a,0x38,0x6e,0x7a,0x5c,0x33,0x34,0x37,0x7a,0x32,0x66,0x5b,0x44,0x66,0x75,0x66,0x75,0x7a,0x7a,0x76,0x61,0x65,0x6d,0x44,0x65,0x6d,0x61,0x66,0x75,0x7a,0x7a,0x76,                                                                                                                                                                0x61,0x65,0x6d,0x34,0x5c,0x22,0x5c,0x6e,0x22,0xa,
fuzzvar2: \"_Z5\\3435Dfuzzvaemanzz4f[ZZ6vaema6666666666666666666666666nzz3\\264f[ZZ8nz\\347z2f[ZZ8vaemanz:3f[ZZ8\\\"Dfufuzz3nzzvf[ZZ8nz\\347z2f[DfufuzzvaemDe                                                                                                                                                                mafuzzvaem4\\\"\\n\"\x0a
artifact_prefix='./'; Test unit written to ./crash-cfe825f8687b933ba7fe90b763eebc2c6db533b2
Base64: ZnV6enZhcjI6ICJfWjVcMzQzNURmdXp6dmFlbWFueno0ZltaWjZ2YWVtYTY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjZuenozXDI2NGZbWlo4bnpcMzQ3ejJmW1paOHZhZW1hbno6M2ZbWlo4XCJEZ                                                                                                                                                                nVmdXp6M256enZmW1paOG56XDM0N3oyZltEZnVmdXp6dmFlbURlbWFmdXp6dmFlbTRcIlxuIgo=

Reason

static bool ParseSourceName(State *state) { //Debugging: state has mangled_cur element that points input string indicates mangled name.
  State copy = *state;
  int length = -1;
  if (ParseNumber(state, &length) && ParseIdentifier(state, length)) { //Debugging: length set inside ParserNumber is used in ParseIdentifier.
    return true;
  }
  *state = copy;
  return false;
}
 
static bool ParseNumber(State *state, int *number_out) {
  int sign = 1;
  if (ParseOneCharToken(state, 'n')) {
    sign = -1;
  }
  const char *p = state->mangled_cur; //Debugging: assume that state->mangle_cur points "666666666666666666" string.
  int number = 0;
  for (;*p != '\0'; ++p) { // This loop works until consume all "6" in the string.
    if (IsDigit(*p)) { // always true.
      number = number * 10 + (*p - '0'); //Debugging: number, overflow.
    } else {
      break;
    }
  }
  if (p != state->mangled_cur) {  // Conversion succeeded.
    state->mangled_cur = p;
    if (number_out != NULL) {
      *number_out = number * sign; //Debugging: number_out set to overflowed value.
    }
    return true;
  }
  return false;
}
 
static bool ParseIdentifier(State *state, int length) {
  if (length == -1 ||
      !AtLeastNumCharsRemaining(state->mangled_cur, length)) {
    return false;
  }
  if (IdentifierIsAnonymousNamespace(state, length)) {
    MaybeAppend(state, "(anonymous namespace)");
 
  } else {
    MaybeAppendWithLength(state, state->mangled_cur, length);
 
  }
  state->mangled_cur += length; //Debugging: pointer for buffer points address based on overflowed, Now this program enters unexpected state.
  return true;
}

2 suggestions:

[1] Request CVE number for this bug to inform opencv users to prevent potential security vulnerabilities.
[2] Register below fuzzer code to ossfuzz (https://github.com/google/oss-fuzz) for continuous fuzzing.
(I found that there is no fuzzing test for glog in ossfuzz.)
Note that, the git repo of UTopia project(https://github.com/Samsung/UTopia) is currently empty and will be updated until the end of May.
Fuzzer Code:

/*
 * This fuzzer is generated by UTopia project based on TEST(Test_Tensorflow, read_inception).
 * (UTopia Project: https://github.com/Samsung/UTopia)
 */
#include "demangle.h"

using namespace GOOGLE_NAMESPACE;

extern "C" int LLVMFuzzerTestOneInput(const unsigned char *Data, unsigned Size) {
  char Buffer[Size + 1];
  memcpy(Buffer, Data, Size);
  Buffer[Size] = 0;
  char demangled[4096];
  Demangle(Buffer, demangled, Size);
  return 0;
}
@autofuzzoss autofuzzoss changed the title Demangel API: SEGV on unknown address Demangle API: SEGV on unknown address Apr 11, 2022
DonggeLiu pushed a commit to google/oss-fuzz that referenced this issue Feb 25, 2023
@sergiud are you interested in having glog running on oss-fuzz ?

see also google/glog#816 cc @autofuzzoss

I also quickly find a timeout with input
`_ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_`
eamonnmcmanus pushed a commit to eamonnmcmanus/oss-fuzz that referenced this issue Mar 15, 2023
@sergiud are you interested in having glog running on oss-fuzz ?

see also google/glog#816 cc @autofuzzoss

I also quickly find a timeout with input
`_ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_`
@sergiud sergiud added the bug label Oct 5, 2023
@sergiud sergiud added this to the 0.7 milestone Oct 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants