On Thu, Sep 21, 2023 at 10:22:08PM +0100, Richard W.M. Jones wrote: > On Thu, Sep 21, 2023 at 03:58:01PM -0500, Eric Blake wrote: > > When fuzzing, it is more desirable to always provoke the server into > > sending a response, rather than sometimes accidentally skipping a wire > > call because a client-side strictness test failed. > > > > [Our fuzzer could probably be made even more powerful by changing the > > fuzzer input file to be a series of records, where each record is the > > API to call and then the server's response; right now, the sequence of > > APIs called is hard-coded, which is not as powerful at testing > > potential cross-command coupling. But that's a project for another > > day.] > > Intrigued by how this would work exactly. The current file is just a > stream of bytes from the "server" (the output from libnbd is > discarded). Would the input file be of the form: > > ( [ request + args ] [ stream of bytes from server ] )* > > where [ request + args ] would be a simple serialized representation > of a synchronous nbd_* API call? I think that would work ...
Actually I don't think this would work. The stream of bytes is variable length so it would need a sentinel to indicate the end of one stream (hard to do in-stream) or a length field up front. However fuzzing doesn't work well with length + data since the fuzzer doesn't understand the relationship. This could work (I've abbreviated "request + args" to just "request" and "stream ..." to "stream"): ( [ request ] )* [ sentinel ] [ stream ] (* case B *) where [ sentinel ] is some sentinel that can be distinguished from a request. The idea here is the fuzzing wrapper would read the set of requests into an internal structure, then process the stream as it does now while issuing the requests. However I still don't think the fuzzer would work well with this. The problem is that the stream of bytes is still related to the set of requests. For example if a new request was inserted then some later point in the stream would need to change, but the fuzzer wouldn't understand this relationship. [Now I'm thinking if only we could use an AI transformer it would solve this problem too! Transformers can find these kind of long-range moving dependencies.] This seems better still: [ request ] [ stream ] (* case C *) There's a single request (which can represent exactly one nbd_* request), and a single associated stream. The fuzzer would generate alternate nbd_* APIs as it mutated the request field. However the problem here is we no longer have any way to describe multiple dependent requests. So ... I think my answer is to go back to case B: ( [ request ] )* [ sentinel ] [ stream ] but make the starting test cases all look (nearly) like case C: [ request ] [ sentinel ] [ stream ] The fuzzer would start by finding the simple test cases looking like C, and then might create longer test cases looking like B later in the run (or might not, we'd need to examine the output after a long run). Anyway, something for a rainy day. Rich. > Rich. > > > Signed-off-by: Eric Blake <ebl...@redhat.com> > > Reviewed-by: Richard W.M. Jones <rjo...@redhat.com> > > Reviewed-by: Laszlo Ersek <ler...@redhat.com> > > --- > > fuzzing/libnbd-fuzz-wrapper.c | 5 ++++- > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/fuzzing/libnbd-fuzz-wrapper.c b/fuzzing/libnbd-fuzz-wrapper.c > > index cbd55380..fcd1d04c 100644 > > --- a/fuzzing/libnbd-fuzz-wrapper.c > > +++ b/fuzzing/libnbd-fuzz-wrapper.c > > @@ -193,8 +193,11 @@ client (int sock) > > } > > > > /* Note we ignore errors in these calls because we are only > > - * interested in whether the process crashes. > > + * interested in whether the process crashes. Likewise, we don't > > + * want to accidentally avoid sending traffic to the server merely > > + * because client side strictness sees a problem. > > */ > > + nbd_set_strict_mode (nbd, 0); > > > > /* Enable a metadata context, for block status below. */ > > nbd_add_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION); > > -- > > 2.41.0 > > -- > Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones > Read my programming and virtualization blog: http://rwmj.wordpress.com > virt-top is 'top' for virtual machines. Tiny program with many > powerful monitoring features, net stats, disk stats, logging, etc. > http://people.redhat.com/~rjones/virt-top -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs