dm: Check for device sector overflow if CONFIG_LBDAF is not set
Reference to a device in device-mapper table contains offset in sectors. If the sector_t is 32bit integer (CONFIG_LBDAF is not set), then several device-mapper targets can overflow this offset and validity check is then performed on a wrong offset and a wrong table is activated. See for example (on 32bit without CONFIG_LBDAF) this overflow: # dmsetup create test --table "0 2048 linear /dev/sdg 4294967297" # dmsetup table test 0 2048 linear 8:96 1 This patch adds explicit check for overflow if the offset is sector_t type. Signed-off-by: Milan Broz <gmazyland@gmail.com> Reviewed-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
parent
8d683dcd65
commit
ef87bfc24f
|
@ -2781,7 +2781,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
|
||||
if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
|
||||
ti->error = "Invalid device sector";
|
||||
goto bad;
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ static int delay_class_ctr(struct dm_target *ti, struct delay_class *c, char **a
|
|||
unsigned long long tmpll;
|
||||
char dummy;
|
||||
|
||||
if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) {
|
||||
if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
|
||||
ti->error = "Invalid device sector";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
devname = dm_shift_arg(&as);
|
||||
|
||||
r = -EINVAL;
|
||||
if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1) {
|
||||
if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
|
||||
ti->error = "Invalid device sector";
|
||||
goto bad;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1) {
|
||||
if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1 || tmp != (sector_t)tmp) {
|
||||
ti->error = "Invalid device sector";
|
||||
goto bad;
|
||||
}
|
||||
|
|
|
@ -943,7 +943,8 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
|
|||
char dummy;
|
||||
int ret;
|
||||
|
||||
if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1) {
|
||||
if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1 ||
|
||||
offset != (sector_t)offset) {
|
||||
ti->error = "Invalid offset";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ static int unstripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (sscanf(argv[4], "%llu%c", &start, &dummy) != 1) {
|
||||
if (sscanf(argv[4], "%llu%c", &start, &dummy) != 1 || start != (sector_t)start) {
|
||||
ti->error = "Invalid striped device offset";
|
||||
goto err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue