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


Reply via email to