
The maximum recursion depth is set to 25. If that's not sufficient for someone's needs, they're welcome to submit a patch that makes it configurable. This fixes a stack overflow found by AutoFuzz. The stack overflow was caused by recursing too much. I've included the fuzzer's test cases in the fuzzing/corpus directory. I've also created two (one for SimpleTag and ChapterAtom each) additional test files, each comprised of 10,000 recursively nested elements. Manually running the fuzzer (with ASan and UBSan) shows all inputs are now handled correctly, and no stack overflows occur. Change-Id: I8514259fd0788e71a58e3ccce2a0fb8a3523acfc
77 lines
2.1 KiB
C++
77 lines
2.1 KiB
C++
// Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style license
|
|
// that can be found in the LICENSE file in the root of the source
|
|
// tree. An additional intellectual property rights grant can be found
|
|
// in the file PATENTS. All contributing project authors may
|
|
// be found in the AUTHORS file in the root of the source tree.
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <new>
|
|
#include <vector>
|
|
|
|
#include "webm/buffer_reader.h"
|
|
#include "webm/callback.h"
|
|
#include "webm/file_reader.h"
|
|
#include "webm/reader.h"
|
|
#include "webm/status.h"
|
|
#include "webm/webm_parser.h"
|
|
|
|
using webm::BufferReader;
|
|
using webm::Callback;
|
|
using webm::FileReader;
|
|
using webm::Reader;
|
|
using webm::Status;
|
|
using webm::WebmParser;
|
|
|
|
static int Run(Reader* reader) {
|
|
Callback callback;
|
|
WebmParser parser;
|
|
|
|
#if WEBM_FUZZER_SEEK_FIRST
|
|
parser.DidSeek();
|
|
#endif
|
|
|
|
Status status(-1);
|
|
try {
|
|
status = parser.Feed(&callback, reader);
|
|
} catch (std::bad_alloc&) {
|
|
// Failed allocations are okay. MSan doesn't throw std::bad_alloc, but
|
|
// someday it might.
|
|
}
|
|
|
|
// BufferReader/FileReader should never return either of the following codes,
|
|
// which means the parser never should too:
|
|
assert(status.code != Status::kWouldBlock);
|
|
assert(status.code != Status::kOkPartial);
|
|
|
|
// Only the following ranges have status codes defined:
|
|
assert((-1031 <= status.code && status.code <= -1025) ||
|
|
(-3 <= status.code && status.code <= 0));
|
|
|
|
return 0;
|
|
}
|
|
|
|
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data,
|
|
std::size_t size) {
|
|
BufferReader reader(std::vector<std::uint8_t>(data, data + size));
|
|
return Run(&reader);
|
|
}
|
|
|
|
#if __AFL_COMPILER
|
|
int main(int argc, char* argv[]) {
|
|
FILE* file = (argc == 2) ? std::fopen(argv[1], "rb") :
|
|
std::freopen(nullptr, "rb", stdin);
|
|
if (!file) {
|
|
std::cerr << "File cannot be opened\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
FileReader reader(file);
|
|
return Run(&reader);
|
|
}
|
|
#endif
|