summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hanselmann <public@hansmi.ch>2021-05-30 16:46:33 +0200
committerMichael Hanselmann <public@hansmi.ch>2021-07-08 23:24:34 +0200
commit58f198e8d4ae36cc29b76c7a9f731021aa92f146 (patch)
treefdbdd58bc2df98f6e18faaced8d7b4ac65f01be0
parent6236042f76942ff797f9e58319943b4524a2901e (diff)
usbredirparserfuzz: Test un-/serializing of data
Exercise more code paths by unserializing a fuzzed data buffer and serializing while reading and writing. Signed-off-by: Michael Hanselmann <public@hansmi.ch>
-rw-r--r--fuzzing/usbredirparserfuzz.cc55
1 files changed, 55 insertions, 0 deletions
diff --git a/fuzzing/usbredirparserfuzz.cc b/fuzzing/usbredirparserfuzz.cc
index ecd3c96..e97a136 100644
--- a/fuzzing/usbredirparserfuzz.cc
+++ b/fuzzing/usbredirparserfuzz.cc
@@ -361,6 +361,50 @@ void parser_bulk_receiving_status(void *priv, uint64_t id,
struct usb_redir_bulk_receiving_status_header *bulk_receiving_status)
{
}
+
+int try_unserialize(struct usbredirparser *parser, FuzzedDataProvider *fdp)
+{
+ std::vector<uint8_t> state;
+ size_t len = fdp->ConsumeIntegralInRange<size_t>(1, 64 * 1024);
+
+ state.reserve(len);
+
+ if (len >= 4) {
+ // Could also move USBREDIRPARSER_SERIALIZE_MAGIC after moving it to
+ // a shared header.
+ state.insert(state.end(), {'U', 'R', 'P', '1'});
+ len -= 4;
+ }
+
+ if (len > 0) {
+ const std::vector<uint8_t> payload{fdp->ConsumeBytes<uint8_t>(len)};
+
+ state.insert(state.end(), payload.cbegin(), payload.cend());
+ }
+
+ if (state.empty()) {
+ return 0;
+ }
+
+ state.shrink_to_fit();
+
+ return usbredirparser_unserialize(parser, &state[0], state.size());
+}
+
+int try_serialize(struct usbredirparser *parser)
+{
+ uint8_t *state = nullptr;
+ int len = 0;
+ int ret;
+
+ ret = usbredirparser_serialize(parser, &state, &len);
+
+ if (ret == 0) {
+ free(state);
+ }
+
+ return ret;
+}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
@@ -426,8 +470,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
usbredirparser_init(parser.get(), "fuzzer", caps.data(), caps.size(),
init_flags);
+ if (fdp->ConsumeBool() && try_unserialize(parser.get(), fdp.get()) != 0) {
+ goto out;
+ }
+
while (fdp->remaining_bytes() > 0 ||
usbredirparser_has_data_to_write(parser.get())) {
+ if (fdp->ConsumeBool() && try_serialize(parser.get()) != 0) {
+ goto out;
+ }
+
if (fdp->remaining_bytes() > 0) {
ret = usbredirparser_do_read(parser.get());
@@ -440,6 +492,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
goto out;
}
+ if (fdp->ConsumeBool() && try_serialize(parser.get()) != 0) {
+ goto out;
+ }
}
while (usbredirparser_has_data_to_write(parser.get())) {