There were a number of cases where the error message for an invalid
table line did not match the actual problem. Fix these. Additionally,
error out when duplicate corrupt_bio_byte, random_read_corrupt, or
random_write_corrupt features are present. Also, error_reads is
incompatible with random_read_corrupt and corrupt_bio_byte with the READ
flag set, so disallow that.

Reported-by: Kent Overstreet <kent.overstr...@linux.dev>
Signed-off-by: Benjamin Marzinski <bmarz...@redhat.com>
---
 drivers/md/dm-flakey.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
index b690905ab89f..f5f8d25d1b2d 100644
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -128,8 +128,11 @@ static int parse_features(struct dm_arg_set *as, struct 
flakey_c *fc,
                 * corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags>
                 */
                if (!strcasecmp(arg_name, "corrupt_bio_byte")) {
-                       if (!argc) {
-                               ti->error = "Feature corrupt_bio_byte requires 
parameters";
+                       if (fc->corrupt_bio_byte) {
+                               ti->error = "Feature corrupt_bio_byte 
duplicated";
+                               return -EINVAL;
+                       } else if (argc < 4) {
+                               ti->error = "Feature corrupt_bio_byte requires 
4 parameters";
                                return -EINVAL;
                        }
 
@@ -176,7 +179,10 @@ static int parse_features(struct dm_arg_set *as, struct 
flakey_c *fc,
                }
 
                if (!strcasecmp(arg_name, "random_read_corrupt")) {
-                       if (!argc) {
+                       if (fc->random_read_corrupt) {
+                               ti->error = "Feature random_read_corrupt 
duplicated";
+                               return -EINVAL;
+                       } else if (!argc) {
                                ti->error = "Feature random_read_corrupt 
requires a parameter";
                                return -EINVAL;
                        }
@@ -189,7 +195,10 @@ static int parse_features(struct dm_arg_set *as, struct 
flakey_c *fc,
                }
 
                if (!strcasecmp(arg_name, "random_write_corrupt")) {
-                       if (!argc) {
+                       if (fc->random_write_corrupt) {
+                               ti->error = "Feature random_write_corrupt 
duplicated";
+                               return -EINVAL;
+                       } else if (!argc) {
                                ti->error = "Feature random_write_corrupt 
requires a parameter";
                                return -EINVAL;
                        }
@@ -205,12 +214,18 @@ static int parse_features(struct dm_arg_set *as, struct 
flakey_c *fc,
                return -EINVAL;
        }
 
-       if (test_bit(DROP_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) 
{
-               ti->error = "drop_writes is incompatible with corrupt_bio_byte 
with the WRITE flag set";
+       if (test_bit(DROP_WRITES, &fc->flags) &&
+           (fc->corrupt_bio_rw == WRITE || fc->random_write_corrupt)) {
+               ti->error = "drop_writes is incompatible with 
random_write_corrupt or corrupt_bio_byte with the WRITE flag set";
                return -EINVAL;
 
-       } else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == 
WRITE)) {
-               ti->error = "error_writes is incompatible with corrupt_bio_byte 
with the WRITE flag set";
+       } else if (test_bit(ERROR_WRITES, &fc->flags) &&
+                  (fc->corrupt_bio_rw == WRITE || fc->random_write_corrupt)) {
+               ti->error = "error_writes is incompatible with 
random_write_corrupt or corrupt_bio_byte with the WRITE flag set";
+               return -EINVAL;
+       } else if (test_bit(ERROR_READS, &fc->flags) &&
+                  (fc->corrupt_bio_rw == READ || fc->random_read_corrupt)) {
+               ti->error = "error_reads is incompatible with 
random_read_corrupt or corrupt_bio_byte with the READ flag set";
                return -EINVAL;
        }
 
@@ -278,7 +293,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int 
argc, char **argv)
        if (r)
                goto bad;
 
-       r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error);
+       r = dm_read_arg(_args + 1, &as, &fc->down_interval, &ti->error);
        if (r)
                goto bad;
 
-- 
2.48.1


Reply via email to