This is an archive of the discontinued LLVM Phabricator instance.

[libFuzzer] Avoid undefined behavior. Properly discard output to stdout and stderr.
ClosedPublic

Authored by mpividori on Jan 13 2017, 6:55 PM.

Details

Summary

fuzzer-fdmask.test was failing in Windows, when setting -close_fd_mask to a non-zero value.

I realized it was happening, because libFuzzer closes the file descriptor for stdout (1) or stderr (2) , but after that, it writes directly to stdout and stderr using the file streams stdout and stderr, which is undefined behavior. In Windows, in particular, this was making the test fail.

Instead of closing the file descriptors, I redirect the output to /dev/null on linux and nul on Windows.

Diff Detail

Repository
rL LLVM

Event Timeline

mpividori updated this revision to Diff 84412.Jan 13 2017, 6:55 PM
mpividori retitled this revision from to [libFuzzer] Avoid undefined behavior. Properly discard output to stdout and stderr..
mpividori updated this object.
mpividori added reviewers: kcc, zturner.
mpividori set the repository for this revision to rL LLVM.
mpividori added a subscriber: llvm-commits.
vitalybuka added inline comments.
lib/Fuzzer/FuzzerIOPosix.cpp
80 ↗(On Diff #84412)

Why not just use CloseFile on Posix if it works?

Hi, it is undefined behavior. It could fail.
Also, if we close stdout and we open a new file in libFuzzer, we get the file descriptor 1, which could generate problem if some code assumes file descriptors refers to stdout and works directly writing to the file descriptor 1, but it will be writing to the opened file.

For example, before this commit, if you compile this simple test function with libFuzzer and execute: ./my_fuzzer -close_fd_mask=1 , it will write to the testout file many times the message that was expected to be send to stdout.

#include <cstdint>
#include <fcntl.h>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

static volatile int Sink;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  int fd = open("testout", O_CREAT | O_WRONLY | O_APPEND);
  if (fd == -1) return 1;
  std::cout << "SOME MSG TO STDOUT, NOT TO THE FILE" << std::endl;
  close(fd);
  return 0;
}
zturner added inline comments.Jan 17 2017, 10:08 AM
lib/Fuzzer/FuzzerIOPosix.cpp
80 ↗(On Diff #84412)

I think it was just working on accident, seems like writing to a closed file descriptor is always wrong, even if you get lucky and it "works".

kcc accepted this revision.Jan 17 2017, 1:02 PM

LGTM

This revision is now accepted and ready to land.Jan 17 2017, 1:02 PM
This revision was automatically updated to reflect the committed changes.