Skip to content

Commit

Permalink
Trying to fix #1753
Browse files Browse the repository at this point in the history
  • Loading branch information
domenukk committed Dec 22, 2023
1 parent 44caffa commit e148e6e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 34 deletions.
31 changes: 21 additions & 10 deletions libafl/src/events/launcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,16 @@ where
/// A file name to write all client output to
#[builder(default = None)]
stdout_file: Option<&'a str>,
/// The actual, opened, stdout_file - so that we keep it open until the end
#[builder(setter(skip), default = None)]
opened_stdout_file: Option<File>,
/// A file name to write all client stderr output to. If not specified, output is sent to
/// `stdout_file`.
#[builder(default = None)]
stderr_file: Option<&'a str>,
/// The actual, opened, stdout_file - so that we keep it open until the end
#[builder(setter(skip), default = None)]
opened_stderr_file: Option<File>,
/// The `ip:port` address of another broker to connect our new broker to for multi-machine
/// clusters.
#[builder(default = None)]
Expand Down Expand Up @@ -166,12 +172,10 @@ where

log::info!("spawning on cores: {:?}", self.cores);

#[cfg(feature = "std")]
let stdout_file = self
self.opened_stdout_file = self
.stdout_file
.map(|filename| File::create(filename).unwrap());
#[cfg(feature = "std")]
let stderr_file = self
self.opened_stderr_file = self
.stderr_file
.map(|filename| File::create(filename).unwrap());

Expand Down Expand Up @@ -204,9 +208,9 @@ where

