<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/72334>72334</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
libFuzzer's runtime argument -stop_file doesn't work with empty files
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
markszabo
</td>
</tr>
</table>
<pre>
libFuzzer has a runtime argument `-stop-file` with [this description](https://github.com/llvm/llvm-project/blob/72accbfd0a1023b3182202276904120524ff9200/compiler-rt/lib/fuzzer/FuzzerFlags.def#L76):
```
stop_file: "Stop fuzzing ASAP if this file exists"
```
However fuzzing only stops if the file exists and has some content. If the file is empty, the fuzzing continues.
## Steps to reproduce
1. Create a simple fuzz test, e.g.
```cpp
#include <fuzzer/FuzzedDataProvider.h>
#include <assert.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
FuzzedDataProvider provider(data, size);
int a = provider.ConsumeIntegral<int>();
int b = provider.ConsumeIntegral<int>();
assert(a+b == b+a);
return 0;
}
```
Save it as `test.cpp`
2. Compile the test
```sh
clang++ -g -fsanitize=address,fuzzer test.cpp -o test
```
3. Run the resulting binary with the `-stop_file` argument:
```sh
./test -stop_file=/tmp/stop-file
```
4. In a separate terminal create the stop-file as an empty file:
```sh
touch /tmp/stop-file
```
Observe that the fuzzing run continues.
4. Create a file with some content:
```sh
rm /tmp/stop-file # optional
echo abc > /tmp/stop-file
```
Observe that the fuzzing stops quickly with a message like `Done 5036370 runs in 21 second(s)`.
## Expected behavior
Either the flag description should say that the file can't be empty, or fuzzing should stop even if the file is empty.
## Potential cause of the issue
I believe [this is the part of the code](https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/fuzzer/FuzzerLoop.cpp#L878-L880) that stops the fuzzing loop if the file exists:
```cpp
if (!Options.StopFile.empty() &&
!FileToVector(Options.StopFile, 1, false).empty())
break;
```
`FileToVector()` is implemented [here](https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/fuzzer/FuzzerIO.cpp#L41):
```cpp
Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {
std::ifstream T(Path, std::ios::binary);
if (ExitOnError && !T) {
Printf("No such directory: %s; exiting\n", Path.c_str());
exit(1);
}
T.seekg(0, T.end);
auto EndPos = T.tellg();
if (EndPos < 0) return {};
size_t FileLen = EndPos;
if (MaxSize)
FileLen = std::min(FileLen, MaxSize);
T.seekg(0, T.beg);
Unit Res(FileLen);
T.read(reinterpret_cast<char *>(Res.data()), FileLen);
return Res;
}
```
This returns `{}` if the file doesn't exist, but also if the file is empty, leading to this behavior.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8V99v6joS_mvMy6hRsPkRHngoULSVerfVKXtfKycZwFvHztpOT3v--tU4IYSWXu3ZlbZCkCaezzOeme-bSO_VwSAu2XTFppuRbMLRumUl3av_JXM7ym35sdQq3za_fqGDo_QgwTUmqApBukNToQnAZumND7a-2SuNbJbCTxWOwKarcFQeSvSFU3VQ1rDphvHsGELtmbhlfMv49qDCscmTwlaMb7V-O_3c1M7-E4vA-DbXNmd8O-eyKPJ9mcpxykUuxhnnKefz2SKdjHk65ZP9fsHTlPFtYataaXQ3juy1IvN9jIHxbRvMVsuDT0rcMy4e5jPGF-RSumHp6XuWdp_4LwX4EgMUt8A4fw62BsJU5gC3z7dPoPYQA6ZFgO_KB884vwrWfv_N_sQ3dD2KNfoDaB_fYuEQCqQpYwK8rRAKawKakMD9YKHygFUdPhhftzc7XFqsTIM-uYiPC8YFPAesPQQLDmtny6bA4aJxAmuHMiBI8KqqdYsKAX2gbTA5dKAA0AdZ1PX5JhfKFLopEZhYXyah3Mggn5x9UyW65MjEXWd2aSS9RxeGzwH6C3wP6AxlZM04B2UCPDz8-Ueb5B368Gjw3tRNYDwrrPEBGmVC9hKA8dtSBklhePULX0L8oULoN5mvuuuv7kLdXTCeDWFiIa16CPojnyQwseltkrU1vqnw3gQ8OKmZWCsTKD6efQOQ_7cAF0jtUTKeScZXEZJQc8ZXcmjW2TgMjTOQXsDNN18T3t95lm8IKoD09JCqJKFiuKx7nsC6bdBYprGWvkD6Y3-v0NIcGF8xvoKbA9zsvTQq0FmLjSxLh94z3pUWnPaEG_sN8tAVkcCPxkQ3HPpGB-qXXBnpPloWoycnfns58duJ-XrG-MbxhPEt-QADc7Ghm1XN-PbMmV3VX_NwksC9oe7DWjpqxICuUkZqKNrGJA97JDp4aVoagI6t_tLFYJviCN-6dC3Hj7lH90Yby3DBM64x33DNZEAj0c14tkMmO_t5zUtXXXGRWAJsFBapz3xQHC3IvAAm7r6P6zeiagn5X40qXnVXFBIq9F4eELR6jfWxsQZhmoqZmKd0Dh6UAT4Gj4U1JeOZp_aapdcY-O69xiJgCTke5ZuyDoaL7lQ4UlmTR1oehnIK_mgbXYKXHwO36WQKaRifB8jxrAj2LDQnO5IwfENzITcnFbnm6pOlXCkqPtl4BNvaKe-bC9m4hxy1wjfspwDl48paunCyKmyJ_9tEUEll_jO1f7C2jkzExUM2z24esixlfNEeW5vhYc61tfUVDf5uQhjqHZlFEh4_xiT5hCaFrdKYdKkgggbGZ_QZcjMwPqZ1O_snFsGSsHyGoDyO6WsvtSepGWIOlQsAcofy9czo17iFzdJPG7ZVStmKYk8khyUl8Yju_5as-8dTqibjv5jL-lP_h1EBPgXSSr0PJVmLWx8c5ZXx2ZMMx4Hk_yHfn6NqryG3VsPduwqP5s45QlkMJoAeSu19cCgr2DGe9Wj9U-vbi1ZELrW4LY3BFl0ZUOZ3l9s9OWXCPmaE_92CJ5YulYvhfbQj6NQzsaLKJNFi07WhaZOvgXxKihcf3Lkueh9oOePZ-NKxXtRPN3aJR3w9ME5tsoZdgsRiQxPZBAt3pnyyPk4muySg1ofP80cX8mndGmLbdYMFhTvfDEC7pFAuH9BE3Nb0yyH2eRvU_NCsT0hFVZd1jyiWgeWncedr1DkeLqOOpfYD_RBy-HyXOJTE9w6VCehqh-GlkD4wsS6OkhJ-205pP9An7dx4yhFfw1XM7rBo197hPl_X2npHhNtaxTGsO2bq6wGllRZ9qxKR3GIHNAGk9vaqHtACjbKkPgq2fdU5KVYyKpeiXIiFHOFyPE_TdDwXqRgdlwWfTKaIc7koZ9OimIp9VmR5OscFTxdZVo7UkqdcjMfjaSrS8WSciJQvMon7sphm-XS2YJMUK6l0QrSSWHcYRblZzrkQk5GWOWofX2A5N_iz0yLO6X3WLSMV5c3Bs0mqicLPKEEFjeeXW8bn_uur7XlwG5zXT-te20HgPGf5UeP08re5MXrr48utEJN_BwAA__9sCacO">