webrtc_m130/test/fuzzers/utils/rtp_replayer.h
Benjamin Wright 47dbcabc2e Fuzzing support for RTPDump VP8 and VP9 Streams.
This change integrates fuzzing support for RtpDumps in WebRTC. This allows
LibFuzzer to directly fuzz the RTP code path from packet arrival all the way
to actual decoding and rendering. It does this by replaying each RTP packet
in the RTPDump which can be mutated directly by the fuzzer.

For fuzzing support the RtpFileReader needs to support reading from a
buffer instead of an file. The test class requires FILE* for all its
parsing operations and is deeply coupled this way. I chose to solve this
problem at an OS level by using the tmpfile() option and copying the buffer
to the tmpfile(). fmemopen() is no available on most platforms so couldn't
be used as a generic solution. The additional copy isn't ideal but won't
be a bottleneck for the fuzzing.

In the future I plan for the fuzzers to read from a configuration file. But
given the current packaging strategy for fuzzers in WebRTC this isn't easy.

Bug: webrtc:9860
Change-Id: I2560120e82663f9e9fb5b9640e6a6d16f9c1a360
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/126682
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Benjamin Wright <benwright@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27151}
2019-03-15 18:48:43 +00:00

88 lines
3.1 KiB
C++

/*
* Copyright (c) 2019 The WebRTC 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.
*/
#ifndef TEST_FUZZERS_UTILS_RTP_REPLAYER_H_
#define TEST_FUZZERS_UTILS_RTP_REPLAYER_H_
#include <stdio.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "api/test/video/function_video_decoder_factory.h"
#include "api/video_codecs/video_decoder.h"
#include "call/call.h"
#include "logging/rtc_event_log/rtc_event_log.h"
#include "media/engine/internal_decoder_factory.h"
#include "rtc_base/time_utils.h"
#include "test/null_transport.h"
#include "test/rtp_file_reader.h"
#include "test/test_video_capturer.h"
#include "test/video_renderer.h"
namespace webrtc {
namespace test {
// The RtpReplayer is a utility for fuzzing the RTP/RTCP receiver stack in
// WebRTC. It achieves this by accepting a set of Receiver configurations and
// an RtpDump (consisting of both RTP and RTCP packets). The |rtp_dump| is
// passed in as a buffer to allow simple mutation fuzzing directly on the dump.
class RtpReplayer final {
public:
// Holds all the important stream information required to emulate the WebRTC
// rtp receival code path.
struct StreamState {
test::NullTransport transport;
std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>> sinks;
std::vector<VideoReceiveStream*> receive_streams;
std::unique_ptr<VideoDecoderFactory> decoder_factory;
};
// Construct an RtpReplayer from a JSON replay configuration file.
static void Replay(const std::string& replay_config_filepath,
const uint8_t* rtp_dump_data,
size_t rtp_dump_size);
// Construct an RtpReplayer from a set of VideoReceiveStream::Configs. Note
// the stream_state.transport must be set for each receiver stream.
static void Replay(
std::unique_ptr<StreamState> stream_state,
std::vector<VideoReceiveStream::Config> receive_stream_config,
const uint8_t* rtp_dump_data,
size_t rtp_dump_size);
private:
// Reads the replay configuration from Json.
static std::vector<VideoReceiveStream::Config> ReadConfigFromFile(
const std::string& replay_config,
Transport* transport);
// Configures the stream state based on the receiver configurations.
static void SetupVideoStreams(
std::vector<VideoReceiveStream::Config>* receive_stream_configs,
StreamState* stream_state,
Call* call);
// Creates a new RtpReader which can read the RtpDump
static std::unique_ptr<test::RtpFileReader> CreateRtpReader(
const uint8_t* rtp_dump_data,
size_t rtp_dump_size);
// Replays each packet to from the RtpDump.
static void ReplayPackets(Call* call, test::RtpFileReader* rtp_reader);
}; // class RtpReplayer
} // namespace test
} // namespace webrtc
#endif // TEST_FUZZERS_UTILS_RTP_REPLAYER_H_