On Mon, Oct 19, 2020 at 01:42:27PM +0200, Martijn de Gouw wrote:
> When the passed token is longer than 4032 bytes, the remaining part
> of the token must be copied from the rqstp->rq_arg.pages. But the
> copy must make sure it happens in a consecutive way.

Thanks.  Apologies, but I don't immediately see where the copy is
non-consecutive.  What exactly is the bug in the existing code?

--b.

> 
> Signed-off-by: Martijn de Gouw <martijn.de.g...@prodrive-technologies.com>
> ---
>  net/sunrpc/auth_gss/svcauth_gss.c | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/net/sunrpc/auth_gss/svcauth_gss.c 
> b/net/sunrpc/auth_gss/svcauth_gss.c
> index 258b04372f85..bd4678db9d76 100644
> --- a/net/sunrpc/auth_gss/svcauth_gss.c
> +++ b/net/sunrpc/auth_gss/svcauth_gss.c
> @@ -1147,9 +1147,9 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp,
>                              struct gssp_in_token *in_token)
>  {
>       struct kvec *argv = &rqstp->rq_arg.head[0];
> -     unsigned int page_base, length;
> -     int pages, i, res;
> -     size_t inlen;
> +     unsigned int length, pgto_offs, pgfrom_offs;
> +     int pages, i, res, pgto, pgfrom;
> +     size_t inlen, to_offs, from_offs;
>  
>       res = gss_read_common_verf(gc, argv, authp, in_handle);
>       if (res)
> @@ -1177,17 +1177,24 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp,
>       memcpy(page_address(in_token->pages[0]), argv->iov_base, length);
>       inlen -= length;
>  
> -     i = 1;
> -     page_base = rqstp->rq_arg.page_base;
> +     to_offs = length;
> +     from_offs = rqstp->rq_arg.page_base;
>       while (inlen) {
> -             length = min_t(unsigned int, inlen, PAGE_SIZE);
> -             memcpy(page_address(in_token->pages[i]),
> -                    page_address(rqstp->rq_arg.pages[i]) + page_base,
> +             pgto = to_offs >> PAGE_SHIFT;
> +             pgfrom = from_offs >> PAGE_SHIFT;
> +             pgto_offs = to_offs & ~PAGE_MASK;
> +             pgfrom_offs = from_offs & ~PAGE_MASK;
> +
> +             length = min_t(unsigned int, inlen,
> +                      min_t(unsigned int, PAGE_SIZE - pgto_offs,
> +                            PAGE_SIZE - pgfrom_offs));
> +             memcpy(page_address(in_token->pages[pgto]) + pgto_offs,
> +                    page_address(rqstp->rq_arg.pages[pgfrom]) + pgfrom_offs,
>                      length);
>  
> +             to_offs += length;
> +             from_offs += length;
>               inlen -= length;
> -             page_base = 0;
> -             i++;
>       }
>       return 0;
>  }
> -- 
> 2.20.1

Reply via email to