Skip to content

Commit e24a2e0

Browse files
authored
Merge pull request #2660 from stevenengler/epoll-ctl-check
Remove unneeded workaround in `syscallhandler_epoll_ctl`
2 parents a2161b3 + 12adcab commit e24a2e0

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed

src/main/host/descriptor/epoll.c

+17
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,23 @@ gint epoll_control(Epoll* epoll, gint operation, int fd, const Descriptor* descr
489489

490490
switch (operation) {
491491
case EPOLL_CTL_ADD: {
492+
/* Check if we're trying to add a file that's already been closed.
493+
* Typically a file that is referenced in the descriptor table
494+
* should never be a closed file, but Shadow's TCP sockets do close
495+
* themselves even if there are still file handles (see
496+
* `_tcp_endOfFileSignalled`), so we need to check this. */
497+
Status status;
498+
if (watchType == EWT_LEGACY_FILE) {
499+
status = legacyfile_getStatus(watchObject.as_legacy_file);
500+
} else if (watchType == EWT_GENERIC_FILE) {
501+
status = file_getStatus(watchObject.as_file);
502+
}
503+
if (status & STATUS_FILE_CLOSED) {
504+
warning("Attempted to add a closed file to epoll %p", epoll);
505+
rv = -EBADF;
506+
break;
507+
}
508+
492509
/* EEXIST op was EPOLL_CTL_ADD, and the supplied file descriptor
493510
* fd is already registered with this epoll instance. */
494511
if(watch) {

src/main/host/descriptor/tcp.c

+1
Original file line numberDiff line numberDiff line change
@@ -2324,6 +2324,7 @@ static void _tcp_endOfFileSignalled(TCP* tcp, enum TCPFlags flags) {
23242324

23252325
if((tcp->flags & TCPF_EOF_RD_SIGNALED) && (tcp->flags & TCPF_EOF_WR_SIGNALED)) {
23262326
/* user can no longer access socket */
2327+
/* FIXME: a file should not be closed if there are still file handles (fds) to it */
23272328
legacyfile_adjustStatus(&(tcp->super.super), STATUS_FILE_CLOSED, TRUE);
23282329
legacyfile_adjustStatus(&(tcp->super.super), STATUS_FILE_ACTIVE, FALSE);
23292330
}

src/main/host/syscall/epoll.c

+1-6
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,7 @@ SysCallReturn syscallhandler_epoll_ctl(SysCallHandler* sys,
106106
LegacyFile* legacyDescriptor = descriptor_asLegacyFile(descriptor);
107107

108108
// Make sure the child is not closed only if it's a legacy file
109-
// FIXME: for now we allow child fds to be closed on EPOLL_CTL_DEL operations,
110-
// because libevent frequently closes before issuing the EPOLL_CTL_DEL op.
111-
// Once #1101 is fixed, and we correctly clean up closed watch fds, then we can
112-
// error out here on EPOLL_CTL_DEL ops too.
113-
// See: https://github.com/shadow/shadow/issues/1101
114-
if (legacyDescriptor != NULL && op != EPOLL_CTL_DEL) {
109+
if (legacyDescriptor != NULL) {
115110
errorCode = _syscallhandler_validateLegacyFile(legacyDescriptor, DT_NONE);
116111

117112
if (errorCode) {

src/main/host/syscall/protected.c

+6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ int _syscallhandler_validateLegacyFile(LegacyFile* descriptor, LegacyFileType ex
4949
Status status = legacyfile_getStatus(descriptor);
5050

5151
if (status & STATUS_FILE_CLOSED) {
52+
// A file that is referenced in the descriptor table should never
53+
// be a closed file. File handles (fds) are handles to open files,
54+
// so if we have a file handle to a closed file, then there's an
55+
// error somewhere in Shadow. Shadow's TCP sockets do close
56+
// themselves even if there are still file handles (see
57+
// `_tcp_endOfFileSignalled`), so we can't make this a panic.
5258
warning("descriptor %p is closed", descriptor);
5359
return -EBADF;
5460
}

0 commit comments

Comments
 (0)