AFLplusplus / LibAFL

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...
Other
2.03k stars 319 forks source link

Fix pipe I/O in forkserver #2602

Closed henryhchchc closed 1 month ago

henryhchchc commented 1 month ago

When the fork server read a value from the pipe via read_st_size, the call self.st_pipe.read() may not read exactly size bytes. This happens when size is large (e.g., > 65535). In this case, we will run into the error at line 958 when the AUTODICT in the target is large.

https://github.com/AFLplusplus/LibAFL/blob/a69cd9843248665c3f6e5b519e045eada091c6d3/libafl/src/executors/forkserver.rs#L955-L959

When size is large, multiple reads are required to fill the buffer until read returns 0.

domenukk commented 1 month ago

Thanks for your work! :) As indicated above, replacing every use might be an issue for performance, without any benefit. I would probably try to restrict this to writes and reads that can actually fail (i.e., that are much larger than 4 bytes)

henryhchchc commented 1 month ago
After this operation, 1420 kB of additional disk space will be used.
Err:1 http://azure.archive.ubuntu.com/ubuntu noble-updates/main amd64 libegl-mesa0 amd64 24.0.9-0ubuntu0.1
  404  Not Found [IP: 20.106.104.242 80]
Get:2 http://azure.archive.ubuntu.com/ubuntu noble/main amd64 libipc-system-simple-perl all 1.30-2 [22.3 kB]
Get:3 http://azure.archive.ubuntu.com/ubuntu noble/main amd64 libfile-basedir-perl all 0.09-2 [14.4 kB]
Get:4 http://azure.archive.ubuntu.com/ubuntu noble/main amd64 libfile-desktopentry-perl all 0.22-3 [16.8 kB]
Get:5 http://azure.archive.ubuntu.com/ubuntu noble/main amd64 libfile-mimeinfo-perl all 0.34-1 [42.1 kB]
Get:6 http://azure.archive.ubuntu.com/ubuntu noble/main amd64 libio-stringy-perl all 2.111-3 [55.8 kB]
Get:7 http://azure.archive.ubuntu.com/ubuntu noble/main amd64 libegl1 amd64 1.7.0-1build1 [28.7 kB]
Get:8 http://azure.archive.ubuntu.com/ubuntu noble/main amd64 libgles2 amd64 1.7.0-1build1 [17.1 kB]
Get:9 http://azure.archive.ubuntu.com/ubuntu noble/universe amd64 zutty amd64 0.14.8.20231210+dfsg1-1 [185 kB]
Fetched 382 kB in 1s (557 kB/s)
E: Failed to fetch http://azure.archive.ubuntu.com/ubuntu/pool/main/m/mesa/libegl-mesa0_24.0.9-0ubuntu0.1_amd64.deb  404  Not Found [IP: 20.106.104.242 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
Error: Process completed with exit code 100.

The CI failure looks irrelevant.

domenukk commented 1 month ago

Thank you, this looks great! Yes something looks flakey in CI, unrelated for sure.

tokatoka commented 1 month ago

does this really fix your issue?

tokatoka commented 1 month ago

BTW I found returning the size of the bytes is redundant

for this i agree

henryhchchc commented 1 month ago

does this really fix your issue?

In case you missed it. read was replaced with read_exact in read_st_size.

tokatoka commented 1 month ago

sorry, indeed i missed that. but why does read stop at 65536 bytes? (why read_exact works but read() doesn't work)?

henryhchchc commented 1 month ago

why read_exact works but read() doesn't work

Let's say we have let buf: &mut [u8] = todo!(); whose length is n.

why does read stop at 65536 bytes

Short answer, I don't know. Long answer, this depends on the implementation of system calls, OS, and hardwares. I run into this issue on a Linux machine with AMD CPU. Probably the size of some I/O cache is 64k.


After a quick search driven by curiosity:

On Linux, the default pipe buffer size is 64k (16 pages). I guess the Linux read system call stops when the buffer is drained.