diff options
| author | tiif <pekyuan@gmail.com> | 2024-08-23 21:23:09 +0800 |
|---|---|---|
| committer | tiif <pekyuan@gmail.com> | 2024-08-24 18:13:49 +0800 |
| commit | 14f22c6e66b75aab02fc2a50ce18f1af638050ec (patch) | |
| tree | 986824715a09aa856a19789a0cd444c8174de4b1 | |
| parent | b8c02eb11eaac24e56ef718040eb83c304125ac6 (diff) | |
| download | rust-14f22c6e66b75aab02fc2a50ce18f1af638050ec.tar.gz rust-14f22c6e66b75aab02fc2a50ce18f1af638050ec.zip | |
epoll: Add EINVAL case
| -rw-r--r-- | src/tools/miri/src/shims/unix/linux/epoll.rs | 7 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass-dep/libc/libc-epoll.rs | 14 |
2 files changed, 21 insertions, 0 deletions
diff --git a/src/tools/miri/src/shims/unix/linux/epoll.rs b/src/tools/miri/src/shims/unix/linux/epoll.rs index fb1e0afdf9e..ea430fec593 100644 --- a/src/tools/miri/src/shims/unix/linux/epoll.rs +++ b/src/tools/miri/src/shims/unix/linux/epoll.rs @@ -251,6 +251,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_unsup_format!("epoll_ctl: encountered unknown unsupported operation {:#x}", op); } + // Throw EINVAL if epfd and fd have the same value. + if epfd_value == fd { + let einval = this.eval_libc("EINVAL"); + this.set_last_error(einval)?; + return Ok(Scalar::from_i32(-1)); + } + // Check if epfd is a valid epoll file descriptor. let Some(epfd) = this.machine.fds.get(epfd_value) else { return Ok(Scalar::from_i32(this.fd_not_found()?)); diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs index 052ce73de23..7b8acbd1200 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs @@ -21,6 +21,7 @@ fn main() { test_socketpair_epollerr(); test_epoll_lost_events(); test_ready_list_fetching_logic(); + test_epoll_ctl_epfd_equal_fd(); } // Using `as` cast since `EPOLLET` wraps around @@ -630,3 +631,16 @@ fn test_ready_list_fetching_logic() { let expected_value1 = fd1 as u64; check_epoll_wait::<1>(epfd, &[(expected_event1, expected_value1)]); } + +// In epoll_ctl, if the value of epfd equals to fd, EINVAL should be returned. +fn test_epoll_ctl_epfd_equal_fd() { + // Create an epoll instance. + let epfd = unsafe { libc::epoll_create1(0) }; + assert_ne!(epfd, -1); + + let array_ptr = std::ptr::without_provenance_mut::<libc::epoll_event>(0x100); + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, epfd, array_ptr) }; + let e = std::io::Error::last_os_error(); + assert_eq!(e.raw_os_error(), Some(libc::EINVAL)); + assert_eq!(res, -1); +} |
