Skip to content

Commit

Permalink
add a direct dlsym test
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Oct 6, 2023
1 parent 6249e1f commit 9026be9
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
8 changes: 5 additions & 3 deletions src/tools/miri/src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ use shims::unix::macos::foreign_items as macos;

fn is_dyn_sym(name: &str, target_os: &str) -> bool {
match name {
// `signal` is set up as a weak symbol in `init_extern_statics` so we might as well allow it
// in `dlsym` as well.
// Used for tests.
"isatty" => true,
// `signal` is set up as a weak symbol in `init_extern_statics` (on Android) so we might as
// well allow it in `dlsym`.
"signal" => true,
// Give specific OSes a chance to allow their symbols.
_ =>
Expand Down Expand Up @@ -588,7 +590,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"getuid"
if this.frame_in_std() => {
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
// FOr now, just pretend we always have this fixed UID.
// For now, just pretend we always have this fixed UID.
this.write_int(super::UID, dest)?;
}

Expand Down
35 changes: 19 additions & 16 deletions src/tools/miri/src/shims/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub trait FileDescriptor: std::fmt::Debug + Any {

fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>>;

fn is_tty(&self) -> bool {
fn is_tty(&self, _communicate_allowed: bool) -> bool {
false
}

Expand Down Expand Up @@ -156,8 +156,8 @@ impl FileDescriptor for FileHandle {
Some(self.file.as_raw_fd())
}

fn is_tty(&self) -> bool {
self.file.is_terminal()
fn is_tty(&self, communicate_allowed: bool) -> bool {
communicate_allowed && self.file.is_terminal()
}
}

Expand Down Expand Up @@ -188,8 +188,8 @@ impl FileDescriptor for io::Stdin {
Some(libc::STDIN_FILENO)
}

fn is_tty(&self) -> bool {
self.is_terminal()
fn is_tty(&self, communicate_allowed: bool) -> bool {
communicate_allowed && self.is_terminal()
}
}

Expand Down Expand Up @@ -225,8 +225,8 @@ impl FileDescriptor for io::Stdout {
Some(libc::STDOUT_FILENO)
}

fn is_tty(&self) -> bool {
self.is_terminal()
fn is_tty(&self, communicate_allowed: bool) -> bool {
communicate_allowed && self.is_terminal()
}
}

Expand Down Expand Up @@ -255,8 +255,8 @@ impl FileDescriptor for io::Stderr {
Some(libc::STDERR_FILENO)
}

fn is_tty(&self) -> bool {
self.is_terminal()
fn is_tty(&self, communicate_allowed: bool) -> bool {
communicate_allowed && self.is_terminal()
}
}

Expand Down Expand Up @@ -1721,15 +1721,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let this = self.eval_context_mut();
// "returns 1 if fd is an open file descriptor referring to a terminal;
// otherwise 0 is returned, and errno is set to indicate the error"
if matches!(this.machine.isolated_op, IsolatedOp::Allow) {
let fd = this.read_scalar(miri_fd)?.to_i32()?;
if this.machine.file_handler.handles.get(&fd).map(|fd| fd.is_tty()) == Some(true) {
let fd = this.read_scalar(miri_fd)?.to_i32()?;
let error = if let Some(fd) = this.machine.file_handler.handles.get(&fd) {
if fd.is_tty(this.machine.communicate()) {
return Ok(Scalar::from_i32(1));
} else {
this.eval_libc("ENOTTY")
}
}
// Fallback when the FD was not found or isolation is enabled.
let enotty = this.eval_libc("ENOTTY");
this.set_last_error(enotty)?;
} else {
// FD does not exist
this.eval_libc("EBADF")
};
this.set_last_error(error)?;
Ok(Scalar::from_i32(0))
}

Expand Down
14 changes: 14 additions & 0 deletions src/tools/miri/tests/pass-dep/shims/libc-misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![feature(io_error_more)]

use std::fs::{remove_file, File};
use std::mem::transmute;
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;

Expand Down Expand Up @@ -375,6 +376,18 @@ fn test_sigrt() {
assert!(max - min >= 8)
}

fn test_dlsym() {
let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"notasymbol\0".as_ptr().cast()) };
assert!(addr as usize == 0);

let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"isatty\0".as_ptr().cast()) };
assert!(addr as usize != 0);
let isatty: extern "C" fn(i32) -> i32 = unsafe { transmute(addr) };
assert_eq!(isatty(999), 0);
let errno = std::io::Error::last_os_error().raw_os_error().unwrap();
assert_eq!(errno, libc::EBADF);
}

fn main() {
test_posix_gettimeofday();
test_posix_mkstemp();
Expand All @@ -387,6 +400,7 @@ fn main() {

test_isatty();
test_clocks();
test_dlsym();

test_memcpy();
test_strcpy();
Expand Down

0 comments on commit 9026be9

Please sign in to comment.