| 29 Dec 2025 |
emily | well it is only select that has this footgun in the first place | 01:03:32 |
Ihar Hrachyshka | indeed windows uses a different implementation. It uses same macro but ends up with a different code path.. :( | 01:04:41 |
emily | https://gitlab.gnome.org/GNOME/glib/-/blob/ecef4b16cfe1a67f18c82f7b12f58241922c7b89/glib/gpoll.c#L544 doesn't bother doing any checks, but Darwin's FD_SET will do overflow checks by default (see sys/_types/_fd_def.h), but _DARWIN_UNLIMITED_SELECT adjusts the behaviour | 01:04:43 |
emily | so I think this turns something likely caught at runtime into a potential vulnerability, on Darwin | 01:05:06 |
emily | I think what would be ideal is #define _DARWIN_UNLIMITED_SELECT just in this file and doing it as a heap allocation | 01:05:38 |
Ihar Hrachyshka | ok. should I add an explicit nfds check against SET_FDSIZE in that g_poll implementation? would it save runtime? | 01:06:07 |
emily | of a struct { int32_t fds_bits[]; } | 01:06:13 |
emily | yeah that would also work as a cheaper fix | 01:06:40 |
emily | but it should only be a few lines to do the heap allocation thing | 01:06:45 |
emily | something like… | 01:08:49 |
emily | fd_set rset_stack, wset_stack, xset_stack;
fd_set *rset = &rset_stack, *wset = &wset_stack, *xset = &xset_stack;
if (nfds > FD_SETSIZE)
{
size_t nelems = __DARWIN_howmany(nfds, __DARWIN_NFDBITS);
size_t size = sizeof (struct { int32_t fds_bits[nelems] });
rset = g_malloc0 (size);
wset = g_malloc0 (size);
xset = g_malloc0 (size);
}
…
if (nfds > FD_SETSIZE)
{
g_free (rset);
g_free (wset);
g_free (xset);
}
| 01:12:50 |
emily | (I guess can g_malloc rather than g_malloc0, since FD_ZERO and all) | 01:13:41 |
emily | thankfully guint is small enough that you don't have to worry about size overflow 🫣 | 01:14:42 |
Ihar Hrachyshka | Seems like a better way - no need to choose a value for FD_SETSIZE. will adopt and add a test case as Randy suggested. | 01:16:57 |
emily | yeah, would definitely not trust this without testing :D | 01:19:44 |
emily | it does have the somewhat sad effect that every call will do heap allocation when you have lots of fds, but probably code relying on select isn't exactly hyperoptimized to begin with…? | 01:20:28 |
Ihar Hrachyshka | if you have more fds than what the platform supports, your alternative is getting the fault, so... | 01:23:08 |
Ihar Hrachyshka | we are not making it worse | 01:23:26 |
Ihar Hrachyshka | * if you have more fds than what the platform supports, your alternative atm is getting the fault, so... | 01:24:00 |
emily | yeah | 01:25:06 |
emily | can always do both this and raising FD_SETSIZE | 01:25:17 |
Randy Eckenrode | I got SwiftPM working correctly in a dev shell to build my Advent of Code solutions from 2022 (which were written in Swift). The resulting binary correctly targets macOS 13 per the platforms configuration in Package.swift. | 01:27:55 |
Randy Eckenrode | I guess next is splitting out the stdlib. I’m not sure what else is left other than maybe seeing if I can do some kind of cursed prebuilts thing. | 01:28:15 |
Ihar Hrachyshka | if I were to go with alloc (which I will), I'd do raising only if I notice perf degradation. (atm it smells like premature optimization) | 01:28:17 |
Randy Eckenrode | (And building on Linux.) | 01:28:18 |
emily | yeah I expect the syscall overhead is much higher than allocation anyway. | 01:30:40 |