dfuzzer
dfuzzer copied to clipboard
Dictionaries as a way to guide dfuzzer?
It was discussed in https://github.com/matusmarhefka/dfuzzer/pull/80#discussion_r867525573
More generally it would be great to come up with more heuristics allowing dfuzzer to cover as much code as possible (preferably automatically)
@mrc0mmand issues like https://github.com/systemd/systemd/issues/23381 could be caught by dfuzzer
if it supported json dictionaries. Generally a lot of DBus interfaces provided by systemd
aren't covered by any tests so I think if dfuzzer
could load json dictionaries with more or less valid data and apply just its basic heuristics based on the assumption that corner cases aren't covered as usual it could be used to look for and prevent "shallow" issue like that more effectively. Turns out cockpit
https://github.com/cockpit-project/cockpit/blob/main/src/bridge/cockpitdbusjson.c can translate json into dbus calls (with glib
and json-glib
as far as I can see) so maybe something like that could be hooked up to dfuzzer
.
https://github.com/systemd/systemd/issues/20933 would be another example where json dictionaries with basic mutations could have helped probably.
FWIW there is another project where json is converted to dbus messages: https://github.com/elrafoon/json-dbus-bridge
So I tried to collect valid dbus messages that can be used to populate dictionaries automatically using the systemd testsuite and it didn't work out unfortunately. For example the DBus interfaces provided by machined aren't covered by a lot of tests judging from machine-dbus.c (8.1%) and machined-dbus.c (26.34%). I'm not sure what to do about it. Another issue is that for example importd
uses file descriptors extensively and dfuzzer
sends (mostly) invalid file descriptors without trying to read/write to/from them and it isn't clear how to address that. It should be possible to redirect its input with bash using <
or something like that but it could help to get past basic checks on the receiving end only.
So I tried to collect valid dbus messages that can be used to populate dictionaries automatically using the systemd testsuite and it didn't work out unfortunately. For example the DBus interfaces provided by machined aren't covered by a lot of tests judging from machine-dbus.c (8.1%) and machined-dbus.c (26.34%). I'm not sure what to do about it.
Do you have any example how such message looks like? Or is it something like https://github.com/dbus-fuzzer/dfuzzer/issues/75#issuecomment-1120477537?
Another issue is that for example
importd
uses file descriptors extensively anddfuzzer
sends (mostly) invalid file descriptors without trying to read/write to/from them and it isn't clear how to address that. It should be possible to redirect its input with bash using<
or something like that but it could help to get past basic checks on the receiving end only.
This could be, maybe, solvable to some degree by sometimes opening a valid file descriptor, for example via fmemopen() or something similar.
Or is it something like https://github.com/dbus-fuzzer/dfuzzer/issues/75#issuecomment-1120477537?
Yes it is. I just ran busctl monitor
in the background to figure out what valid messages look like and how likely it is dfuzzer
can generate them with/without dictionaries.
This could be, maybe, solvable to some degree by sometimes opening a valid file descriptor, for example via fmemopen() or something similar.
Agreed. I think it should be possible to pass valid file descriptors. It's just that dfuzzer
can't be sure what exactly DBus services it tests do with them. They can write to them or read from them (or do something else) and just passing fds and closing them can't get far in most cases. If dfuzzer kept them open if would probably be more useful but it would still have to read/write something.
Or is it something like #75 (comment)?
Yes it is. I just ran
busctl monitor
in the background to figure out what valid messages look like and how likely it isdfuzzer
can generate them with/without dictionaries.
I see. Would it make sense to begin with a "dumb" implementation first - i.e. accepting a file with a list of JSON objects, and if the service/object/interface/method* matches, use the payload instead of generating a random one? I'm still not completely sure how all the pieces would fit together, so this might be a good starting point :-)
* this could use the same rules as the suppression stuff, if needed, i.e. a missing interface means "all interfaces"
This could be, maybe, solvable to some degree by sometimes opening a valid file descriptor, for example via fmemopen() or something similar.
Agreed. I think it should be possible to pass valid file descriptors. It's just that
dfuzzer
can't be sure what exactly DBus services it tests do with them. They can write to them or read from them (or do something else) and just passing fds and closing them can't get far in most cases. If dfuzzer kept them open if would probably be more useful but it would still have to read/write something.
I see, that make sense. Could you, please, open an issue about this, since the solution might not be as straightforward as I originally thought? (And this is something we should definitely fix/implement.)
I've been thinking about this and I think that maybe instead of json it would be easier to use pcaps. Wireshark can dissect dbus messages so it should be easy to turn them into something human-friendly if necessary. It should also make it easier to replay messages to get services to reach certain points before starting throwing gibberish.
I haven't figured out what to do with file descriptors though :-)