[Git][ghc/ghc][wip/dcoutts/io-manager-tidy] 2 commits: In select I/O manager, ensure wakeup fds are within range
Duncan Coutts pushed to branch wip/dcoutts/io-manager-tidy at Glasgow Haskell Compiler / GHC Commits: 0cd74e31 by Duncan Coutts at 2026-07-16T21:21:04+01:00 In select I/O manager, ensure wakeup fds are within range It could plausibly happen that if the RTS is used within another process that already has many open fds, that the new fds returned by newFdWakeup are out of bounds for select. - - - - - 95d7e7e5 by Duncan Coutts at 2026-07-16T21:23:33+01:00 Be more explicit about enum IOReadOrWrite values, and type within cmm Belt and braces. - - - - - 3 changed files: - rts/IOManager.h - rts/PrimOps.cmm - rts/posix/Select.c Changes: ===================================== rts/IOManager.h ===================================== @@ -319,7 +319,7 @@ void scavengeTSOIOManager(StgTSO *tso); /* Several code paths are almost identical between read and write paths. In * such cases we use a shared code path with an enum to say which we're doing. */ -typedef enum { IORead, IOWrite } IOReadOrWrite; +typedef enum { IORead = 0, IOWrite = 1 } IOReadOrWrite; /* Synchronous operations: I/O and delays. As synchronous operations they * necessarily operate on threads. The thread is suspended until the operation ===================================== rts/PrimOps.cmm ===================================== @@ -2269,7 +2269,7 @@ stg_waitReadzh ( W_ fd ) (ok) = ccall syncIOWaitReady(Capability_iomgr(MyCapability()) "ptr", CurrentTSO "ptr", - /* IORead */ 0::I32, fd); + /* IORead */ 0::CInt, fd); if (ok != 0::CBool) (likely: True) { jump stg_block_noregs(); } else { ===================================== rts/posix/Select.c ===================================== @@ -63,6 +63,14 @@ void initCapabilityIOManagerSelect(CapIOManager *iomgr) #if defined(HAVE_PREEMPTION) newFdWakeup(&iomgr->interrupt_fd_r, &iomgr->interrupt_fd_w); + + /* Would never happen in a standalone process, but could plausibly happen + * if the RTS is used within another process that already has many open fds. + */ + if (iomgr->interrupt_fd_r < 0 || iomgr->interrupt_fd_r >= (int)FD_SETSIZE || + iomgr->interrupt_fd_w < 0 || iomgr->interrupt_fd_w >= (int)FD_SETSIZE) { + barf("initCapabilityIOManagerSelect: fds out of select range"); + } #endif } @@ -284,6 +292,7 @@ awaitCompletedTimeoutsOrIOSelect(CapIOManager *iomgr, bool wait) { int fd = iomgr->interrupt_fd_r; maxfd = (fd > maxfd) ? fd : maxfd; + ASSERT(fd >= 0 && fd < (int)FD_SETSIZE); // checked during init FD_SET(fd, &rfd); } #endif View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c0393a7c97b4d16b14be8368fd420b8... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c0393a7c97b4d16b14be8368fd420b8... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Duncan Coutts (@dcoutts)