| Index: webrtc/test/fuzzers/transport_feedback_packet_loss_tracker_fuzzer.cc
|
| diff --git a/webrtc/test/fuzzers/transport_feedback_packet_loss_tracker_fuzzer.cc b/webrtc/test/fuzzers/transport_feedback_packet_loss_tracker_fuzzer.cc
|
| index 5c3cfcba289b44103b7326cfc8b09c11f2fa7ead..c8e261982d12cb9ce23fc0da69d9a74b1e98e428 100644
|
| --- a/webrtc/test/fuzzers/transport_feedback_packet_loss_tracker_fuzzer.cc
|
| +++ b/webrtc/test/fuzzers/transport_feedback_packet_loss_tracker_fuzzer.cc
|
| @@ -109,16 +109,12 @@ bool Setup(const uint8_t** data,
|
|
|
| constexpr size_t kSeqNumHalf = 0x8000u;
|
|
|
| - // 0x8000 >= max_window_size >= plr_min_num_packets > rplr_min_num_pairs >= 1
|
| - // (The distribution isn't uniform, but it's enough; more would be overkill.)
|
| - const size_t max_window_size = FuzzInRange(data, size, 2, kSeqNumHalf);
|
| - const size_t plr_min_num_packets =
|
| - FuzzInRange(data, size, 2, max_window_size);
|
| - const size_t rplr_min_num_pairs =
|
| - FuzzInRange(data, size, 1, plr_min_num_packets - 1);
|
| + const int64_t max_window_size_ms = FuzzInRange(data, size, 1, 1 << 16);
|
| + const size_t plr_min_num_packets = FuzzInRange(data, size, 1, kSeqNumHalf);
|
| + const size_t rplr_min_num_pairs = FuzzInRange(data, size, 1, kSeqNumHalf - 1);
|
|
|
| tracker->reset(new TransportFeedbackPacketLossTracker(
|
| - max_window_size, plr_min_num_packets, rplr_min_num_pairs));
|
| + max_window_size_ms, plr_min_num_packets, rplr_min_num_pairs));
|
|
|
| return true;
|
| }
|
| @@ -140,10 +136,56 @@ bool FuzzSequenceNumberDelta(const uint8_t** data,
|
| return true;
|
| }
|
|
|
| +bool FuzzClockAdvancement(const uint8_t** data,
|
| + size_t* size,
|
| + int64_t* time_ms) {
|
| + // Fuzzing 64-bit worth of delta would be extreme overkill, as 32-bit is
|
| + // already ~49 days long. We'll fuzz deltas up to a smaller value, and this
|
| + // way also guarantee that wrap-around is impossible, as in real life.
|
| +
|
| + // Higher likelihood for more likely cases:
|
| + // 5% chance of delta = 0.
|
| + // 20% chance of delta in range [1 : 10] (uniformly distributed)
|
| + // 55% chance of delta in range [11 : 500] (uniformly distributed)
|
| + // 20% chance of delta in range [501 : 10000] (uniformly distributed)
|
| + struct ProbabilityDistribution {
|
| + float probability;
|
| + size_t lower;
|
| + size_t higher;
|
| + };
|
| + constexpr ProbabilityDistribution clock_probability_distribution[] = {
|
| + {0.05, 0, 0}, {0.20, 1, 10}, {0.55, 11, 500}, {0.20, 501, 10000}};
|
| +
|
| + if (*size < sizeof(uint8_t)) {
|
| + return false;
|
| + }
|
| + const float fuzzed = FuzzInput<uint8_t>(data, size) / 256.0f;
|
| +
|
| + float cumulative_probability = 0;
|
| + for (const auto& dist : clock_probability_distribution) {
|
| + cumulative_probability += dist.probability;
|
| + if (fuzzed < cumulative_probability) {
|
| + if (dist.lower == dist.higher) {
|
| + *time_ms += dist.lower;
|
| + return true;
|
| + } else if (*size < sizeof(uint16_t)) {
|
| + return false;
|
| + } else {
|
| + *time_ms += FuzzInRange(data, size, dist.lower, dist.higher);
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| +
|
| + RTC_NOTREACHED();
|
| + return false;
|
| +}
|
| +
|
| bool FuzzPacketSendBlock(
|
| std::unique_ptr<TransportFeedbackPacketLossTracker>& tracker,
|
| const uint8_t** data,
|
| - size_t* size) {
|
| + size_t* size,
|
| + int64_t* time_ms) {
|
| // We want to test with block lengths between 1 and 2^16, inclusive.
|
| if (*size < sizeof(uint8_t)) {
|
| return false;
|
| @@ -155,16 +197,24 @@ bool FuzzPacketSendBlock(
|
| return false;
|
| }
|
| uint16_t seq_num = FuzzInput<uint16_t>(data, size);
|
| - tracker->OnPacketAdded(seq_num);
|
| + tracker->OnPacketAdded(seq_num, *time_ms);
|
| tracker->Validate();
|
|
|
| + bool may_continue = FuzzClockAdvancement(data, size, time_ms);
|
| + if (!may_continue) {
|
| + return false;
|
| + }
|
| +
|
| for (size_t i = 1; i < packet_block_len; i++) {
|
| uint16_t delta;
|
| - bool may_continue = FuzzSequenceNumberDelta(data, size, &delta);
|
| + may_continue = FuzzSequenceNumberDelta(data, size, &delta);
|
| + if (!may_continue)
|
| + return false;
|
| + may_continue = FuzzClockAdvancement(data, size, time_ms);
|
| if (!may_continue)
|
| return false;
|
| seq_num += delta;
|
| - tracker->OnPacketAdded(seq_num);
|
| + tracker->OnPacketAdded(seq_num, *time_ms);
|
| tracker->Validate();
|
| }
|
|
|
| @@ -206,8 +256,15 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
|
|
| may_continue = Setup(&data, &size, &tracker);
|
|
|
| + // We never expect this to wrap around, so it makes sense to just start with
|
| + // a sane value, and keep on incrementing by a fuzzed delta.
|
| + if (size < sizeof(uint32_t)) {
|
| + return;
|
| + }
|
| + int64_t time_ms = FuzzInput<uint32_t>(&data, &size);
|
| +
|
| while (may_continue) {
|
| - may_continue = FuzzPacketSendBlock(tracker, &data, &size);
|
| + may_continue = FuzzPacketSendBlock(tracker, &data, &size, &time_ms);
|
| if (!may_continue) {
|
| return;
|
| }
|
|
|