public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Benjamin Coddington <bcodding@hammerspace.com>,
	Chuck Lever <chuck.lever@oracle.com>, NeilBrown <neil@brown.name>,
	Trond Myklebust <trondmy@kernel.org>,
	Anna Schumaker <anna@kernel.org>,
	Eric Biggers <ebiggers@kernel.org>,
	Rick Macklem <rick.macklem@gmail.com>
Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	 linux-crypto@vger.kernel.org
Subject: Re: [PATCH v4 0/3] kNFSD Signed Filehandles
Date: Fri, 06 Feb 2026 10:46:41 -0500	[thread overview]
Message-ID: <6789380caa630c8efefce6862c77bf6780af45da.camel@kernel.org> (raw)
In-Reply-To: <cover.1770390036.git.bcodding@hammerspace.com>

On Fri, 2026-02-06 at 10:09 -0500, Benjamin Coddington wrote:
> The following series enables the linux NFS server to add a Message
> Authentication Code (MAC) to the filehandles it gives to clients.  This
> provides additional protection to the exported filesystem against filehandle
> guessing attacks.
> 
> Filesystems generate their own filehandles through the export_operation
> "encode_fh" and a filehandle provides sufficient access to open a file
> without needing to perform a lookup.  A trusted NFS client holding a valid
> filehandle can remotely access the corresponding file without reference to
> access-path restrictions that might be imposed by the ancestor directories
> or the server exports.
> 
> In order to acquire a filehandle, you must perform lookup operations on the
> parent directory(ies), and the permissions on those directories may prohibit
> you from walking into them to find the files within.  This would normally be
> considered sufficient protection on a local filesystem to prohibit users
> from accessing those files, however when the filesystem is exported via NFS
> an exported file can be accessed whenever the NFS server is presented with
> the correct filehandle, which can be guessed or acquired by means other than
> LOOKUP.
> 
> Filehandles are easy to guess because they are well-formed.  The
> open_by_handle_at(2) man page contains an example C program
> (t_name_to_handle_at.c) that can display a filehandle given a path.  Here's
> an example filehandle from a fairly modern XFS:
> 
> # ./t_name_to_handle_at /exports/foo 
> 57
> 12 129    99 00 00 00 00 00 00 00 b4 10 0b 8c
> 
>           ^---------  filehandle  ----------^
>           ^------- inode -------^ ^-- gen --^
> 
> This filehandle consists of a 64-bit inode number and 32-bit generation
> number.  Because the handle is well-formed, its easy to fabricate
> filehandles that match other files within the same filesystem.  You can
> simply insert inode numbers and iterate on the generation number.
> Eventually you'll be able to access the file using open_by_handle_at(2).
> For a local system, open_by_handle_at(2) requires CAP_DAC_READ_SEARCH, which
> protects against guessing attacks by unprivileged users.
> 
> Simple testing confirms that the correct generation number can be found
> within ~1200 minutes using open_by_handle_at() over NFS on a local system
> and it is estimated that adding network delay with genuine NFS calls may
> only increase this to around 24 hours.
> 
> In contrast to a local user using open_by_handle(2), the NFS server must
> permissively allow remote clients to open by filehandle without being able
> to check or trust the remote caller's access. Therefore additional
> protection against this attack is needed for NFS case.  We propose to sign
> filehandles by appending an 8-byte MAC which is the siphash of the
> filehandle from a key set from the nfs-utilities.  NFS server can then
> ensure that guessing a valid filehandle+MAC is practically impossible
> without knowledge of the MAC's key.  The NFS server performs optional
> signing by possessing a key set from userspace and having the "sign_fh"
> export option.
> 
> Because filehandles are long-lived, and there's no method for expiring them,
> the server's key should be set once and not changed.  It also should be
> persisted across restarts.  The methods to set the key allow only setting it
> once, afterward it cannot be changed.  A separate patchset for nfs-utils
> contains the userspace changes required to set the server's key.
> 
> I had planned on adding additional work to enable the server to check whether the
> 8-byte MAC will overflow maximum filehandle length for the protocol at
> export time.  There could be some filesystems with 40-byte fileid and
> 24-byte fsid which would break NFSv3's 64-byte filehandle maximum with an
> 8-byte MAC appended.  The server should refuse to export those filesystems
> when "sign_fh" is requested.  However, the way the export caches work (the
> server may not even be running when a user sets up the export) its
> impossible to do this check at export time.  Instead, the server will refuse
> to give out filehandles at mount time and emit a pr_warn().
> 
> Thanks for any comments and critique.
> 
> Changes from encrypt_fh posting:
> https://lore.kernel.org/linux-nfs/510E10A4-11BE-412D-93AF-C4CC969954E7@hammerspace.com
> 	- sign filehandles instead of encrypt them (Eric Biggers)
> 	- fix the NFSEXP_ macros, specifically NFSEXP_ALLFLAGS (NeilBrown)
> 	- rebase onto cel/nfsd-next (Chuck Lever)
> 	- condensed/clarified problem explantion (thanks Chuck Lever)
> 	- add nfsctl file "fh_key" for rpc.nfsd to also set the key
> 
> Changes from v1 posting:
> https://lore.kernel.org/linux-nfs/cover.1768573690.git.bcodding@hammerspace.com
> 	- remove fh_fileid_offset() (Chuck Lever)
> 	- fix pr_warns, fix memcmp (Chuck Lever)
> 	- remove incorrect rootfh comment (NeilBrown)
> 	- make fh_key setting an optional attr to threads verb (Jeff Layton)
> 	- drop BIT() EXP_ flag conversion
> 	- cover-letter tune-ups (NeilBrown, Chuck Lever)
> 	- fix NFSEXP_ALLFLAGS on 2/3
> 	- cast fh->fh_size + sizeof(hash) result to int (avoid x86_64 WARNING)
> 	- move MAC signing into __fh_update() (Chuck Lever)
> 
> Changes from v2 posting:
> https://lore.kernel.org/linux-nfs/cover.1769026777.git.bcodding@hammerspace.com
> 	- more cover-letter detail (NeilBrown)
> 	- Documentation/filesystems/nfs/exporting.rst section (Jeff Layton)
> 	- fix key copy (Eric Biggers)
> 	- use NFSD_A_SERVER_MAX (NeilBrown)
> 	- remove procfs fh_key interface (Chuck Lever)
> 	- remove FH_AT_MAC (Chuck Lever)
> 	- allow fh_key change when server is not running (Chuck/Jeff)
> 	- accept fh_key as netlink attribute instead of command (Jeff Layton)
> 
> Changes from v3 posting:
> https://lore.kernel.org/linux-nfs/cover.1770046529.git.bcodding@hammerspace.com
> 	- /actually/ fix up endianness problems (Eric Biggers)
> 	- comment typo
> 	- fix Documentation underline warnings
> 	- fix possible uninitialized fh_key var
> 
> Benjamin Coddington (3):
>   NFSD: Add a key for signing filehandles
>   NFSD/export: Add sign_fh export option
>   NFSD: Sign filehandles
> 
>  Documentation/filesystems/nfs/exporting.rst | 85 +++++++++++++++++++++
>  Documentation/netlink/specs/nfsd.yaml       |  6 ++
>  fs/nfsd/export.c                            |  5 +-
>  fs/nfsd/netlink.c                           |  5 +-
>  fs/nfsd/netns.h                             |  2 +
>  fs/nfsd/nfsctl.c                            | 37 ++++++++-
>  fs/nfsd/nfsfh.c                             | 64 +++++++++++++++-
>  fs/nfsd/trace.h                             | 25 ++++++
>  include/uapi/linux/nfsd/export.h            |  4 +-
>  include/uapi/linux/nfsd_netlink.h           |  1 +
>  10 files changed, 225 insertions(+), 9 deletions(-)
> 
> 
> base-commit: e3934bbd57c73b3835a77562ca47b5fbc6f34287


