syzkaller icon indicating copy to clipboard operation
syzkaller copied to clipboard

all: do comparison substitution for extra coverage

Open a-nogikh opened this issue 1 year ago • 5 comments

Collect comparison arguments for extra coverage. For that, we now need to start remote coverage collection for every forked program.

Substitute the arguments into all calls that have remote_cover set.


Do we need any special handling for the SYZ_EXECUTOR_USES_FORK_SERVER == 0 case?

a-nogikh avatar May 28 '24 16:05 a-nogikh

Codecov Report

Attention: Patch coverage is 0% with 24 lines in your changes are missing coverage. Please review.

Project coverage is 61.2%. Comparing base (34889ee) to head (1dcae20). Report is 2 commits behind head on master.

Additional details and impacted files
Files Coverage Δ
pkg/ipc/ipc.go 47.6% <0.0%> (-0.2%) :arrow_down:
pkg/fuzzer/job.go 21.8% <0.0%> (-0.8%) :arrow_down:

... and 2 files with indirect coverage changes

codecov[bot] avatar May 31 '24 10:05 codecov[bot]

Hmm, the backward incompatibility is worse than I thought.

Since we may lose a current->kcov reference (the fix will be posted soon), we're not just leaking remote kcov handles. If it were only that, we could address it by trying out a number of different handles for every procid.

But we're also unable to reuse the same *kcov object since

  • It's already not in KCOV_MODE_INIT, which breaks https://elixir.bootlin.com/linux/latest/source/kernel/kcov.c#L621
  • We cannot reset/free it: KCOV_DISABLE only works for current->kcov: https://elixir.bootlin.com/linux/latest/source/kernel/kcov.c#L612

And we cannot obtain a new /dev/kcov handle inside execute_one() -- when we're there, we're already in a sandboxed environment.

UPD: We might have to return to keeping a single remote kcov instance per a syz-executor process. Maybe we could then open two remote kcov instances -- one for the normal coverage and one for comparisons? The only real downside is that we'd have to also keep two memory buffers for them.

a-nogikh avatar May 31 '24 18:05 a-nogikh

Can we create the remote kcov on a thread that never executes? I.e. not the main thread, but rather an additional special thread that exists just for that purpose?

dvyukov avatar Jun 03 '24 07:06 dvyukov

Can we create the remote kcov on a thread that never executes? I.e. not the main thread, but rather an additional special thread that exists just for that purpose?

Interesting! Though it won't be a thread that truly never executes since it will at least have to execute the KCOV_REMOTE_ENABLE ioctl. We can try to e.g. block the thread after that ioctl. There's still a chance to catch an irq in between, but a much smaller one.

a-nogikh avatar Jun 03 '24 09:06 a-nogikh

Can we create the remote kcov on a thread that never executes? I.e. not the main thread, but rather an additional special thread that exists just for that purpose?

Interesting! Though it won't be a thread that truly never executes since it will at least have to execute the KCOV_REMOTE_ENABLE ioctl. We can try to e.g. block the thread after that ioctl. There's still a chance to catch an irq in between, but a much smaller one.

KCOV_REMOTE_ENABLE is done once per top level process, so it should reduce probability several orders of magnitude. If can be mmaped by a different thread, then we could even create them in syz-fuzzer (I wouldn't bother now, we can do it in the rewritten executor runner).

dvyukov avatar Jun 03 '24 09:06 dvyukov