We use v->allocated with the semantics of "length" or "number of used elements" of a vector. If realloc() fails while deleting an element, we should keep the previously allocated v->slot array but still decrement "allocated" in order to avoid accessing invalid vector elements.
The next successful realloc will bring v->allocated and the actual size of the array in sync again. Signed-off-by: Martin Wilck <mwi...@suse.com> --- libmpathutil/vector.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libmpathutil/vector.c b/libmpathutil/vector.c index 7f763cb..f69d644 100644 --- a/libmpathutil/vector.c +++ b/libmpathutil/vector.c @@ -113,7 +113,7 @@ vector_del_slot(vector v, int slot) return; for (i = slot + 1; i < VECTOR_SIZE(v); i++) - v->slot[i-1] = v->slot[i]; + v->slot[i - 1] = v->slot[i]; v->allocated -= VECTOR_DEFAULT_SIZE; @@ -125,9 +125,15 @@ vector_del_slot(vector v, int slot) void *new_slot; new_slot = realloc(v->slot, sizeof (void *) * v->allocated); - if (!new_slot) - v->allocated += VECTOR_DEFAULT_SIZE; - else + /* + * If realloc() fails, v->allocated will be smaller than the + * actual allocated size vector size. + * This is intentional; we want VECTOR_SIZE() to return + * the number of used elements. Otherwise, vector_for_each_slot() + * et al. wouldn't work as intended; there might be duplicate + * or stale elements at the end of the vector. + */ + if (new_slot) v->slot = new_slot; } } -- 2.49.0