summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2020-07-29 14:56:14 -0700
committergVisor bot <gvisor-bot@google.com>2020-07-29 14:57:48 -0700
commit4cd4759238655e35c8dc63723f4e55014b5ea9ea (patch)
treeaffb441301d9d12f09dfd94a15543b6658447924
parent1715896fc81fce0302e790186302d7460838a918 (diff)
Force registration for EPOLLHUP, not EPOLLRDHUP, in vfs2's epoll.
Compare Linux's fs/eventpoll.c:do_epoll_ctl(). I don't know where EPOLLRDHUP came from. PiperOrigin-RevId: 323874419
-rw-r--r--pkg/sentry/vfs/epoll.go4
-rw-r--r--test/syscalls/linux/epoll.cc22
2 files changed, 24 insertions, 2 deletions
diff --git a/pkg/sentry/vfs/epoll.go b/pkg/sentry/vfs/epoll.go
index 599c3131c..5b009b928 100644
--- a/pkg/sentry/vfs/epoll.go
+++ b/pkg/sentry/vfs/epoll.go
@@ -186,7 +186,7 @@ func (ep *EpollInstance) AddInterest(file *FileDescription, num int32, event lin
}
// Register interest in file.
- mask := event.Events | linux.EPOLLERR | linux.EPOLLRDHUP
+ mask := event.Events | linux.EPOLLERR | linux.EPOLLHUP
epi := &epollInterest{
epoll: ep,
key: key,
@@ -257,7 +257,7 @@ func (ep *EpollInstance) ModifyInterest(file *FileDescription, num int32, event
}
// Update epi for the next call to ep.ReadEvents().
- mask := event.Events | linux.EPOLLERR | linux.EPOLLRDHUP
+ mask := event.Events | linux.EPOLLERR | linux.EPOLLHUP
ep.mu.Lock()
epi.mask = mask
epi.userData = event.Data
diff --git a/test/syscalls/linux/epoll.cc b/test/syscalls/linux/epoll.cc
index f57d38dc7..2101e5c9f 100644
--- a/test/syscalls/linux/epoll.cc
+++ b/test/syscalls/linux/epoll.cc
@@ -422,6 +422,28 @@ TEST(EpollTest, CloseFile) {
SyscallSucceedsWithValue(0));
}
+TEST(EpollTest, PipeReaderHupAfterWriterClosed) {
+ auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
+ int pipefds[2];
+ ASSERT_THAT(pipe(pipefds), SyscallSucceeds());
+ FileDescriptor rfd(pipefds[0]);
+ FileDescriptor wfd(pipefds[1]);
+
+ ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), rfd.get(), 0, kMagicConstant));
+ struct epoll_event result[kFDsPerEpoll];
+ // Initially, rfd should not generate any events of interest.
+ ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
+ SyscallSucceedsWithValue(0));
+ // Close the write end of the pipe.
+ wfd.reset();
+ // rfd should now generate EPOLLHUP, which EPOLL_CTL_ADD unconditionally adds
+ // to the set of events of interest.
+ ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
+ SyscallSucceedsWithValue(1));
+ EXPECT_EQ(result[0].events, EPOLLHUP);
+ EXPECT_EQ(result[0].data.u64, kMagicConstant);
+}
+
} // namespace
} // namespace testing