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>
next prev 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