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