On Tue, Jul 18, 2023 at 02:58:46PM +0200, Ard Biesheuvel wrote:

...

> -static int deflate_comp_init(struct deflate_ctx *ctx)
> +static int deflate_process(struct acomp_req *req, struct z_stream_s *stream,
> +                        int (*process)(struct z_stream_s *, int))
>  {
> -     int ret = 0;
> -     struct z_stream_s *stream = &ctx->comp_stream;
> +     unsigned int slen = req->slen;
> +     unsigned int dlen = req->dlen;
> +     struct scatter_walk src, dst;
> +     unsigned int scur, dcur;
> +     int ret;
>  
> -     stream->workspace = vzalloc(zlib_deflate_workspacesize(
> -                             -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL));
> -     if (!stream->workspace) {
> -             ret = -ENOMEM;
> -             goto out;
> -     }
> +     stream->avail_in = stream->avail_out = 0;
> +
> +     scatterwalk_start(&src, req->src);
> +     scatterwalk_start(&dst, req->dst);
> +
> +     scur = dcur = 0;
> +
> +     do {
> +             if (stream->avail_in == 0) {
> +                     if (scur) {
> +                             slen -= scur;
> +
> +                             scatterwalk_unmap(stream->next_in - scur);
> +                             scatterwalk_advance(&src, scur);
> +                             scatterwalk_done(&src, 0, slen);
> +                     }
> +
> +                     scur = scatterwalk_clamp(&src, slen);
> +                     if (scur) {
> +                             stream->next_in = scatterwalk_map(&src);
> +                             stream->avail_in = scur;
> +                     }
> +             }
> +
> +             if (stream->avail_out == 0) {
> +                     if (dcur) {
> +                             dlen -= dcur;
> +
> +                             scatterwalk_unmap(stream->next_out - dcur);
> +                             scatterwalk_advance(&dst, dcur);
> +                             scatterwalk_done(&dst, 1, dlen);
> +                     }
> +
> +                     dcur = scatterwalk_clamp(&dst, dlen);
> +                     if (!dcur)
> +                             break;

Hi Ard,

I'm unsure if this can happen. But if this break occurs in the first
iteration of this do loop, then ret will be used uninitialised below.

Smatch noticed this.

> +
> +                     stream->next_out = scatterwalk_map(&dst);
> +                     stream->avail_out = dcur;
> +             }
> +
> +             ret = process(stream, (slen == scur) ? Z_FINISH : Z_SYNC_FLUSH);
> +     } while (ret == Z_OK);
> +
> +     if (scur)
> +             scatterwalk_unmap(stream->next_in - scur);
> +     if (dcur)
> +             scatterwalk_unmap(stream->next_out - dcur);
> +
> +     if (ret != Z_STREAM_END)
> +             return -EINVAL;
> +
> +     req->dlen = stream->total_out;
> +     return 0;
> +}

...

Reply via email to