libceph: fix a use after free issue in osdmap_set_max_osd
If the state variable is krealloced successfully, map->osd_state will be freed, once following two reallocation failed, and exit the function without resetting map->osd_state, map->osd_state become a wild pointer. fix it by resetting them after krealloc successfully. Signed-off-by: Li RongQing <roy.qing.li@gmail.com> Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
This commit is contained in:
parent
dc220db03f
commit
589506f1e7
|
@ -671,26 +671,26 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
state = krealloc(map->osd_state, max*sizeof(*state), GFP_NOFS);
|
state = krealloc(map->osd_state, max*sizeof(*state), GFP_NOFS);
|
||||||
weight = krealloc(map->osd_weight, max*sizeof(*weight), GFP_NOFS);
|
if (!state)
|
||||||
addr = krealloc(map->osd_addr, max*sizeof(*addr), GFP_NOFS);
|
|
||||||
if (!state || !weight || !addr) {
|
|
||||||
kfree(state);
|
|
||||||
kfree(weight);
|
|
||||||
kfree(addr);
|
|
||||||
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
map->osd_state = state;
|
||||||
|
|
||||||
|
weight = krealloc(map->osd_weight, max*sizeof(*weight), GFP_NOFS);
|
||||||
|
if (!weight)
|
||||||
|
return -ENOMEM;
|
||||||
|
map->osd_weight = weight;
|
||||||
|
|
||||||
|
addr = krealloc(map->osd_addr, max*sizeof(*addr), GFP_NOFS);
|
||||||
|
if (!addr)
|
||||||
|
return -ENOMEM;
|
||||||
|
map->osd_addr = addr;
|
||||||
|
|
||||||
for (i = map->max_osd; i < max; i++) {
|
for (i = map->max_osd; i < max; i++) {
|
||||||
state[i] = 0;
|
map->osd_state[i] = 0;
|
||||||
weight[i] = CEPH_OSD_OUT;
|
map->osd_weight[i] = CEPH_OSD_OUT;
|
||||||
memset(addr + i, 0, sizeof(*addr));
|
memset(map->osd_addr + i, 0, sizeof(*map->osd_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
map->osd_state = state;
|
|
||||||
map->osd_weight = weight;
|
|
||||||
map->osd_addr = addr;
|
|
||||||
|
|
||||||
if (map->osd_primary_affinity) {
|
if (map->osd_primary_affinity) {
|
||||||
u32 *affinity;
|
u32 *affinity;
|
||||||
|
|
||||||
|
@ -698,11 +698,11 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
|
||||||
max*sizeof(*affinity), GFP_NOFS);
|
max*sizeof(*affinity), GFP_NOFS);
|
||||||
if (!affinity)
|
if (!affinity)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
map->osd_primary_affinity = affinity;
|
||||||
|
|
||||||
for (i = map->max_osd; i < max; i++)
|
for (i = map->max_osd; i < max; i++)
|
||||||
affinity[i] = CEPH_OSD_DEFAULT_PRIMARY_AFFINITY;
|
map->osd_primary_affinity[i] =
|
||||||
|
CEPH_OSD_DEFAULT_PRIMARY_AFFINITY;
|
||||||
map->osd_primary_affinity = affinity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map->max_osd = max;
|
map->max_osd = max;
|
||||||
|
|
Loading…
Reference in New Issue