From: "Darrick J. Wong" <djwong@kernel.org>
To: John Groves <john@jagalactic.com>
Cc: John Groves <John@groves.net>, Miklos Szeredi <miklos@szeredi.hu>,
Dan Williams <djbw@kernel.org>,
Bernd Schubert <bschubert@ddn.com>,
Alison Schofield <alison.schofield@intel.com>,
John Groves <jgroves@micron.com>,
Jonathan Corbet <corbet@lwn.net>, Jake Edge <jake@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Vishal Verma <vishal.l.verma@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
Matthew Wilcox <willy@infradead.org>, Jan Kara <jack@suse.cz>,
Alexander Viro <viro@zeniv.linux.org.uk>,
David Hildenbrand <david@kernel.org>,
Christian Brauner <brauner@kernel.org>,
Randy Dunlap <rdunlap@infradead.org>,
Jeff Layton <jlayton@kernel.org>,
Amir Goldstein <amir73il@gmail.com>,
Jonathan Cameron <jic23@kernel.org>,
Stefan Hajnoczi <shajnocz@redhat.com>,
Joanne Koong <joannelkoong@gmail.com>,
Josef Bacik <josef@toxicpanda.com>,
Bagas Sanjaya <bagasdotme@gmail.com>,
Chen Linxuan <chenlinxuan@uniontech.com>,
James Morse <james.morse@arm.com>, Fuad Tabba <tabba@google.com>,
Sean Christopherson <seanjc@google.com>,
Shivank Garg <shivankg@amd.com>,
Ackerley Tng <ackerleytng@google.com>,
Gregory Price <gourry@gourry.net>,
Andrew Morton <akpm@linux-foundation.org>,
Namjae Jeon <linkinjeon@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Ira Weiny <iweiny@kernel.org>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Haren Myneni <haren@linux.ibm.com>,
Pratyush Yadav <pratyush@kernel.org>,
Giovanni Cabiddu <giovanni.cabiddu@intel.com>,
Jiri Slaby <jirislaby@kernel.org>,
Ethan Nelson-Moore <enelsonmoore@gmail.com>,
Gabriel Whigham <gabewhigham@gmail.com>,
Aravind Ramesh <arramesh@micron.com>,
Ajay Joshi <ajayjoshi@micron.com>,
"venkataravis@micron.com" <venkataravis@micron.com>,
"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"nvdimm@lists.linux.dev" <nvdimm@lists.linux.dev>,
"linux-cxl@vger.kernel.org" <linux-cxl@vger.kernel.org>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"fuse-devel@lists.linux.dev" <fuse-devel@lists.linux.dev>
Subject: Re: [PATCH V12 10/12] famfs: Add runtime operation-permission (opts) framework
Date: Wed, 5 Aug 2026 22:31:00 -0700 [thread overview]
Message-ID: <20260806053100.GJ3560084@frogsfrogsfrogs> (raw)
In-Reply-To: <0100019fc574dabe-572d99fc-3bb0-421a-afec-05432de2a757-000000@email.amazonses.com>
On Mon, Aug 03, 2026 at 02:29:57AM +0000, John Groves wrote:
> From: John Groves <John@Groves.net>
>
> famfs denies most namespace, attribute and data operations by default
> because the userspace log, not the kernel, is authoritative for a famfs
> instance. Earlier commits already guard each such operation with a
> famfs_opt_enabled(fsi, FAMFS_OPT_x) check backed by a permissive stub. This
> commit defines the permission bitmap and makes those checks live.
Why would it ever be acceptable for user programs to mess with the
directory tree and file attributes? There's nothing here that would
seem to write to the userspace log. Or am I mistaken, and only the
program that maintains the userspace log (e.g. the famfs server) can do
these kinds of operations?
--D
> Add:
> - FAMFS_OPT_* (uapi): a u64 permission bitmap, one bit per gated operation
> (create, mkdir, mknod, symlink, link, unlink, rmdir, rename, the four
> setattr components, data write, and MAP_CREATE), plus FAMFS_OPT_ALL. The
> FAMFS_OPT_XATTR bit is reserved - famfs has no xattr ops yet.
> - fsi->opts: a per-mount atomic64 bitmap initialized to FAMFS_OPT_DEFAULT,
> which sets famfs's default policy: create, mkdir, chmod, chown, utimes,
> write and MAP_CREATE are permitted; unlink of mapped files, link,
> symlink, mknod, rmdir, rename and truncate are denied.
> - the real famfs_opt_enabled() (replacing the stub), so every planted gate
> now consults fsi->opts.
> - FAMFSIOC_{GET,SET,CLEAR}_OPTS: read the bitmap, or enable/disable the
> bits set in a caller-supplied mask, returning the resulting bitmap.
> SET/CLEAR require CAP_SYS_ADMIN and reject unknown bits with -EINVAL;
> the bitmap is updated with atomic RMW so the checks stay lockless.
> Signed-off-by: John Groves <john@groves.net>
> ---
> fs/famfs/famfs_file.c | 55 ++++++++++++++++++++++++++++++++
> fs/famfs/famfs_inode.c | 1 +
> fs/famfs/famfs_internal.h | 30 ++++++++++++++---
> include/uapi/linux/famfs_ioctl.h | 45 ++++++++++++++++++++++++++
> 4 files changed, 127 insertions(+), 4 deletions(-)
>
> diff --git a/fs/famfs/famfs_file.c b/fs/famfs/famfs_file.c
> index e11a55ecf8d7..abf049b32a4b 100644
> --- a/fs/famfs/famfs_file.c
> +++ b/fs/famfs/famfs_file.c
> @@ -357,6 +357,49 @@ famfs_daxdev_open(struct file *file, void __user *arg)
> return rc;
> }
>
> +/**
> + * famfs_get_opts() - FAMFSIOC_GET_OPTS: return the permission bitmap
> + */
> +static long famfs_get_opts(struct famfs_fs_info *fsi, void __user *arg)
> +{
> + struct famfs_ioc_opts o = { .opts = atomic64_read(&fsi->opts) };
> +
> + if (copy_to_user(arg, &o, sizeof(o)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +/*
> + * famfs_modify_opts() - FAMFSIOC_SET_OPTS / FAMFSIOC_CLEAR_OPTS
> + * @set: true to enable (OR in) the requested bits, false to disable (mask out)
> + *
> + * The caller supplies a mask of FAMFS_OPT_* bits; the resulting bitmap is
> + * returned. Requires CAP_SYS_ADMIN since it changes mount-wide policy.
> + */
> +static long famfs_modify_opts(struct famfs_fs_info *fsi, void __user *arg,
> + bool set)
> +{
> + struct famfs_ioc_opts o;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> + if (copy_from_user(&o, arg, sizeof(o)))
> + return -EFAULT;
> + if (o.opts & ~FAMFS_OPT_ALL)
> + return -EINVAL;
> +
> + if (set)
> + o.opts = atomic64_fetch_or(o.opts, &fsi->opts) | o.opts;
> + else
> + o.opts = atomic64_fetch_and(~o.opts, &fsi->opts) & ~o.opts;
> +
> + if (copy_to_user(arg, &o, sizeof(o)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> /**
> * famfs_file_ioctl() - Top-level famfs file ioctl handler
> * @file: the file
> @@ -378,6 +421,18 @@ famfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> rc = 0;
> break;
>
> + case FAMFSIOC_GET_OPTS:
> + rc = famfs_get_opts(fsi, (void __user *)arg);
> + break;
> +
> + case FAMFSIOC_SET_OPTS:
> + rc = famfs_modify_opts(fsi, (void __user *)arg, true);
> + break;
> +
> + case FAMFSIOC_CLEAR_OPTS:
> + rc = famfs_modify_opts(fsi, (void __user *)arg, false);
> + break;
> +
> case FAMFSIOC_DAXDEV_OPEN:
> rc = famfs_daxdev_open(file, (void __user *)arg);
> break;
> diff --git a/fs/famfs/famfs_inode.c b/fs/famfs/famfs_inode.c
> index a6c3b4574e69..6cbd7d657fd8 100644
> --- a/fs/famfs/famfs_inode.c
> +++ b/fs/famfs/famfs_inode.c
> @@ -717,6 +717,7 @@ static int famfs_init_fs_context(struct fs_context *fc)
> return -ENOMEM;
>
> init_rwsem(&fsi->devlist_sem);
> + atomic64_set(&fsi->opts, FAMFS_OPT_DEFAULT);
> fsi->mount_opts.mode = FAMFS_DEFAULT_MODE;
> fc->s_fs_info = fsi;
> fc->ops = &famfs_context_ops;
> diff --git a/fs/famfs/famfs_internal.h b/fs/famfs/famfs_internal.h
> index b5f9c8d0349f..26873162b4a0 100644
> --- a/fs/famfs/famfs_internal.h
> +++ b/fs/famfs/famfs_internal.h
> @@ -12,11 +12,24 @@
> #define FAMFS_INTERNAL_H
>
> #include <linux/rwsem.h>
> +#include <linux/atomic.h>
> #include <linux/bits.h>
> #include <linux/build_bug.h>
>
> #include <linux/famfs_ioctl.h>
>
> +/*
> + * Default operation-permission bitmap (see FAMFS_OPT_* in the uapi header).
> + * This preserves famfs's historical behavior: file/dir creation, the fmap
> + * ioctl, data writes, and the non-resize setattr components are permitted;
> + * unlink of mapped files, link, symlink, mknod, rmdir, rename and truncate
> + * are denied until enabled via FAMFSIOC_SET_OPTS.
> + */
> +#define FAMFS_OPT_DEFAULT (FAMFS_OPT_CREATE | FAMFS_OPT_MKDIR | \
> + FAMFS_OPT_CHMOD | FAMFS_OPT_CHOWN | \
> + FAMFS_OPT_UTIMES | FAMFS_OPT_WRITE | \
> + FAMFS_OPT_MAP_CREATE)
> +
> extern const struct file_operations famfs_file_operations;
>
> /*
> @@ -104,6 +117,8 @@ struct famfs_dax_devlist {
> * @famfs_fs_info
> *
> * @mount_opts: The mount options
> + * @opts: Operation-permission bitmap (FAMFS_OPT_*), adjusted at runtime
> + * via the FAMFSIOC_{GET,SET,CLEAR}_OPTS ioctls
> * @deverror: True if the dax device has called our notify_failure entry
> * point, or if other "shutdown" conditions exist
> * @dax_devlist: Table of backing daxdevs (slot 0 is the mount primary)
> @@ -111,16 +126,23 @@ struct famfs_dax_devlist {
> */
> struct famfs_fs_info {
> struct famfs_mount_opts mount_opts;
> + atomic64_t opts;
> bool deverror;
> struct famfs_dax_devlist *dax_devlist;
> struct rw_semaphore devlist_sem;
> };
>
> -/* This stub will be replaced in a later commit
> - * Note: the opt parameter is intentionally unused, and will be used by
> - * the replacement function when that commit lands
> +/*
> + * famfs_opt_enabled() - is operation permission @opt enabled for this mount?
> + *
> + * @opt is a single FAMFS_OPT_* bit; returns true if that operation is
> + * permitted. The bitmap is read locklessly (updated via atomic RMW by the
> + * FAMFSIOC_{SET,CLEAR}_OPTS ioctls).
> */
> -#define famfs_opt_enabled(fsi, opt) (fsi != 0)
> +static inline bool famfs_opt_enabled(struct famfs_fs_info *fsi, u64 opt)
> +{
> + return !!(atomic64_read(&fsi->opts) & opt);
> +}
>
> int lookup_daxdev(const char *pathname, dev_t *devno);
> int famfs_devlist_alloc(struct famfs_fs_info *fsi);
> diff --git a/include/uapi/linux/famfs_ioctl.h b/include/uapi/linux/famfs_ioctl.h
> index 751d8b033c2e..efe6ef263975 100644
> --- a/include/uapi/linux/famfs_ioctl.h
> +++ b/include/uapi/linux/famfs_ioctl.h
> @@ -100,6 +100,48 @@ struct famfs_ioc_daxdev {
> __u32 flags;
> };
>
> +/*
> + * Mount-wide operation permissions, queried and modified via the
> + * FAMFSIOC_{GET,SET,CLEAR}_OPTS ioctls. A set bit means the operation is
> + * permitted; a clear bit means it is rejected with -EPERM. famfs denies most
> + * of these by default because the userspace log, not the kernel, is
> + * authoritative for a famfs instance.
> + */
> +#define FAMFS_OPT_CREATE (1ULL << 0) /* create a regular file */
> +#define FAMFS_OPT_MKDIR (1ULL << 1) /* mkdir */
> +#define FAMFS_OPT_MKNOD (1ULL << 2) /* mknod a special file */
> +#define FAMFS_OPT_SYMLINK (1ULL << 3) /* create a symlink */
> +#define FAMFS_OPT_LINK (1ULL << 4) /* hard link */
> +#define FAMFS_OPT_UNLINK (1ULL << 5) /* unlink a mapped file */
> +#define FAMFS_OPT_RMDIR (1ULL << 6) /* rmdir */
> +#define FAMFS_OPT_RENAME (1ULL << 7) /* rename */
> +#define FAMFS_OPT_CHMOD (1ULL << 8) /* setattr ATTR_MODE */
> +#define FAMFS_OPT_CHOWN (1ULL << 9) /* setattr ATTR_UID / ATTR_GID */
> +#define FAMFS_OPT_TRUNCATE (1ULL << 10) /* setattr ATTR_SIZE (resize) */
> +#define FAMFS_OPT_UTIMES (1ULL << 11) /* setattr ATTR_ATIME/ATTR_MTIME*/
> +#define FAMFS_OPT_WRITE (1ULL << 12) /* write file data */
> +#define FAMFS_OPT_XATTR (1ULL << 13) /* set/remove xattrs (reserved) */
> +#define FAMFS_OPT_MAP_CREATE (1ULL << 14) /* attach an fmap (MAP_CREATE) */
> +
> +#define FAMFS_OPT_ALL (FAMFS_OPT_CREATE | FAMFS_OPT_MKDIR | \
> + FAMFS_OPT_MKNOD | FAMFS_OPT_SYMLINK | \
> + FAMFS_OPT_LINK | FAMFS_OPT_UNLINK | \
> + FAMFS_OPT_RMDIR | FAMFS_OPT_RENAME | \
> + FAMFS_OPT_CHMOD | FAMFS_OPT_CHOWN | \
> + FAMFS_OPT_TRUNCATE | FAMFS_OPT_UTIMES | \
> + FAMFS_OPT_WRITE | FAMFS_OPT_XATTR | \
> + FAMFS_OPT_MAP_CREATE)
> +
> +/**
> + * struct famfs_ioc_opts - operation-permission bitmap
> + * @opts: for GET, the current bitmap is returned here. For SET/CLEAR, the
> + * caller-supplied mask of bits to enable/disable on input, and the
> + * resulting bitmap on return.
> + */
> +struct famfs_ioc_opts {
> + __u64 opts;
> +};
> +
> #define FAMFSIOC_MAGIC 'u'
>
> /* famfs file ioctl opcodes */
> @@ -111,5 +153,8 @@ struct famfs_ioc_daxdev {
> */
> #define FAMFSIOC_MAP_CREATE _IOW(FAMFSIOC_MAGIC, 0x51, struct famfs_ioc_fmap_header)
> #define FAMFSIOC_DAXDEV_OPEN _IOW(FAMFSIOC_MAGIC, 0x52, struct famfs_ioc_daxdev)
> +#define FAMFSIOC_GET_OPTS _IOR(FAMFSIOC_MAGIC, 0x53, struct famfs_ioc_opts)
> +#define FAMFSIOC_SET_OPTS _IOWR(FAMFSIOC_MAGIC, 0x54, struct famfs_ioc_opts)
> +#define FAMFSIOC_CLEAR_OPTS _IOWR(FAMFSIOC_MAGIC, 0x55, struct famfs_ioc_opts)
>
> #endif /* FAMFS_IOCTL_H */
> --
> 2.53.0
>
>
>
next prev parent reply other threads:[~2026-08-06 5:31 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260803022730.75731-1-john@jagalactic.com>
2026-08-03 2:27 ` [PATCH V12 00/12] famfs: the Fabric-Attached Memory File System (standalone) John Groves
2026-08-03 2:28 ` [PATCH V12 01/12] dax: replace exported dax_dev_get() with non-allocating dax_dev_find() John Groves
2026-08-03 2:43 ` sashiko-bot
2026-08-03 19:13 ` Alison Schofield
2026-08-05 20:21 ` John Groves
2026-08-03 2:28 ` [PATCH V12 02/12] famfs: Module operations, fs_context, and mount John Groves
2026-08-03 2:49 ` sashiko-bot
2026-08-06 4:37 ` Darrick J. Wong
2026-08-06 13:22 ` John Groves
2026-08-03 2:28 ` [PATCH V12 03/12] famfs: Add daxdev table and dax notify_failure support John Groves
2026-08-03 2:45 ` sashiko-bot
2026-08-06 5:05 ` Darrick J. Wong
2026-08-06 13:36 ` John Groves
2026-08-03 2:28 ` [PATCH V12 04/12] famfs: Introduce inode_operations and super_operations John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:12 ` Darrick J. Wong
2026-08-06 16:31 ` John Groves
2026-08-03 2:29 ` [PATCH V12 05/12] famfs: Introduce file_operations read/write John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:14 ` Darrick J. Wong
2026-08-03 2:29 ` [PATCH V12 06/12] famfs: Introduce mmap and VM fault handling John Groves
2026-08-03 2:46 ` sashiko-bot
2026-08-06 5:16 ` Darrick J. Wong
2026-08-03 2:29 ` [PATCH V12 07/12] famfs: MAP_CREATE ioctl and fmap ingest (ABI 44) John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:24 ` Darrick J. Wong
2026-08-03 2:29 ` [PATCH V12 08/12] famfs: iomap_begin and file-to-dax offset resolution John Groves
2026-08-03 2:44 ` sashiko-bot
2026-08-06 5:28 ` Darrick J. Wong
2026-08-03 2:29 ` [PATCH V12 09/12] famfs: Register secondary daxdevs by path (FAMFSIOC_DAXDEV_OPEN) John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:29 ` Darrick J. Wong
2026-08-03 2:29 ` [PATCH V12 10/12] famfs: Add runtime operation-permission (opts) framework John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:31 ` Darrick J. Wong [this message]
2026-08-03 2:30 ` [PATCH V12 11/12] famfs: Report device capacity via statfs so df works John Groves
2026-08-03 2:58 ` sashiko-bot
2026-08-06 5:33 ` Darrick J. Wong
2026-08-03 2:30 ` [PATCH V12 12/12] famfs: Add documentation John Groves
2026-08-06 5:38 ` Darrick J. Wong
2026-08-03 8:52 ` [PATCH V12 00/12] famfs: the Fabric-Attached Memory File System (standalone) Amir Goldstein
2026-08-06 5:19 ` Matthew Wilcox
2026-08-06 5:34 ` Darrick J. Wong
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=20260806053100.GJ3560084@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=John@groves.net \
--cc=ackerleytng@google.com \
--cc=ajayjoshi@micron.com \
--cc=akpm@linux-foundation.org \
--cc=alison.schofield@intel.com \
--cc=amir73il@gmail.com \
--cc=arramesh@micron.com \
--cc=bagasdotme@gmail.com \
--cc=brauner@kernel.org \
--cc=bschubert@ddn.com \
--cc=chenlinxuan@uniontech.com \
--cc=corbet@lwn.net \
--cc=dave.jiang@intel.com \
--cc=david@kernel.org \
--cc=djbw@kernel.org \
--cc=enelsonmoore@gmail.com \
--cc=fuse-devel@lists.linux.dev \
--cc=gabewhigham@gmail.com \
--cc=giovanni.cabiddu@intel.com \
--cc=gourry@gourry.net \
--cc=gregkh@linuxfoundation.org \
--cc=haren@linux.ibm.com \
--cc=iweiny@kernel.org \
--cc=jack@suse.cz \
--cc=jake@lwn.net \
--cc=james.morse@arm.com \
--cc=jgroves@micron.com \
--cc=jic23@kernel.org \
--cc=jirislaby@kernel.org \
--cc=jlayton@kernel.org \
--cc=joannelkoong@gmail.com \
--cc=john@jagalactic.com \
--cc=josef@toxicpanda.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=miklos@szeredi.hu \
--cc=nvdimm@lists.linux.dev \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=rdunlap@infradead.org \
--cc=seanjc@google.com \
--cc=shajnocz@redhat.com \
--cc=shivankg@amd.com \
--cc=skhan@linuxfoundation.org \
--cc=tabba@google.com \
--cc=venkataravis@micron.com \
--cc=viro@zeniv.linux.org.uk \
--cc=vishal.l.verma@intel.com \
--cc=willy@infradead.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