Skip to content

Commit 4587c7c

Browse files
committed
Auto merge of #3109 - RalfJung:dlsym, r=RalfJung
add a direct dlsym test
2 parents 4135408 + 03a03e2 commit 4587c7c

File tree

3 files changed

+38
-19
lines changed

3 files changed

+38
-19
lines changed

src/tools/miri/src/shims/unix/foreign_items.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ use shims::unix::macos::foreign_items as macos;
2222

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

src/tools/miri/src/shims/unix/fs.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub trait FileDescriptor: std::fmt::Debug + Any {
6363

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

66-
fn is_tty(&self) -> bool {
66+
fn is_tty(&self, _communicate_allowed: bool) -> bool {
6767
false
6868
}
6969

@@ -156,8 +156,8 @@ impl FileDescriptor for FileHandle {
156156
Some(self.file.as_raw_fd())
157157
}
158158

159-
fn is_tty(&self) -> bool {
160-
self.file.is_terminal()
159+
fn is_tty(&self, communicate_allowed: bool) -> bool {
160+
communicate_allowed && self.file.is_terminal()
161161
}
162162
}
163163

@@ -188,8 +188,8 @@ impl FileDescriptor for io::Stdin {
188188
Some(libc::STDIN_FILENO)
189189
}
190190

191-
fn is_tty(&self) -> bool {
192-
self.is_terminal()
191+
fn is_tty(&self, communicate_allowed: bool) -> bool {
192+
communicate_allowed && self.is_terminal()
193193
}
194194
}
195195

@@ -225,8 +225,8 @@ impl FileDescriptor for io::Stdout {
225225
Some(libc::STDOUT_FILENO)
226226
}
227227

228-
fn is_tty(&self) -> bool {
229-
self.is_terminal()
228+
fn is_tty(&self, communicate_allowed: bool) -> bool {
229+
communicate_allowed && self.is_terminal()
230230
}
231231
}
232232

@@ -255,8 +255,8 @@ impl FileDescriptor for io::Stderr {
255255
Some(libc::STDERR_FILENO)
256256
}
257257

258-
fn is_tty(&self) -> bool {
259-
self.is_terminal()
258+
fn is_tty(&self, communicate_allowed: bool) -> bool {
259+
communicate_allowed && self.is_terminal()
260260
}
261261
}
262262

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

src/tools/miri/tests/pass-dep/shims/libc-misc.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![feature(io_error_more)]
44

55
use std::fs::{remove_file, File};
6+
use std::mem::transmute;
67
use std::os::unix::io::AsRawFd;
78
use std::path::PathBuf;
89

@@ -375,6 +376,18 @@ fn test_sigrt() {
375376
assert!(max - min >= 8)
376377
}
377378

379+
fn test_dlsym() {
380+
let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"notasymbol\0".as_ptr().cast()) };
381+
assert!(addr as usize == 0);
382+
383+
let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"isatty\0".as_ptr().cast()) };
384+
assert!(addr as usize != 0);
385+
let isatty: extern "C" fn(i32) -> i32 = unsafe { transmute(addr) };
386+
assert_eq!(isatty(999), 0);
387+
let errno = std::io::Error::last_os_error().raw_os_error().unwrap();
388+
assert_eq!(errno, libc::EBADF);
389+
}
390+
378391
fn main() {
379392
test_posix_gettimeofday();
380393
test_posix_mkstemp();
@@ -387,6 +400,7 @@ fn main() {
387400

388401
test_isatty();
389402
test_clocks();
403+
test_dlsym();
390404

391405
test_memcpy();
392406
test_strcpy();

0 commit comments

Comments
 (0)