diff options
author | shirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-05-08 12:47:25 +0000 |
---|---|---|
committer | shirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-05-08 12:47:25 +0000 |
commit | 5ccee663e9150df0de86f8eaaebed079c7561186 (patch) | |
tree | 8477f16e57e17599013640fdda744a378678013e /win32 | |
parent | 7e134cf71e2535b562cd2d81e3ff69cbe49d0ce0 (diff) |
* include/ruby/win32.h (FD_SET): change function to macro.
To avoid buffer overflow when smaller FD_SETSISE is used in ext
libraries.
* win32/win32.c (rb_w32_fdset): this function is not used anymore.
But we leave this for compatibility.
* win32/win32.c (rb_w32_select_with_thread): fix SEGV when smaller
FD_SETSISE is used in ext libraries. Dereference of fd_set pointer
causes SEGV.
* test/-ext-/win32/test_fd_setsize.rb(TestFdSetSize): add tests for
above.
* ext/-test-/win32/fd_setsize/depend: ditto.
* ext/-test-/win32/fd_setsize/extconf.rb: ditto.
* ext/-test-/win32/fd_setsize/fd_setsize.c: ditto.
[ruby-core:44588] [Bug #6352]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r-- | win32/win32.c | 34 |
1 files changed, 12 insertions, 22 deletions
diff --git a/win32/win32.c b/win32/win32.c index 50387844ab..16ec249b4c 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -2452,25 +2452,10 @@ ioctl(int i, int u, ...) return -1; } -#undef FD_SET - void rb_w32_fdset(int fd, fd_set *set) { - unsigned int i; - SOCKET s = TO_SOCKET(fd); - - for (i = 0; i < set->fd_count; i++) { - if (set->fd_array[i] == s) { - return; - } - } - if (i == set->fd_count) { - if (set->fd_count < FD_SETSIZE) { - set->fd_array[i] = s; - set->fd_count++; - } - } + FD_SET(fd, set); } #undef FD_CLR @@ -2868,14 +2853,19 @@ rb_w32_select_with_thread(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, fd_set orig_rd; fd_set orig_wr; fd_set orig_ex; - if (rd) orig_rd = *rd; - if (wr) orig_wr = *wr; - if (ex) orig_ex = *ex; + + FD_ZERO(&orig_rd); + FD_ZERO(&orig_wr); + FD_ZERO(&orig_ex); + + if (rd) copy_fd(&orig_rd, rd); + if (wr) copy_fd(&orig_wr, wr); + if (ex) copy_fd(&orig_ex, ex); r = do_select(nfds, rd, wr, ex, &zero); // polling if (r != 0) break; // signaled or error - if (rd) *rd = orig_rd; - if (wr) *wr = orig_wr; - if (ex) *ex = orig_ex; + if (rd) copy_fd(rd, &orig_rd); + if (wr) copy_fd(wr, &orig_wr); + if (ex) copy_fd(ex, &orig_ex); if (timeout) { struct timeval now; |