Skip to content

Commit 3a9e63c

Browse files
committed
Auto merge of #3836 - tiif:einval_ctl, r=oli-obk
epoll: Add a EINVAL case In ``epoll_ctl`` documentation, it is mentioned that: > EINVAL epfd is not an epoll file descriptor, or fd is the same as epfd, or the requested operation op is not supported by this interface. So I added this EINVAL case for ``epfd == fd`` in ``epoll_ctl``
2 parents 17659eb + 14f22c6 commit 3a9e63c

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

src/tools/miri/src/shims/unix/linux/epoll.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
251251
throw_unsup_format!("epoll_ctl: encountered unknown unsupported operation {:#x}", op);
252252
}
253253

254+
// Throw EINVAL if epfd and fd have the same value.
255+
if epfd_value == fd {
256+
let einval = this.eval_libc("EINVAL");
257+
this.set_last_error(einval)?;
258+
return Ok(Scalar::from_i32(-1));
259+
}
260+
254261
// Check if epfd is a valid epoll file descriptor.
255262
let Some(epfd) = this.machine.fds.get(epfd_value) else {
256263
return Ok(Scalar::from_i32(this.fd_not_found()?));

src/tools/miri/tests/pass-dep/libc/libc-epoll.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ fn main() {
2121
test_socketpair_epollerr();
2222
test_epoll_lost_events();
2323
test_ready_list_fetching_logic();
24+
test_epoll_ctl_epfd_equal_fd();
2425
}
2526

2627
// Using `as` cast since `EPOLLET` wraps around
@@ -630,3 +631,16 @@ fn test_ready_list_fetching_logic() {
630631
let expected_value1 = fd1 as u64;
631632
check_epoll_wait::<1>(epfd, &[(expected_event1, expected_value1)]);
632633
}
634+
635+
// In epoll_ctl, if the value of epfd equals to fd, EINVAL should be returned.
636+
fn test_epoll_ctl_epfd_equal_fd() {
637+
// Create an epoll instance.
638+
let epfd = unsafe { libc::epoll_create1(0) };
639+
assert_ne!(epfd, -1);
640+
641+
let array_ptr = std::ptr::without_provenance_mut::<libc::epoll_event>(0x100);
642+
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, epfd, array_ptr) };
643+
let e = std::io::Error::last_os_error();
644+
assert_eq!(e.raw_os_error(), Some(libc::EINVAL));
645+
assert_eq!(res, -1);
646+
}

0 commit comments

Comments
 (0)