Commit ed41ed5
committed
frontend/unix: NULL-check every alloc in inotify path watcher setup
frontend_unix_watch_path_for_changes (the HAS_INOTIFY setup branch)
called four allocators back-to-back with no NULL checks:
inotify_data = (inotify_data_t*)calloc(1, sizeof(*inotify_data));
inotify_data->fd = fd;
inotify_data->wd_list = int_vector_list_new();
inotify_data->path_list = string_list_new();
...
*change_data = (path_change_data_t*)calloc(1, sizeof(path_change_data_t));
(*change_data)->data = inotify_data;
Two concrete failure modes:
1. NULL-deref: if calloc(1, sizeof(inotify_data_t)) returned NULL,
the 'inotify_data->fd = fd' on the very next line segfaulted.
Same problem with the trailing '(*change_data)->data = ...'
if the second calloc failed.
2. Silent partial-success leaks: if inotify_data's calloc succeeded
but int_vector_list_new or string_list_new returned NULL, the
subsequent for-loop still called int_vector_list_append and
string_list_append on a NULL list; the latter dereferences
list->size (libretro-common/lists/string_list.c:145) for a
second NULL-deref. If, conversely, all three list allocations
succeeded but the second calloc (path_change_data_t) failed,
the function returned with inotify_data + its two sub-lists +
the already-established inotify_add_watch kernel watches all
orphaned (inotify_data is not reachable from anywhere since
*change_data is still NULL).
Fix: NULL-check each allocation in turn. On any failure, unwind
what was built up - closing the inotify fd automatically releases
all its inotify_add_watch entries in the kernel (inotify(7):
'all associated watches are automatically freed' on fd close), so
no manual inotify_rm_watch loop is needed on the final failure
path. Leave *change_data untouched on every failure path, which
is what callers already expect as 'no watcher is set up' (the
tear-down branch at the top of this same function uses
'change_data && *change_data' as its presence check).
Reachability: this runs when the user enables playlist auto-scan,
history tracking, or one of the other 'watch this folder for
changes' features. Not a hot path. But the allocations here are
for small structs (tens of bytes each), so OOM on them indicates
genuine memory pressure where segfaulting rather than degrading
gracefully is the wrong outcome.
Thread-safety: unchanged. Watcher setup/teardown runs on the
main thread; inotify_data and the change_data indirection belong
to the caller's state.1 parent 747a8ab commit ed41ed5
1 file changed
Lines changed: 42 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2961 | 2961 | | |
2962 | 2962 | | |
2963 | 2963 | | |
2964 | | - | |
| 2964 | + | |
| 2965 | + | |
| 2966 | + | |
| 2967 | + | |
| 2968 | + | |
| 2969 | + | |
| 2970 | + | |
| 2971 | + | |
| 2972 | + | |
| 2973 | + | |
| 2974 | + | |
| 2975 | + | |
| 2976 | + | |
| 2977 | + | |
| 2978 | + | |
2965 | 2979 | | |
2966 | | - | |
2967 | | - | |
| 2980 | + | |
| 2981 | + | |
| 2982 | + | |
| 2983 | + | |
| 2984 | + | |
| 2985 | + | |
| 2986 | + | |
| 2987 | + | |
| 2988 | + | |
| 2989 | + | |
| 2990 | + | |
| 2991 | + | |
| 2992 | + | |
| 2993 | + | |
| 2994 | + | |
2968 | 2995 | | |
2969 | 2996 | | |
2970 | 2997 | | |
| |||
2992 | 3019 | | |
2993 | 3020 | | |
2994 | 3021 | | |
2995 | | - | |
| 3022 | + | |
| 3023 | + | |
| 3024 | + | |
| 3025 | + | |
| 3026 | + | |
| 3027 | + | |
| 3028 | + | |
| 3029 | + | |
| 3030 | + | |
| 3031 | + | |
| 3032 | + | |
| 3033 | + | |
2996 | 3034 | | |
2997 | 3035 | | |
2998 | 3036 | | |
| |||
0 commit comments