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

SEGV Bug Report, Fuzzing suggestion #836

Closed
autofuzzoss opened this issue Jul 4, 2022 · 1 comment
Closed

SEGV Bug Report, Fuzzing suggestion #836

autofuzzoss opened this issue Jul 4, 2022 · 1 comment

Comments

@autofuzzoss
Copy link

autofuzzoss commented Jul 4, 2022

System information (version)

  • Commit: b33e3ba
  • Operating System / Platform : ubuntu 18.04
  • Compiler : clang++ 10.0.1

Reproduce 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;
}

Build steps

mkdir -p build && cd build
cmake -DBUILD_SHARED_LIB=OFF -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_AR=/bin/llvm-ar -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_C_FLAGS=-g -DCMAKE_CXX_FLAGS=-g -DCMAKE_EXE_LINKER_FLAGS=-g -DCMAKE_SHARED_LINKER_FLAGS=-g .. > /dev/null 2>&1
make -j8 V=1

Reason

static bool ParseSourceName(State *state) { //Note that: 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)) { // length set inside ParserNumber is used 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; // 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'); // number, overflow.
    } else {
      break;
    }
  }
  if (p != state->mangled_cur) {  // Conversion succeeded.
    state->mangled_cur = p;
    if (number_out != NULL) {
      *number_out = number * sign; // 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; //pointer for buffer points address based on overflowed, Now this program enters unexpected state.
  return true;
}

Address Sanitizer Report

AddressSanitizer:DEADLYSIGNAL
=================================================================
==92==ERROR: AddressSanitizer: SEGV on unknown address 0xffffffffc0f87120 (pc 0x0000004c6d9c bp 0x7fff865ab760 sp 0x7fff865ab740 T0)
==92==The signal is caused by a READ memory access.
    #0 0x4c6d9c in google::ParseOneCharToken(google::State*, char) /root/fuzz-test-generation/exp/glog/src/demangle.cc:212:24
    #1 0x4c9291 in google::ParseAbiTag(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:756:10
    #2 0x4c76f1 in google::OneOrMore(bool (*)(google::State*), google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:257:7
    #3 0x4c9157 in google::ParseAbiTags(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:745:7
    #4 0x4c8ebe in google::ParseUnqualifiedName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:614:47
    #5 0x4c6cbc in google::ParseUnscopedName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:538:7
    #6 0x4c6b84 in google::ParseUnscopedTemplateName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:555:10
    #7 0x4c635c in google::ParseName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:521:7
    #8 0x4c8464 in google::ParseClassEnumType(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1079:10
    #9 0x4c7b65 in google::ParseType(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1000:7
    #10 0x4c770d in google::OneOrMore(bool (*)(google::State*), google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:258:12
    #11 0x4c641f in google::ParseBareFunctionType(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1068:7
    #12 0x4c6282 in google::ParseEncoding(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:500:27
    #13 0x4c5ff6 in google::ParseMangledName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:492:44
    #14 0x4c5f24 in google::ParseTopLevelMangledName(google::State*) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1341:7
    #15 0x4c5e61 in google::Demangle(char const*, char*, unsigned long) /root/fuzz-test-generation/exp/glog/src/demangle.cc:1395:10
    #16 0x4c5d6b in main (/root/fuzz-test-generation/exp_musang/glog/crash1/poc+0x4c5d6b)
    #17 0x7f5d931c6bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #18 0x41b4a9 in _start (/root/fuzz-test-generation/exp_musang/glog/crash1/poc+0x41b4a9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/fuzz-test-generation/exp/glog/src/demangle.cc:212:24 in google::ParseOneCharToken(google::State*, char)
==92==ABORTING

Recommendations

2 suggestions for security improvements.
[1] Request CVE number for this bug to inform users to prevent potential security vulnerabilities.
[2] Register below fuzzer code to ossfuzz for continuous fuzzing.

FuzzerCode:

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
 * 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
Copy link
Author

Duplicated with #816

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant