forked from Minki/linux
dm table: remove unused buggy code that extends the targets array
A device mapper table is allocated in the following way: * The function dm_table_create is called, it gets the number of targets as an argument -- it allocates a targets array accordingly. * For each target, we call dm_table_add_target. If we add more targets than were specified in dm_table_create, the function dm_table_add_target reallocates the targets array. However, this reallocation code is wrong - it moves the targets array to a new location, while some target constructors hold pointers to the array in the old location. The following DM target drivers save the pointer to the target structure, so they corrupt memory if the target array is moved: multipath, raid, mirror, snapshot, stripe, switch, thin, verity. Under normal circumstances, the reallocation function is not called (because dm_table_create is called with the correct number of targets), so the buggy reallocation code is not used. Prior to the fix "dm table: fail dm_table_create on dm_round_up overflow", the reallocation code could only be used in case the user specifies too large a value in param->target_count, such as 0xffffffff. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
parent
19fa1a6756
commit
57a2f23856
@ -155,7 +155,6 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
|
||||
{
|
||||
sector_t *n_highs;
|
||||
struct dm_target *n_targets;
|
||||
int n = t->num_targets;
|
||||
|
||||
/*
|
||||
* Allocate both the target array and offset array at once.
|
||||
@ -169,12 +168,7 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
|
||||
|
||||
n_targets = (struct dm_target *) (n_highs + num);
|
||||
|
||||
if (n) {
|
||||
memcpy(n_highs, t->highs, sizeof(*n_highs) * n);
|
||||
memcpy(n_targets, t->targets, sizeof(*n_targets) * n);
|
||||
}
|
||||
|
||||
memset(n_highs + n, -1, sizeof(*n_highs) * (num - n));
|
||||
memset(n_highs, -1, sizeof(*n_highs) * num);
|
||||
vfree(t->highs);
|
||||
|
||||
t->num_allocated = num;
|
||||
@ -260,17 +254,6 @@ void dm_table_destroy(struct dm_table *t)
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks to see if we need to extend highs or targets.
|
||||
*/
|
||||
static inline int check_space(struct dm_table *t)
|
||||
{
|
||||
if (t->num_targets >= t->num_allocated)
|
||||
return alloc_targets(t, t->num_allocated * 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we've already got a device in the list.
|
||||
*/
|
||||
@ -731,8 +714,7 @@ int dm_table_add_target(struct dm_table *t, const char *type,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((r = check_space(t)))
|
||||
return r;
|
||||
BUG_ON(t->num_targets >= t->num_allocated);
|
||||
|
||||
tgt = t->targets + t->num_targets;
|
||||
memset(tgt, 0, sizeof(*tgt));
|
||||
|
Loading…
Reference in New Issue
Block a user