linux/fs/nfsd
Christian Brauner 620c266f39 fhandle: relax open_by_handle_at() permission checks
A current limitation of open_by_handle_at() is that it's currently not possible
to use it from within containers at all because we require CAP_DAC_READ_SEARCH
in the initial namespace. That's unfortunate because there are scenarios where
using open_by_handle_at() from within containers.

Two examples:

(1) cgroupfs allows to encode cgroups to file handles and reopen them with
    open_by_handle_at().
(2) Fanotify allows placing filesystem watches they currently aren't usable in
    containers because the returned file handles cannot be used.

Here's a proposal for relaxing the permission check for open_by_handle_at().

(1) Opening file handles when the caller has privileges over the filesystem
    (1.1) The caller has an unobstructed view of the filesystem.
    (1.2) The caller has permissions to follow a path to the file handle.

This doesn't address the problem of opening a file handle when only a portion
of a filesystem is exposed as is common in containers by e.g., bind-mounting a
subtree. The proposal to solve this use-case is:

(2) Opening file handles when the caller has privileges over a subtree
    (2.1) The caller is able to reach the file from the provided mount fd.
    (2.2) The caller has permissions to construct an unobstructed path to the
          file handle.
    (2.3) The caller has permissions to follow a path to the file handle.

The relaxed permission checks are currently restricted to directory file
handles which are what both cgroupfs and fanotify need. Handling disconnected
non-directory file handles would lead to a potentially non-deterministic api.
If a disconnected non-directory file handle is provided we may fail to decode
a valid path that we could use for permission checking. That in itself isn't a
problem as we would just return EACCES in that case. However, confusion may
arise if a non-disconnected dentry ends up in the cache later and those opening
the file handle would suddenly succeed.

* It's potentially possible to use timing information (side-channel) to infer
  whether a given inode exists. I don't think that's particularly
  problematic. Thanks to Jann for bringing this to my attention.

* An unrelated note (IOW, these are thoughts that apply to
  open_by_handle_at() generically and are unrelated to the changes here):
  Jann pointed out that we should verify whether deleted files could
  potentially be reopened through open_by_handle_at(). I don't think that's
  possible though.

  Another potential thing to check is whether open_by_handle_at() could be
  abused to open internal stuff like memfds or gpu stuff. I don't think so
  but I haven't had the time to completely verify this.

This dates back to discussions Amir and I had quite some time ago and thanks to
him for providing a lot of details around the export code and related patches!

Link: https://lore.kernel.org/r/20240524-vfs-open_by_handle_at-v1-1-3d4b7d22736b@kernel.org
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-05-28 15:57:23 +02:00
..
acl.h NFSD: add posix ACLs to struct nfsd_attrs 2022-08-04 10:28:03 -04:00
auth.c cred: get rid of CONFIG_DEBUG_CREDENTIALS 2023-12-15 14:19:48 -08:00
auth.h
blocklayout.c nfsd: allow layout state to be admin-revoked. 2024-03-01 09:12:22 -05:00
blocklayoutxdr.c NFSD: Make @gdev parameter of ->encode_getdeviceinfo a const pointer 2023-10-16 12:44:29 -04:00
blocklayoutxdr.h NFSD: Make @gdev parameter of ->encode_getdeviceinfo a const pointer 2023-10-16 12:44:29 -04:00
cache.h nfsd: make all of the nfsd stats per-network namespace 2024-03-01 09:12:10 -05:00
current_stateid.h
export.c fs: nfsd: use group allocation/free of per-cpu counters API 2024-05-06 09:07:17 -04:00
export.h NFSD: Fix frame size warning in svc_export_parse() 2023-10-16 12:44:39 -04:00
filecache.c fsnotify: create a wrapper fsnotify_find_inode_mark() 2024-04-04 16:24:16 +02:00
filecache.h nfsd: Don't leave work of closing files to a work queue 2024-03-01 09:12:05 -05:00
flexfilelayout.c nfsd: move nfserrno() to vfs.c 2022-11-28 12:54:44 -05:00
flexfilelayoutxdr.c NFSD: Make @gdev parameter of ->encode_getdeviceinfo a const pointer 2023-10-16 12:44:29 -04:00
flexfilelayoutxdr.h NFSD: Make @gdev parameter of ->encode_getdeviceinfo a const pointer 2023-10-16 12:44:29 -04:00
idmap.h
Kconfig nfsd: new Kconfig option for legacy client tracking 2024-01-07 17:54:24 -05:00
lockd.c NFSD: simplify struct nfsfh 2021-10-02 15:51:10 -04:00
Makefile NFSD: introduce netlink stubs 2023-10-16 12:44:09 -04:00
netlink.c NFSD: add listener-{set,get} netlink command 2024-05-06 09:07:22 -04:00
netlink.h NFSD: add listener-{set,get} netlink command 2024-05-06 09:07:22 -04:00
netns.h NFSD: add write_version to netlink command 2024-05-06 09:07:21 -04:00
nfs2acl.c NFSD 6.3 Release Notes 2023-02-22 14:21:40 -08:00
nfs3acl.c NFSD 6.3 Release Notes 2023-02-22 14:21:40 -08:00
nfs3proc.c nfsd: Fix NFSv3 atomicity bugs in nfsd_setattr() 2024-03-01 09:12:33 -05:00
nfs3xdr.c nfsd: Fix NFSv3 atomicity bugs in nfsd_setattr() 2024-03-01 09:12:33 -05:00
nfs4acl.c nfsd: inherit required unset default acls from effective set 2023-08-29 17:45:22 -04:00
nfs4callback.c NFSD: Move callback_wq into struct nfs4_client 2024-05-06 09:07:16 -04:00
nfs4idmap.c SUNRPC: return proper error from get_expiry() 2023-04-26 09:05:00 -04:00
nfs4layouts.c NFSD 6.9 Release Notes 2024-03-12 14:27:37 -07:00
nfs4proc.c NFSD: Force all NFSv4.2 COPY requests to be synchronous 2024-05-09 09:10:48 -04:00
nfs4recover.c nfsd: new Kconfig option for legacy client tracking 2024-01-07 17:54:24 -05:00
nfs4state.c nfsd: optimise recalculate_deny_mode() for a common case 2024-05-06 09:07:19 -04:00
nfs4xdr.c NFSD: Add COPY status code to OFFLOAD_STATUS response 2024-05-06 09:07:23 -04:00
nfscache.c nfsd: Simplify the allocation of slab caches in nfsd_drc_slab_create 2024-03-01 09:12:24 -05:00
nfsctl.c NFSD: add listener-{set,get} netlink command 2024-05-06 09:07:22 -04:00
nfsd.h NFS/knfsd: Remove the invalid NFS error 'NFSERR_OPNOTSUPP' 2024-05-06 12:47:24 -04:00
nfsfh.c fhandle: relax open_by_handle_at() permission checks 2024-05-28 15:57:23 +02:00
nfsfh.h NFSD: Add nfsd4_encode_fattr4_change() 2023-10-16 12:44:14 -04:00
nfsproc.c nfsd: Fix NFSv3 atomicity bugs in nfsd_setattr() 2024-03-01 09:12:33 -05:00
nfssvc.c NFSD: add write_version to netlink command 2024-05-06 09:07:21 -04:00
nfsxdr.c NFSD: Ensure that xdr_write_pages updates rq_next_page 2023-06-05 09:01:44 -04:00
pnfs.h nfsd: allow layout state to be admin-revoked. 2024-03-01 09:12:22 -05:00
state.h NFSD: Move callback_wq into struct nfs4_client 2024-05-06 09:07:16 -04:00
stats.c fs: nfsd: use group allocation/free of per-cpu counters API 2024-05-06 09:07:17 -04:00
stats.h fs: nfsd: use group allocation/free of per-cpu counters API 2024-05-06 09:07:17 -04:00
trace.c
trace.h tracing/treewide: Remove second parameter of __assign_str() 2024-05-22 20:14:47 -04:00
vfs.c nfsd: set security label during create operations 2024-05-06 09:07:24 -04:00
vfs.h nfsd: set security label during create operations 2024-05-06 09:07:24 -04:00
xdr3.h nfsd: Fix NFSv3 atomicity bugs in nfsd_setattr() 2024-03-01 09:12:33 -05:00
xdr4.h NFSD: Add COPY status code to OFFLOAD_STATUS response 2024-05-06 09:07:23 -04:00
xdr4cb.h NFSD: add support for CB_GETATTR callback 2024-03-01 09:12:31 -05:00
xdr.h NFSD: prevent underflow in nfssvc_decode_writeargs() 2022-03-15 09:35:56 -04:00