@@ -23,6 +23,7 @@ fn main() {
23
23
test_ready_list_fetching_logic ( ) ;
24
24
test_epoll_ctl_epfd_equal_fd ( ) ;
25
25
test_epoll_ctl_notification ( ) ;
26
+ test_issue_3858 ( ) ;
26
27
}
27
28
28
29
// Using `as` cast since `EPOLLET` wraps around
@@ -683,3 +684,40 @@ fn test_epoll_ctl_notification() {
683
684
// for this epfd, because there is no I/O event between the two epoll_wait.
684
685
check_epoll_wait :: < 1 > ( epfd0, & [ ] ) ;
685
686
}
687
+
688
+ // Test for ICE caused by weak epoll interest upgrade succeed, but the attempt to retrieve
689
+ // the epoll instance based on the epoll file descriptor value failed. EpollEventInterest
690
+ // should store a WeakFileDescriptionRef instead of the file descriptor number, so if the
691
+ // epoll instance is duped, it'd still be usable after `close` is called on the original
692
+ // epoll file descriptor.
693
+ // https://github.com/rust-lang/miri/issues/3858
694
+ fn test_issue_3858 ( ) {
695
+ // Create an eventfd instance.
696
+ let flags = libc:: EFD_NONBLOCK | libc:: EFD_CLOEXEC ;
697
+ let fd = unsafe { libc:: eventfd ( 0 , flags) } ;
698
+
699
+ // Create an epoll instance.
700
+ let epfd = unsafe { libc:: epoll_create1 ( 0 ) } ;
701
+ assert_ne ! ( epfd, -1 ) ;
702
+
703
+ // Register eventfd with EPOLLIN | EPOLLET.
704
+ let mut ev = libc:: epoll_event {
705
+ events : ( libc:: EPOLLIN | libc:: EPOLLET ) as _ ,
706
+ u64 : u64:: try_from ( fd) . unwrap ( ) ,
707
+ } ;
708
+ let res = unsafe { libc:: epoll_ctl ( epfd, libc:: EPOLL_CTL_ADD , fd, & mut ev) } ;
709
+ assert_eq ! ( res, 0 ) ;
710
+
711
+ // Dup the epoll instance.
712
+ let newfd = unsafe { libc:: dup ( epfd) } ;
713
+ assert_ne ! ( newfd, -1 ) ;
714
+
715
+ // Close the old epoll instance, so the new FD is now the only FD.
716
+ let res = unsafe { libc:: close ( epfd) } ;
717
+ assert_eq ! ( res, 0 ) ;
718
+
719
+ // Write to the eventfd instance.
720
+ let sized_8_data: [ u8 ; 8 ] = 1_u64 . to_ne_bytes ( ) ;
721
+ let res = unsafe { libc:: write ( fd, sized_8_data. as_ptr ( ) as * const libc:: c_void , 8 ) } ;
722
+ assert_eq ! ( res, 8 ) ;
723
+ }
0 commit comments