On Tue, Jun 02, 2026 at 10:42:35AM +0100, Keith Busch wrote:
> When nr_sectors is 0, it is reset to U64_MAX so overflows if start > 1.

Yeah.

> I think you want to remove overriding nr_sectors to U64_MAX and do:
> 
>       if (!nr_sectors)
>               inj->end = U64_MAX;
>       else if (U64_MAX - nr_sectors < start )
>               return -EINVAL;
>       else
>               inj->end = start + nr_sectors - 1;

I ended up ordering a bit differently for better readability, but
yes.

> > +   mutex_lock(&disk->error_injection_lock);
> > +   if (!disk_live(disk)) {
> > +           mutex_unlock(&disk->error_injection_lock);
> > +           return -EINVAL;
> 
> I think we've leaked 'inj' in this error case.

Yes.

> 
> > +   }
> > +   list_add(&inj->entry, &disk->error_injection_list);
> 
> The __blk_error_inject interates this list with
> "list_for_each_entry_rcu", so shouldn't this be list_add_rcu to match?

Yes.

> > +static const match_table_t opt_tokens = {
> > +   { Opt_add,                      "add",                  },
> > +   { Opt_removeall,                "removeall",            },
> > +   { Opt_op,                       "op=%s",                },
> > +   { Opt_start,                    "start=%u"              },
> > +   { Opt_nr_sectors,               "nr_sectors=%u"         },
> 
> Shouldn't start and nr_sectors use %llu?

lib/parser.c doesn't use those prefixes, it's a bit weird.

> > +   if (!options)
> > +           return -ENOMEM;
> > +
> 
> On failure, memdup_user_nul returns an ERR_PTR rather than NULL.
> 
>       if (IS_ERR(options))
>               return PTR_ERR(options);

Aarg, annoying.  Because memdup_user does return NULL :(

> 
> > +   case Removeall:
> > +           if (option_mask & ~Opt_removeall)
> > +                   return -EINVAL;
> 
> Leaking "options"? Should this be:
> 
>               if (option_mask & ~Opt_removeall) {
>                       ret = -EINVAL;
>                       goto out_free_options;
>               }
> 
> ?

Yes.


Reply via email to