Re: [RFC] crypto: ccree - protect against short scatterlists

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Gilad,

On Sun, Jan 26, 2020 at 2:38 PM Gilad Ben-Yossef <gilad@xxxxxxxxxxxxx> wrote:
> Deal gracefully with the event of being handed a scatterlist
> which is shorter than expected.
>
> This mitigates a crash in some cases of crashes due to
> attempt to map empty (but not NULL) scatterlists with none
> zero lengths.
>
> This is an interim patch, to help diagnoze the issue, not
> intended for mainline in its current form as of yet.
>
> Signed-off-by: Gilad Ben-Yossef <gilad@xxxxxxxxxxxxx>
> Reported-by: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx>

Thanks for your patch!

Unfortunately this doesn't make a difference, as ...

> --- a/drivers/crypto/ccree/cc_buffer_mgr.c
> +++ b/drivers/crypto/ccree/cc_buffer_mgr.c
> @@ -286,10 +286,32 @@ static void cc_add_sg_entry(struct device *dev, struct buffer_array *sgl_data,
>         sgl_data->num_of_buffers++;
>  }
>
> +static unsigned int cc_sg_trunc_len(struct scatterlist *sg, unsigned int len)
> +{
> +       unsigned int total;
> +
> +       if (!len)
> +               return 0;
> +
> +       for (total = 0; sg; sg = sg_next(sg)) {
> +               total += sg->length;
> +               if (total >= len) {
> +                       total = len;
> +                       break;
> +               }
> +       }
> +
> +       return total;
> +}
> +
>  static int cc_map_sg(struct device *dev, struct scatterlist *sg,
>                      unsigned int nbytes, int direction, u32 *nents,
>                      u32 max_sg_nents, u32 *lbytes, u32 *mapped_nents)
>  {
> +       int ret;
> +
> +       nbytes = cc_sg_trunc_len(sg, nbytes);
> +
>         if (sg_is_last(sg)) {

(1) this branch is taken, and not the else below,
(2) nothing acts upon detecting nbytes = 0.

With extra debug print:

    cc_map_sg: nbytes  = 0, first branch taken

>                 /* One entry only case -set to DLLI */
>                 if (dma_map_sg(dev, sg, 1, direction) != 1) {
> @@ -313,12 +335,14 @@ static int cc_map_sg(struct device *dev, struct scatterlist *sg,
>                 /* In case of mmu the number of mapped nents might
>                  * be changed from the original sgl nents
>                  */
> -               *mapped_nents = dma_map_sg(dev, sg, *nents, direction);
> -               if (*mapped_nents == 0) {
> +               ret = dma_map_sg(dev, sg, *nents, direction);
> +               if (dma_mapping_error(dev, ret)) {
>                         *nents = 0;
> -                       dev_err(dev, "dma_map_sg() sg buffer failed\n");
> +                       dev_err(dev, "dma_map_sg() sg buffer failed %d\n", ret);
>                         return -ENOMEM;
>                 }
> +
> +               *mapped_nents = ret;
>         }
>
>         return 0;

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds



[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux