Skip to content

Commit a2af0ea

Browse files
ayushr2gvisor-bot
authored andcommitted
eventfd: writes must be exactly 8 bytes
Linux 6.9+ enforces that writes to eventfd must be exactly 8 bytes. Previously, Linux allowed writes larger than 8 bytes, ignoring the extra input. See commit d31563b5f9bb "eventfd: strictly check the count parameter of eventfd_write to avoid inputting illegal strings" PiperOrigin-RevId: 824690963
1 parent bcdd0d0 commit a2af0ea

File tree

2 files changed

+10
-14
lines changed

2 files changed

+10
-14
lines changed

pkg/sentry/fsimpl/eventfd/eventfd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func (efd *EventFileDescription) Read(ctx context.Context, dst usermem.IOSequenc
164164

165165
// Write implements vfs.FileDescriptionImpl.Write.
166166
func (efd *EventFileDescription) Write(ctx context.Context, src usermem.IOSequence, _ vfs.WriteOptions) (int64, error) {
167-
if src.NumBytes() < 8 {
167+
if src.NumBytes() != 8 {
168168
return 0, unix.EINVAL
169169
}
170170
if err := efd.write(ctx, src); err != nil {

test/syscalls/linux/eventfd.cc

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,19 @@ TEST(EventfdTest, IllegalPwrite) {
120120
EXPECT_THAT(pwrite(efd.get(), "x", 1, 0), SyscallFailsWithErrno(ESPIPE));
121121
}
122122

123-
TEST(EventfdTest, BigWrite) {
123+
TEST(EventfdTest, BigWriteFails) {
124+
// Starting Linux 6.9, big writes fail. gVisor has the newer behavior.
125+
if (!IsRunningOnGvisor()) {
126+
auto version = ASSERT_NO_ERRNO_AND_VALUE(GetKernelVersion());
127+
SKIP_IF(version.major < 6 || (version.major == 6 && version.minor < 9));
128+
}
124129
FileDescriptor efd =
125130
ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE));
126131

127132
uint64_t big[16];
128133
big[0] = 16;
129-
ASSERT_THAT(write(efd.get(), big, sizeof(big)), SyscallSucceeds());
134+
ASSERT_THAT(write(efd.get(), big, sizeof(big)),
135+
SyscallFailsWithErrno(EINVAL));
130136
}
131137

132138
TEST(EventfdTest, BigRead) {
@@ -136,22 +142,12 @@ TEST(EventfdTest, BigRead) {
136142
uint64_t l = 1;
137143
ASSERT_THAT(write(efd.get(), &l, sizeof(l)), SyscallSucceeds());
138144

145+
// As of writing, big reads are allowed on Linux while big writes are not.
139146
uint64_t big[16];
140147
ASSERT_THAT(read(efd.get(), big, sizeof(big)), SyscallSucceeds());
141148
EXPECT_EQ(big[0], 1);
142149
}
143150

144-
TEST(EventfdTest, BigWriteBigRead) {
145-
FileDescriptor efd =
146-
ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE));
147-
148-
uint64_t l[16];
149-
l[0] = 16;
150-
ASSERT_THAT(write(efd.get(), l, sizeof(l)), SyscallSucceeds());
151-
ASSERT_THAT(read(efd.get(), l, sizeof(l)), SyscallSucceeds());
152-
EXPECT_EQ(l[0], 1);
153-
}
154-
155151
TEST(EventfdTest, NotifyNonZero) {
156152
// Waits will time out at 10 seconds.
157153
constexpr int kEpollTimeoutMs = 10000;

0 commit comments

Comments
 (0)