rsocket: Fix race in indexer map
authorSean Hefty <sean.hefty@intel.com>
Wed, 11 Feb 2015 00:50:08 +0000 (16:50 -0800)
committerSean Hefty <sean.hefty@intel.com>
Wed, 11 Feb 2015 00:50:08 +0000 (16:50 -0800)
Although insertions and removals of rsockets are protected
against accesses to the index map, when reading the map using
a non-rsocket (i.e. normal fd), the reading of the map may
overlap with the removal of an rsocket.  This can result in
accessing freed memory.

We can avoid this by not freeing the memory when rsockets
no longer reference an index array.  This ensures that the
memory is valid, and protects against reading the memory without
adding locking into the read path.

Problem reported by: Sasha Kotchubievsky <sashakot@mellanox.com>

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
src/indexer.c
src/indexer.h

index f9042f5..be2e69c 100644 (file)
@@ -151,7 +151,6 @@ int idm_set(struct index_map *idm, int index, void *item)
 
        entry = idm->array[idx_array_index(index)];
        entry[idx_entry_index(index)] = item;
-       idm->count[idx_array_index(index)]++;
        return index;
 }
 
@@ -163,9 +162,5 @@ void *idm_clear(struct index_map *idm, int index)
        entry = idm->array[idx_array_index(index)];
        item = entry[idx_entry_index(index)];
        entry[idx_entry_index(index)] = NULL;
-       if (--idm->count[idx_array_index(index)] == 0) {
-               free(idm->array[idx_array_index(index)]);
-               idm->array[idx_array_index(index)] = NULL;
-       }
        return item;
 }
index fc8eae2..0c5f388 100644 (file)
@@ -85,7 +85,6 @@ static inline void *idx_at(struct indexer *idx, int index)
 struct index_map
 {
        void **array[IDX_ARRAY_SIZE];
-       int count[IDX_ARRAY_SIZE];
 };
 
 int idm_set(struct index_map *idm, int index, void *item);