fix(linux): prevent segfault from invalid module indices during rapid reloads
When spamming file changes rapidly, inotify can report stale UNLOAD/RELOAD events for modules that were already unloaded by previous events in the same poll cycle. This caused is_mod_loaded() to return -1, which was then cast to size_t (18446744073709551615) and used as an array index, causing segfaults. Additionally, event counts were calculated before validation, causing loops to run more iterations than valid indices were populated, reading garbage values. Changes: - stk.c: Check if is_mod_loaded() returns valid index (>= 0) before adding to unload/reload lists - stk.c: Reset and recalculate counts after populating arrays with only valid indices to prevent loop overrun - Skip processing events for modules that are no longer loaded This completes the Linux stability fixes started in v0.0.2.
This commit is contained in:
@@ -172,8 +172,7 @@ size_t stk_poll(void)
|
||||
char (*file_list)[STK_PATH_MAX] = NULL;
|
||||
stk_module_event_t *events = NULL;
|
||||
size_t i, file_count = 0, reload_count = 0, load_count = 0,
|
||||
unload_count = 0, reload_index = 0, load_index = 0,
|
||||
unload_index = 0;
|
||||
unload_count = 0;
|
||||
int *reloaded_mod_indices = NULL, *reloaded_mod_file_indices = NULL,
|
||||
*unloaded_mod_indices = NULL, *loaded_mod_indices = NULL;
|
||||
size_t remaining_loads, new_capacity, holes_to_fill;
|
||||
@@ -208,20 +207,31 @@ size_t stk_poll(void)
|
||||
unloaded_mod_indices = malloc(unload_count * sizeof(int));
|
||||
loaded_mod_indices = malloc(load_count * sizeof(int));
|
||||
|
||||
reload_count = 0;
|
||||
unload_count = 0;
|
||||
load_count = 0;
|
||||
|
||||
for (i = 0; i < file_count; ++i) {
|
||||
int mod_index;
|
||||
extract_module_id(file_list[i], mod_id);
|
||||
switch (events[i]) {
|
||||
case STK_MOD_LOAD:
|
||||
loaded_mod_indices[load_index++] = i;
|
||||
loaded_mod_indices[load_count++] = i;
|
||||
break;
|
||||
case STK_MOD_RELOAD:
|
||||
reloaded_mod_file_indices[reload_index] = i;
|
||||
reloaded_mod_indices[reload_index++] =
|
||||
is_mod_loaded(mod_id);
|
||||
mod_index = is_mod_loaded(mod_id);
|
||||
if (mod_index >= 0) {
|
||||
reloaded_mod_file_indices[reload_count] = i;
|
||||
reloaded_mod_indices[reload_count] = mod_index;
|
||||
reload_count++;
|
||||
}
|
||||
break;
|
||||
case STK_MOD_UNLOAD:
|
||||
unloaded_mod_indices[unload_index++] =
|
||||
is_mod_loaded(mod_id);
|
||||
mod_index = is_mod_loaded(mod_id);
|
||||
if (mod_index >= 0) {
|
||||
unloaded_mod_indices[unload_count] = mod_index;
|
||||
unload_count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user