Nice work, Ben. This looks good to me!

Reviewed-by: Jeff Layton <jlayton@kernel.org>

  parent reply	other threads:[~2026-02-06 15:46 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-06 15:09 [PATCH v4 0/3] kNFSD Signed Filehandles Benjamin Coddington
2026-02-06 15:09 ` [PATCH v4 1/3] NFSD: Add a key for signing filehandles Benjamin Coddington
2026-02-06 16:13   ` Benjamin Coddington
2026-02-06 17:38   ` Chuck Lever
2026-02-06 17:52     ` Benjamin Coddington
2026-02-06 18:51       ` Benjamin Coddington
2026-02-06 19:17         ` Chuck Lever
2026-02-06 15:09 ` [PATCH v4 2/3] NFSD/export: Add sign_fh export option Benjamin Coddington
2026-02-06 15:09 ` [PATCH v4 3/3] NFSD: Sign filehandles Benjamin Coddington
2026-02-06 17:47   ` Chuck Lever
2026-02-06 17:55     ` Benjamin Coddington
2026-02-07 10:43   ` kernel test robot
2026-02-06 15:46 ` Jeff Layton [this message]
2026-02-10  1:47 ` [PATCH v4 1/3] NFSD: Add a key for signing filehandles NeilBrown

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=6789380caa630c8efefce6862c77bf6780af45da.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=anna@kernel.org \
    --cc=bcodding@hammerspace.com \
    --cc=chuck.lever@oracle.com \
    --cc=ebiggers@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=rick.macklem@gmail.com \
    --cc=trondmy@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox