aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2018-03-28 11:07:14 -0400
committerMike Snitzer <snitzer@redhat.com>2018-04-04 12:12:37 -0400
commit13bc62d4a6c79b95ec299591df1bae0a505f2d07 (patch)
tree0c4bd4c5f41d979435d04268de3e779c31967d75
parentd4b1aaf53c02e6440c49aeae06ba3a3a8ce9882a (diff)
dm raid: fix parse_raid_params() variable range issue
parse_raid_params() compares variable "int value" with INT_MAX. E.g. related Coverity report excerpt: CID 1364818 (#2 of 3): Operands don't affect result (CONSTANT_EXPRESSION_RESULT) [select issue] 1433 if (value > INT_MAX) { Fix by changing checks to avoid INT_MAX. Whilst on it, avoid unnecessary checks against constants and add check for sane recovery speed min/max. Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-raid.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 598c9e3e41a5..6f823f44b4aa 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -1370,19 +1370,18 @@ static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
1370 * In device-mapper, we specify things in sectors, but 1370 * In device-mapper, we specify things in sectors, but
1371 * MD records this value in kB 1371 * MD records this value in kB
1372 */ 1372 */
1373 value /= 2; 1373 if (value < 0 || value / 2 > COUNTER_MAX) {
1374 if (value > COUNTER_MAX) {
1375 rs->ti->error = "Max write-behind limit out of range"; 1374 rs->ti->error = "Max write-behind limit out of range";
1376 return -EINVAL; 1375 return -EINVAL;
1377 } 1376 }
1378 1377
1379 rs->md.bitmap_info.max_write_behind = value; 1378 rs->md.bitmap_info.max_write_behind = value / 2;
1380 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_DAEMON_SLEEP))) { 1379 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_DAEMON_SLEEP))) {
1381 if (test_and_set_bit(__CTR_FLAG_DAEMON_SLEEP, &rs->ctr_flags)) { 1380 if (test_and_set_bit(__CTR_FLAG_DAEMON_SLEEP, &rs->ctr_flags)) {
1382 rs->ti->error = "Only one daemon_sleep argument pair allowed"; 1381 rs->ti->error = "Only one daemon_sleep argument pair allowed";
1383 return -EINVAL; 1382 return -EINVAL;
1384 } 1383 }
1385 if (!value || (value > MAX_SCHEDULE_TIMEOUT)) { 1384 if (value < 0) {
1386 rs->ti->error = "daemon sleep period out of range"; 1385 rs->ti->error = "daemon sleep period out of range";
1387 return -EINVAL; 1386 return -EINVAL;
1388 } 1387 }
@@ -1424,27 +1423,33 @@ static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
1424 return -EINVAL; 1423 return -EINVAL;
1425 } 1424 }
1426 1425
1426 if (value < 0) {
1427 rs->ti->error = "Bogus stripe cache entries value";
1428 return -EINVAL;
1429 }
1427 rs->stripe_cache_entries = value; 1430 rs->stripe_cache_entries = value;
1428 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MIN_RECOVERY_RATE))) { 1431 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MIN_RECOVERY_RATE))) {
1429 if (test_and_set_bit(__CTR_FLAG_MIN_RECOVERY_RATE, &rs->ctr_flags)) { 1432 if (test_and_set_bit(__CTR_FLAG_MIN_RECOVERY_RATE, &rs->ctr_flags)) {
1430 rs->ti->error = "Only one min_recovery_rate argument pair allowed"; 1433 rs->ti->error = "Only one min_recovery_rate argument pair allowed";
1431 return -EINVAL; 1434 return -EINVAL;
1432 } 1435 }
1433 if (value > INT_MAX) { 1436
1437 if (value < 0) {
1434 rs->ti->error = "min_recovery_rate out of range"; 1438 rs->ti->error = "min_recovery_rate out of range";
1435 return -EINVAL; 1439 return -EINVAL;
1436 } 1440 }
1437 rs->md.sync_speed_min = (int)value; 1441 rs->md.sync_speed_min = value;
1438 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MAX_RECOVERY_RATE))) { 1442 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MAX_RECOVERY_RATE))) {
1439 if (test_and_set_bit(__CTR_FLAG_MAX_RECOVERY_RATE, &rs->ctr_flags)) { 1443 if (test_and_set_bit(__CTR_FLAG_MAX_RECOVERY_RATE, &rs->ctr_flags)) {
1440 rs->ti->error = "Only one max_recovery_rate argument pair allowed"; 1444 rs->ti->error = "Only one max_recovery_rate argument pair allowed";
1441 return -EINVAL; 1445 return -EINVAL;
1442 } 1446 }
1443 if (value > INT_MAX) { 1447
1448 if (value < 0) {
1444 rs->ti->error = "max_recovery_rate out of range"; 1449 rs->ti->error = "max_recovery_rate out of range";
1445 return -EINVAL; 1450 return -EINVAL;
1446 } 1451 }
1447 rs->md.sync_speed_max = (int)value; 1452 rs->md.sync_speed_max = value;
1448 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_REGION_SIZE))) { 1453 } else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_REGION_SIZE))) {
1449 if (test_and_set_bit(__CTR_FLAG_REGION_SIZE, &rs->ctr_flags)) { 1454 if (test_and_set_bit(__CTR_FLAG_REGION_SIZE, &rs->ctr_flags)) {
1450 rs->ti->error = "Only one region_size argument pair allowed"; 1455 rs->ti->error = "Only one region_size argument pair allowed";
@@ -1490,6 +1495,12 @@ static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
1490 return -EINVAL; 1495 return -EINVAL;
1491 } 1496 }
1492 1497
1498 if (rs->md.sync_speed_max &&
1499 rs->md.sync_speed_min > rs->md.sync_speed_max) {
1500 rs->ti->error = "Bogus recovery rates";
1501 return -EINVAL;
1502 }
1503
1493 if (validate_region_size(rs, region_size)) 1504 if (validate_region_size(rs, region_size))
1494 return -EINVAL; 1505 return -EINVAL;
1495 1506