Jinoh Kang (@iamahuman) commented about server/mapping.c:
+ shared->object_capacity = (mapping->size - offsetof(session_shm_t, objects[0])) / sizeof(session_obj_t); + } + SHARED_WRITE_END; +} + +static int grow_session_mapping(void) +{ + unsigned int capacity; + mem_size_t size; + int unix_fd; + void *tmp; + + capacity = session.shared->object_capacity * 3 / 2; + size = offsetof(session_shm_t, objects[capacity]); + size = (size + page_mask) & ~((mem_size_t)page_mask); + The growth rate is not kept in sync with initial capacity, so it's possible that `grow_session_mapping` ends up doing nothing (0% increment) since the initial capacity is too small (e.g. capacity = 31, growth = 33/32). However, `alloc_shared_object` does not check for this condition, resulting in OOB.
So I think either `grow_session_mapping` or `alloc_shared_object` should have an assert for size growth (see the other thread). Note that decrement is not possible—I got this part wrong, sorry. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3103#note_65158