#[cfg(feature = "std")]
if !debug_output {
if let Some(file) = stdout_file {
if let Some(file) = &self.opened_stdout_file {
dup2(file.as_raw_fd(), libc::STDOUT_FILENO)?;
if let Some(stderr) = stderr_file {
if let Some(stderr) = &self.opened_stderr_file {
dup2(stderr.as_raw_fd(), libc::STDERR_FILENO)?;
} else {
dup2(file.as_raw_fd(), libc::STDERR_FILENO)?;
Expand Down Expand Up @@ -423,12 +427,19 @@ where
/// A file name to write all client output to
#[builder(default = None)]
stdout_file: Option<&'a str>,
/// The actual, opened, stdout_file - so that we keep it open until the end
#[builder(setter(skip), default = None)]
opened_stdout_file: Option<File>,
/// A file name to write all client stderr output to. If not specified, output is sent to
/// `stdout_file`.
#[builder(default = None)]
stderr_file: Option<&'a str>,
/// The actual, opened, stdout_file - so that we keep it open until the end
#[builder(setter(skip), default = None)]
opened_stderr_file: Option<File>,
/// The `ip:port` address of another broker to connect our new broker to for multi-machine
/// clusters.
#[builder(default = None)]
remote_broker_addr: Option<SocketAddr>,
/// If this launcher should spawn a new `broker` on `[Self::broker_port]` (default).
Expand Down Expand Up @@ -503,10 +514,10 @@ where

log::info!("spawning on cores: {:?}", self.cores);

let stdout_file = self
self.opened_stdout_file = self
.stdout_file
.map(|filename| File::create(filename).unwrap());
let stderr_file = self
self.opened_stderr_file = self
.stderr_file
.map(|filename| File::create(filename).unwrap());

Expand Down Expand Up @@ -556,9 +567,9 @@ where
std::thread::sleep(std::time::Duration::from_millis(index * 10));

if !debug_output {
if let Some(file) = stdout_file {
if let Some(file) = &self.opened_stdout_file {
dup2(file.as_raw_fd(), libc::STDOUT_FILENO)?;
if let Some(stderr) = stderr_file {
if let Some(stderr) = &self.opened_stderr_file {
dup2(stderr.as_raw_fd(), libc::STDERR_FILENO)?;
} else {
dup2(file.as_raw_fd(), libc::STDERR_FILENO)?;
Expand Down
20 changes: 13 additions & 7 deletions libafl_bolts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ extern crate std;
#[macro_use]
#[doc(hidden)]
pub extern crate alloc;
use alloc::boxed::Box;

#[cfg(feature = "ctor")]
#[doc(hidden)]
Expand Down Expand Up @@ -161,14 +160,14 @@ pub mod bolts_prelude {
pub use super::{cpu::*, os::*};
}

#[cfg(all(unix, feature = "std"))]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(all(not(feature = "xxh3"), feature = "alloc"))]
use core::hash::BuildHasher;
#[cfg(any(feature = "xxh3", feature = "alloc"))]
use core::hash::Hasher;
use log::SetLoggerError;
use std::panic;
#[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(all(unix, feature = "std"))]
Expand All @@ -177,12 +176,14 @@ use std::{
io::{stderr, stdout, Write},
mem,
os::fd::{AsRawFd, FromRawFd, RawFd},
panic,
};

// There's a bug in ahash that doesn't let it build in `alloc` without once_cell right now.
// TODO: re-enable once <https://github.com/tkaitchuck/aHash/issues/155> is resolved.
#[cfg(all(not(feature = "xxh3"), feature = "alloc"))]
use ahash::RandomState;
use log::SetLoggerError;
use serde::{Deserialize, Serialize};
#[cfg(feature = "xxh3")]
use xxhash_rust::xxh3::xxh3_64;
Expand Down Expand Up @@ -575,6 +576,7 @@ impl From<TryFromSliceError> for Error {
}

impl From<SetLoggerError> for Error {
#[allow(unused_variables)]
fn from(err: SetLoggerError) -> Self {
Self::illegal_state(format!("Failed to register logger: {err:?}"))
}
Expand Down Expand Up @@ -972,23 +974,27 @@ impl log::Log for SimpleFdLogger {
///
/// # Safety
/// The function is arguably safe, but it might have undesirable side effects since it closes `stdout` and `stderr`.
#[cfg(unix)]
pub unsafe fn mute_inprocess_target() -> Result<(RawFd, RawFd), Error> {
#[cfg(all(unix, feature = "std"))]
pub unsafe fn dup_and_mute_outputs() -> Result<(RawFd, RawFd), Error> {
let old_stdout = stdout().as_raw_fd();
let old_stderr = stderr().as_raw_fd();
let null_fd = crate::os::null_fd()?;

let new_stdout = crate::os::dup(old_stdout)?;

let new_stderr = crate::os::dup(old_stderr)?;

let null_fd = crate::os::null_fd()?;
crate::os::dup2(null_fd, old_stdout)?;
crate::os::dup2(null_fd, old_stderr)?;

Ok((new_stdout, new_stderr))
}

/// Set up an error print hook that will
///
/// # Safety
/// Will fail if `new_stderr` is not a valid file descriptor.
/// May not be called multiple times concurrently.
#[cfg(all(unix, feature = "std"))]
pub unsafe fn set_error_print_panic_hook(new_stderr: RawFd) {
// Make sure potential errors get printed to the correct (non-closed) stderr
panic::set_hook(Box::new(move |panic_info| {
Expand Down
5 changes: 3 additions & 2 deletions libafl_bolts/src/os/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
//!
#[cfg(feature = "std")]
use std::{env, process::Command};
use std::{fs::File, os::fd::AsRawFd, sync::OnceLock};
use std::{env, fs::File, os::fd::AsRawFd, process::Command, sync::OnceLock};

#[cfg(any(unix, all(windows, feature = "std")))]
use crate::Error;
Expand Down Expand Up @@ -33,6 +32,7 @@ pub mod windows_exceptions;
use libc::pid_t;

/// A file that we keep open, pointing to /dev/null
#[cfg(all(feature = "std", unix))]
static NULL_FILE: OnceLock<File> = OnceLock::new();

/// Child Process Handle
Expand Down Expand Up @@ -136,6 +136,7 @@ pub fn last_error_str<'a>() -> Option<Cow<'a, str>> {
}

/// Get a file descriptor ([`RawFd`]) pointing to "/dev/null"
#[cfg(all(unix, feature = "std"))]
pub fn null_fd() -> Result<RawFd, Error> {
// We don't care about opening the file twice here - races are ok.
if let Some(file) = NULL_FILE.get() {
Expand Down
29 changes: 14 additions & 15 deletions libafl_libfuzzer/libafl_libfuzzer_runtime/src/fuzz.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use core::ffi::c_int;
#[cfg(unix)]
use std::io::Write;
use std::io::{stderr, stdout, Write};
use std::{
fmt::Debug,
fs::File,
net::TcpListener,
os::fd::AsRawFd,
str::FromStr,
time::{SystemTime, UNIX_EPOCH},
};
Expand Down Expand Up @@ -35,23 +36,21 @@ use crate::{feedbacks::LibfuzzerCrashCauseMetadata, fuzz_with, options::Libfuzze
fn destroy_output_fds(options: &LibfuzzerOptions) {
#[cfg(unix)]
{
use std::os::fd::AsRawFd;
use libafl_bolts::os::{dup2, null_fd};

let null_fd = null_fd().unwrap();
let stdout_fd = stdout().as_raw_fd();
let stderr_fd = stderr().as_raw_fd();

if options.tui() {
let file_null = File::open("/dev/null").unwrap();
unsafe {
libc::dup2(file_null.as_raw_fd(), 1);
libc::dup2(file_null.as_raw_fd(), 2);
}
dup2(null_fd, stdout_fd).unwrap();
dup2(null_fd, stderr_fd).unwrap();
} else if options.close_fd_mask() != 0 {
let file_null = File::open("/dev/null").unwrap();
unsafe {
if options.close_fd_mask() & 1 != 0 {
libc::dup2(file_null.as_raw_fd(), 1);
}
if options.close_fd_mask() & 2 != 0 {
libc::dup2(file_null.as_raw_fd(), 2);
}
if options.close_fd_mask() & u8::try_from(stderr_fd).unwrap() != 0 {
dup2(null_fd, stdout_fd).unwrap();
}
if options.close_fd_mask() & u8::try_from(stderr_fd).unwrap() != 0 {
dup2(null_fd, stderr_fd).unwrap();
}
}
}
Expand Down

0 comments on commit e148e6e

Please sign in to comment.