Skip to content

Commit c3a8ee0

Browse files
committed
Fail attempt: Hard to give FileDescriptor::close ecx access
1 parent 30c00a2 commit c3a8ee0

File tree

5 files changed

+31
-4
lines changed

5 files changed

+31
-4
lines changed

src/shims/unix/fd.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
5151

5252
fn close<'tcx>(
5353
self: Box<Self>,
54+
_ecx: &mut MiriInterpCx<'tcx>,
5455
_communicate_allowed: bool,
5556
) -> InterpResult<'tcx, io::Result<()>> {
5657
throw_unsup_format!("cannot close {}", self.name());
@@ -197,11 +198,13 @@ impl FileDescriptor {
197198
RefMut::map(self.0.borrow_mut(), |fd| fd.as_mut())
198199
}
199200

200-
pub fn close<'ctx>(self, communicate_allowed: bool) -> InterpResult<'ctx, io::Result<()>> {
201+
pub fn close<'ctx>(self,
202+
ecx: &mut MiriInterpCx<'tcx>,
203+
communicate_allowed: bool) -> InterpResult<'ctx, io::Result<()>> {
201204
// Destroy this `Rc` using `into_inner` so we can call `close` instead of
202205
// implicitly running the destructor of the file description.
203206
match Rc::into_inner(self.0) {
204-
Some(fd) => RefCell::into_inner(fd).close(communicate_allowed),
207+
Some(fd) => RefCell::into_inner(fd).close(ecx, communicate_allowed),
205208
None => Ok(Ok(())),
206209
}
207210
}

src/shims/unix/fs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl FileDescription for FileHandle {
6060

6161
fn close<'tcx>(
6262
self: Box<Self>,
63+
_ecx: &mut MiriInterpCx<'tcx>,
6364
communicate_allowed: bool,
6465
) -> InterpResult<'tcx, io::Result<()>> {
6566
assert!(communicate_allowed, "isolation should have prevented even opening a file");

src/shims/unix/linux/epoll.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ impl FileDescription for Epoll {
8888

8989
fn close<'tcx>(
9090
self: Box<Self>,
91+
_ecx: &mut MiriInterpCx<'tcx>,
9192
_communicate_allowed: bool,
9293
) -> InterpResult<'tcx, io::Result<()>> {
9394
Ok(Ok(()))

src/shims/unix/linux/eventfd.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ impl FileDescription for Event {
6262
}
6363
fn close<'tcx>(
6464
self: Box<Self>,
65+
_ecx: &mut MiriInterpCx<'tcx>,
6566
_communicate_allowed: bool,
6667
) -> InterpResult<'tcx, io::Result<()>> {
6768
Ok(Ok(()))

src/shims/unix/socket.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ struct SocketPair {
2525
readbuf: Rc<RefCell<Buffer>>,
2626
peer_fd: Weak<WeakFileDescriptor>,
2727
is_nonblock: bool,
28+
peer_closed: bool,
2829
epoll_events: Vec<Weak<EpollEvent>>,
2930
}
3031

3132
impl SocketPair {
3233
fn add_peer_fd(&mut self, fd: Weak<WeakFileDescriptor>) {
3334
self.peer_fd = fd;
3435
}
36+
37+
fn peer_is_closed(&mut self) {
38+
self.peer_closed = true;
39+
}
3540
}
3641

3742
#[derive(Debug)]
@@ -80,20 +85,34 @@ impl FileDescription for SocketPair {
8085
ready_flags.push(epollout);
8186
}
8287
}
88+
8389
Ok(ready_flags)
8490
}
8591

8692
fn close<'tcx>(
8793
self: Box<Self>,
94+
ecx: &mut MiriInterpCx<'tcx>,
8895
_communicate_allowed: bool,
8996
) -> InterpResult<'tcx, io::Result<()>> {
9097
// This is used to signal socketfd of other side that there is no writer to its readbuf.
9198
// If the upgrade fails, there is no need to update as all read ends have been dropped.
9299
if let Some(writebuf) = self.writebuf.upgrade() {
93100
writebuf.borrow_mut().buf_has_writer = false;
94101
};
95-
// TODO: how to notify another file description from here? We only have access to
96-
// current file description.
102+
103+
// Notify peer fd that closed has happened.
104+
if let Some(peer_fd) = self.peer_fd.upgrade() {
105+
if let Some(file_description) = peer_fd.get_file_description() {
106+
let mut binding = file_description.borrow_mut();
107+
let peer_socketpair = binding.downcast_mut::<SocketPair>().unwrap();
108+
peer_socketpair.peer_is_closed();
109+
// When any of the event is happened, we check and update the status of all supported flags.
110+
peer_socketpair
111+
.check_readiness(ecx)
112+
.map(|events| ecx.update_readiness(events, self.return_epoll_events()?))??;
113+
}
114+
}
115+
// TODO: invoke check readiness from other side
97116
Ok(Ok(()))
98117
}
99118

@@ -264,13 +283,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
264283
writebuf: Rc::downgrade(&buffer1),
265284
readbuf: Rc::clone(&buffer2),
266285
peer_fd: Weak::new(),
286+
peer_closed: false,
267287
is_nonblock: is_sock_nonblock,
268288
epoll_events: Vec::new(),
269289
};
270290
let socketpair_1 = SocketPair {
271291
writebuf: Rc::downgrade(&buffer2),
272292
readbuf: Rc::clone(&buffer1),
273293
peer_fd: Weak::new(),
294+
peer_closed: false,
274295
is_nonblock: is_sock_nonblock,
275296
epoll_events: Vec::new(),
276297
};

0 commit comments

Comments
 (0)