From 44831711fcad79cb2cc6c9ac3937bc766bcce670 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Sun, 25 Jan 2026 15:42:17 +0100 Subject: [PATCH 1/3] Fix out of bounds read and write in IO.select Added error handling for file descriptors larger than FD_SETSIZE in mrb_hal_io_fdset_set and mrb_hal_io_fdset_isset functions, for posix hal. I actually don't know how to fix this on windows, or if it needs fixing. --- mrbgems/hal-posix-io/src/io_hal.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mrbgems/hal-posix-io/src/io_hal.c b/mrbgems/hal-posix-io/src/io_hal.c index bba87ce33..bf3f1630b 100644 --- a/mrbgems/hal-posix-io/src/io_hal.c +++ b/mrbgems/hal-posix-io/src/io_hal.c @@ -519,6 +519,10 @@ void mrb_hal_io_fdset_set(mrb_state *mrb, int fd, mrb_io_fdset *fdset) { (void)mrb; + if (fd >= FD_SETSIZE) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "fd is larger than FD_SETSIZE"); + return; + } if (fdset) { FD_SET(fd, &fdset->fds); } @@ -528,6 +532,10 @@ int mrb_hal_io_fdset_isset(mrb_state *mrb, int fd, mrb_io_fdset *fdset) { (void)mrb; + if (fd >= FD_SETSIZE) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "fd is larger than FD_SETSIZE"); + return 0; + } if (fdset) { return FD_ISSET(fd, &fdset->fds); } From 8769f37868631983e7e73fc3bf514f92d9540ea2 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Sun, 25 Jan 2026 15:46:56 +0100 Subject: [PATCH 2/3] Improve error handling for file descriptor range --- mrbgems/hal-posix-io/src/io_hal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mrbgems/hal-posix-io/src/io_hal.c b/mrbgems/hal-posix-io/src/io_hal.c index bf3f1630b..2283fdd7e 100644 --- a/mrbgems/hal-posix-io/src/io_hal.c +++ b/mrbgems/hal-posix-io/src/io_hal.c @@ -519,8 +519,8 @@ void mrb_hal_io_fdset_set(mrb_state *mrb, int fd, mrb_io_fdset *fdset) { (void)mrb; - if (fd >= FD_SETSIZE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "fd is larger than FD_SETSIZE"); + if (fd < 0 || fd >= FD_SETSIZE) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "fd is out of range"); return; } if (fdset) { @@ -532,8 +532,8 @@ int mrb_hal_io_fdset_isset(mrb_state *mrb, int fd, mrb_io_fdset *fdset) { (void)mrb; - if (fd >= FD_SETSIZE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "fd is larger than FD_SETSIZE"); + if (fd < 0 || fd >= FD_SETSIZE) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "fd is out of range"); return 0; } if (fdset) { From c836b096af8e9ec62011f01fcf857e2dda8816d0 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Sun, 25 Jan 2026 16:04:23 +0100 Subject: [PATCH 3/3] Add error handling for fdset size limit This should fix it for Windows. --- mrbgems/hal-win-io/src/io_hal.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mrbgems/hal-win-io/src/io_hal.c b/mrbgems/hal-win-io/src/io_hal.c index 9cc3583bd..f3429b62a 100644 --- a/mrbgems/hal-win-io/src/io_hal.c +++ b/mrbgems/hal-win-io/src/io_hal.c @@ -562,6 +562,11 @@ void mrb_hal_io_fdset_set(mrb_state *mrb, int fd, mrb_io_fdset *fdset) { (void)mrb; + if (fdset->fds.fd_count >= FD_SETSIZE) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too many sockets for fd_set"); + return; + } + if (fdset) { FD_SET(fd, &fdset->fds); }