From: Danny Al-Gaaf Date: Thu, 28 Feb 2013 17:07:28 +0000 (+0100) Subject: crush/builder.c: fix realloc handling X-Git-Tag: v0.59~68^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F83%2Fhead;p=ceph.git crush/builder.c: fix realloc handling Fix handling of realloc. If realloc() fails it returns NULL, assigning the return value of realloc() directly to the pointer without checking for the result will lead to a memory leak in error case. Use a temporary pointer to hold the result of realloc(). In error case return -ENOMEM, otherwise assign it to the pointer we want to realloc. Signed-off-by: Danny Al-Gaaf --- diff --git a/src/crush/builder.c b/src/crush/builder.c index e47974778314..3473704503d0 100644 --- a/src/crush/builder.c +++ b/src/crush/builder.c @@ -68,9 +68,14 @@ int crush_add_rule(struct crush_map *map, struct crush_rule *rule, int ruleno) if (r >= map->max_rules) { /* expand array */ int oldsize; + void *_realloc = NULL; oldsize = map->max_rules; map->max_rules = r+1; - map->rules = realloc(map->rules, map->max_rules * sizeof(map->rules[0])); + if ((_realloc = realloc(map->rules, map->max_rules * sizeof(map->rules[0]))) == NULL) { + return -ENOMEM; + } else { + map->rules = _realloc; + } memset(map->rules + oldsize, 0, (map->max_rules-oldsize) * sizeof(map->rules[0])); } @@ -135,7 +140,12 @@ int crush_add_bucket(struct crush_map *map, map->max_buckets *= 2; else map->max_buckets = 8; - map->buckets = realloc(map->buckets, map->max_buckets * sizeof(map->buckets[0])); + void *_realloc = NULL; + if ((_realloc = realloc(map->buckets, map->max_buckets * sizeof(map->buckets[0]))) == NULL) { + return -ENOMEM; + } else { + map->buckets = _realloc; + } memset(map->buckets + oldsize, 0, (map->max_buckets-oldsize) * sizeof(map->buckets[0])); } @@ -534,9 +544,18 @@ crush_make_bucket(int alg, int hash, int type, int size, int crush_add_uniform_bucket_item(struct crush_bucket_uniform *bucket, int item, int weight) { int newsize = bucket->h.size + 1; - - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); + void *_realloc = NULL; + + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } bucket->h.items[newsize-1] = item; @@ -552,12 +571,29 @@ int crush_add_uniform_bucket_item(struct crush_bucket_uniform *bucket, int item, int crush_add_list_bucket_item(struct crush_bucket_list *bucket, int item, int weight) { int newsize = bucket->h.size + 1; + void *_realloc = NULL; - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); - bucket->item_weights = realloc(bucket->item_weights, sizeof(__u32)*newsize); - bucket->sum_weights = realloc(bucket->sum_weights, sizeof(__u32)*newsize); - + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } + if ((_realloc = realloc(bucket->item_weights, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->item_weights = _realloc; + } + if ((_realloc = realloc(bucket->sum_weights, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->sum_weights = _realloc; + } + bucket->h.items[newsize-1] = item; bucket->item_weights[newsize-1] = weight; if (newsize > 1) { @@ -583,11 +619,25 @@ int crush_add_tree_bucket_item(struct crush_bucket_tree *bucket, int item, int w int depth = calc_depth(newsize);; int node; int j; + void *_realloc = NULL; bucket->num_nodes = 1 << depth; - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); - bucket->node_weights = realloc(bucket->node_weights, sizeof(__u32)*bucket->num_nodes); + + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } + if ((_realloc = realloc(bucket->node_weights, sizeof(__u32)*bucket->num_nodes)) == NULL) { + return -ENOMEM; + } else { + bucket->node_weights = _realloc; + } node = crush_calc_tree_node(newsize-1); bucket->node_weights[node] = weight; @@ -616,10 +666,28 @@ int crush_add_straw_bucket_item(struct crush_bucket_straw *bucket, int item, int { int newsize = bucket->h.size + 1; - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); - bucket->item_weights = realloc(bucket->item_weights, sizeof(__u32)*newsize); - bucket->straws = realloc(bucket->straws, sizeof(__u32)*newsize); + void *_realloc = NULL; + + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } + if ((_realloc = realloc(bucket->item_weights, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->item_weights = _realloc; + } + if ((_realloc = realloc(bucket->straws, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->straws = _realloc; + } bucket->h.items[newsize-1] = item; bucket->item_weights[newsize-1] = weight; @@ -659,6 +727,7 @@ int crush_remove_uniform_bucket_item(struct crush_bucket_uniform *bucket, int it { unsigned i, j; int newsize; + void *_realloc = NULL; for (i = 0; i < bucket->h.size; i++) if (bucket->h.items[i] == item) @@ -671,8 +740,16 @@ int crush_remove_uniform_bucket_item(struct crush_bucket_uniform *bucket, int it newsize = --bucket->h.size; bucket->h.weight -= bucket->item_weight; - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } return 0; } @@ -697,10 +774,28 @@ int crush_remove_list_bucket_item(struct crush_bucket_list *bucket, int item) bucket->h.weight -= weight; newsize = --bucket->h.size; - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); - bucket->item_weights = realloc(bucket->item_weights, sizeof(__u32)*newsize); - bucket->sum_weights = realloc(bucket->sum_weights, sizeof(__u32)*newsize); + void *_realloc = NULL; + + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } + if ((_realloc = realloc(bucket->item_weights, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->item_weights = _realloc; + } + if ((_realloc = realloc(bucket->sum_weights, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->sum_weights = _realloc; + } return 0; } @@ -744,15 +839,29 @@ int crush_remove_tree_bucket_item(struct crush_bucket_tree *bucket, int item) if (newsize != bucket->h.size) { int olddepth, newdepth; - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); + void *_realloc = NULL; + + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } olddepth = calc_depth(bucket->h.size); newdepth = calc_depth(newsize); if (olddepth != newdepth) { bucket->num_nodes = 1 << newdepth; - bucket->node_weights = realloc(bucket->node_weights, - sizeof(__u32)*bucket->num_nodes); + if ((_realloc = realloc(bucket->node_weights, + sizeof(__u32)*bucket->num_nodes)) == NULL) { + return -ENOMEM; + } else { + bucket->node_weights = _realloc; + } } bucket->h.size = newsize; @@ -779,10 +888,28 @@ int crush_remove_straw_bucket_item(struct crush_bucket_straw *bucket, int item) if (i == bucket->h.size) return -ENOENT; - bucket->h.items = realloc(bucket->h.items, sizeof(__s32)*newsize); - bucket->h.perm = realloc(bucket->h.perm, sizeof(__u32)*newsize); - bucket->item_weights = realloc(bucket->item_weights, sizeof(__u32)*newsize); - bucket->straws = realloc(bucket->straws, sizeof(__u32)*newsize); + void *_realloc = NULL; + + if ((_realloc = realloc(bucket->h.items, sizeof(__s32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.items = _realloc; + } + if ((_realloc = realloc(bucket->h.perm, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->h.perm = _realloc; + } + if ((_realloc = realloc(bucket->item_weights, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->item_weights = _realloc; + } + if ((_realloc = realloc(bucket->straws, sizeof(__u32)*newsize)) == NULL) { + return -ENOMEM; + } else { + bucket->straws = _realloc; + } return crush_calc_straw(bucket); }