All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kasiak <j.kasiak@gmail.com>
To: Jeff Layton <jlayton@kernel.org>
Cc: Chuck Lever III <chuck.lever@oracle.com>,
	bfields@fieldses.org,
	Linux NFS Mailing List <linux-nfs@vger.kernel.org>
Subject: Re: [PATCH v2] lockd: detect and reject lock arguments that overflow
Date: Mon, 1 Aug 2022 17:04:16 -0400	[thread overview]
Message-ID: <CAD15GZdz8+oUqJmDxit_NCSJqnD-3J40WkmyVJLQXp+r1yHrWA@mail.gmail.com> (raw)
In-Reply-To: <20220801195726.154229-1-jlayton@kernel.org>

Hi Jeff,

Can't speak to everything, but applying this patch on my system fixes
the issues I was having.

Thanks for the quick patch!

Jan

On Mon, Aug 1, 2022 at 3:57 PM Jeff Layton <jlayton@kernel.org> wrote:
>
> lockd doesn't currently vet the start and length in nlm4 requests like
> it should, and can end up generating lock requests with arguments that
> overflow when passed to the filesystem.
>
> The NLM4 protocol uses unsigned 64-bit arguments for both start and
> length, whereas struct file_lock tracks the start and end as loff_t
> values. By the time we get around to calling nlm4svc_retrieve_args,
> we've lost the information that would allow us to determine if there was
> an overflow.
>
> Start tracking the actual start and len for NLM4 requests in the
> nlm_lock. In nlm4svc_retrieve_args, vet these values to ensure they
> won't cause an overflow, and return NLM4_FBIG if they do.
>
> Link: https://bugzilla.linux-nfs.org/show_bug.cgi?id=392
> Reported-by: Jan Kasiak <j.kasiak@gmail.com>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  fs/lockd/svc4proc.c       |  8 ++++++++
>  fs/lockd/xdr4.c           | 19 ++-----------------
>  include/linux/lockd/xdr.h |  2 ++
>  3 files changed, 12 insertions(+), 17 deletions(-)
>
> v2: record args as u64s in nlm_lock and check them in
>     nlm4svc_retrieve_args
>
> diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
> index 176b468a61c7..e5adb524a445 100644
> --- a/fs/lockd/svc4proc.c
> +++ b/fs/lockd/svc4proc.c
> @@ -32,6 +32,10 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
>         if (!nlmsvc_ops)
>                 return nlm_lck_denied_nolocks;
>
> +       if (lock->lock_start > OFFSET_MAX ||
> +           (lock->lock_len && ((lock->lock_len - 1) > (OFFSET_MAX - lock->lock_start))))
> +               return nlm4_fbig;
> +
>         /* Obtain host handle */
>         if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
>          || (argp->monitor && nsm_monitor(host) < 0))
> @@ -50,6 +54,10 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
>                 /* Set up the missing parts of the file_lock structure */
>                 lock->fl.fl_file  = file->f_file[mode];
>                 lock->fl.fl_pid = current->tgid;
> +               lock->fl.fl_start = (loff_t)lock->lock_start;
> +               lock->fl.fl_end = lock->lock_len ?
> +                                  (loff_t)(lock->lock_start + lock->lock_len - 1) :
> +                                  OFFSET_MAX;
>                 lock->fl.fl_lmops = &nlmsvc_lock_operations;
>                 nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
>                 if (!lock->fl.fl_owner) {
> diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
> index 856267c0864b..712fdfeb8ef0 100644
> --- a/fs/lockd/xdr4.c
> +++ b/fs/lockd/xdr4.c
> @@ -20,13 +20,6 @@
>
>  #include "svcxdr.h"
>
> -static inline loff_t
> -s64_to_loff_t(__s64 offset)
> -{
> -       return (loff_t)offset;
> -}
> -
> -
>  static inline s64
>  loff_t_to_s64(loff_t offset)
>  {
> @@ -70,8 +63,6 @@ static bool
>  svcxdr_decode_lock(struct xdr_stream *xdr, struct nlm_lock *lock)
>  {
>         struct file_lock *fl = &lock->fl;
> -       u64 len, start;
> -       s64 end;
>
>         if (!svcxdr_decode_string(xdr, &lock->caller, &lock->len))
>                 return false;
> @@ -81,20 +72,14 @@ svcxdr_decode_lock(struct xdr_stream *xdr, struct nlm_lock *lock)
>                 return false;
>         if (xdr_stream_decode_u32(xdr, &lock->svid) < 0)
>                 return false;
> -       if (xdr_stream_decode_u64(xdr, &start) < 0)
> +       if (xdr_stream_decode_u64(xdr, &lock->lock_start) < 0)
>                 return false;
> -       if (xdr_stream_decode_u64(xdr, &len) < 0)
> +       if (xdr_stream_decode_u64(xdr, &lock->lock_len) < 0)
>                 return false;
>
>         locks_init_lock(fl);
>         fl->fl_flags = FL_POSIX;
>         fl->fl_type  = F_RDLCK;
> -       end = start + len - 1;
> -       fl->fl_start = s64_to_loff_t(start);
> -       if (len == 0 || end < 0)
> -               fl->fl_end = OFFSET_MAX;
> -       else
> -               fl->fl_end = s64_to_loff_t(end);
>
>         return true;
>  }
> diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h
> index 398f70093cd3..67e4a2c5500b 100644
> --- a/include/linux/lockd/xdr.h
> +++ b/include/linux/lockd/xdr.h
> @@ -41,6 +41,8 @@ struct nlm_lock {
>         struct nfs_fh           fh;
>         struct xdr_netobj       oh;
>         u32                     svid;
> +       u64                     lock_start;
> +       u64                     lock_len;
>         struct file_lock        fl;
>  };
>
> --
> 2.37.1
>

  reply	other threads:[~2022-08-01 21:04 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-01 19:57 [PATCH v2] lockd: detect and reject lock arguments that overflow Jeff Layton
2022-08-01 21:04 ` Jan Kasiak [this message]
2022-08-02 14:10 ` Chuck Lever III
2022-08-02 15:47   ` Jeff Layton
2022-08-02 15:52     ` Chuck Lever III
2022-08-02 15:54       ` Jeff Layton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAD15GZdz8+oUqJmDxit_NCSJqnD-3J40WkmyVJLQXp+r1yHrWA@mail.gmail.com \
    --to=j.kasiak@gmail.com \
    --cc=bfields@fieldses.org \
    --cc=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.