[RFC/PATCH v2 bpf-next fanotify 1/7] fanotify: Introduce fanotify fastpath handler
Amir Goldstein
amir73il at gmail.com
Fri Nov 15 08:51:02 UTC 2024
On Thu, Nov 14, 2024 at 9:44 AM Song Liu <song at kernel.org> wrote:
>
> fanotify fastpath handler enables handling fanotify events within the
> kernel, and thus saves a trip to the user space. fanotify fastpath handler
> can be useful in many use cases. For example, if a user is only interested
> in events for some files in side a directory, a fastpath handler can be
> used to filter out irrelevant events.
>
> fanotify fastpath handler is attached to fsnotify_group. At most one
> fastpath handler can be attached to a fsnotify_group. The attach/detach
> of fastpath handlers are controlled by two new ioctls on the fanotify fds:
> FAN_IOC_ADD_FP and FAN_IOC_DEL_FP.
>
> fanotify fastpath handler is packaged in a kernel module. In the future,
> it is also possible to package fastpath handler in a BPF program. Since
> loading modules requires CAP_SYS_ADMIN, _loading_ fanotify fastpath
> handler in kernel modules is limited to CAP_SYS_ADMIN. However,
> non-SYS_CAP_ADMIN users can _attach_ fastpath handler loaded by sys admin
> to their fanotify fds. To make fanotify fastpath handler more useful
> for non-CAP_SYS_ADMIN users, a fastpath handler can take arguments at
> attach time.
>
> sysfs entry /sys/kernel/fanotify_fastpath is added to help users know
> which fastpath handlers are available. At the moment, files are added for
> each fastpath handler: flags, desc, and init_args.
>
> Signed-off-by: Song Liu <song at kernel.org>
> ---
> fs/notify/fanotify/Kconfig | 13 ++
> fs/notify/fanotify/Makefile | 1 +
> fs/notify/fanotify/fanotify.c | 29 +++
> fs/notify/fanotify/fanotify_fastpath.c | 282 +++++++++++++++++++++++++
> fs/notify/fanotify/fanotify_user.c | 7 +
> include/linux/fanotify.h | 131 ++++++++++++
> include/linux/fsnotify_backend.h | 4 +
> include/uapi/linux/fanotify.h | 25 +++
> 8 files changed, 492 insertions(+)
> create mode 100644 fs/notify/fanotify/fanotify_fastpath.c
>
> diff --git a/fs/notify/fanotify/Kconfig b/fs/notify/fanotify/Kconfig
> index 0e36aaf379b7..74677d3699a3 100644
> --- a/fs/notify/fanotify/Kconfig
> +++ b/fs/notify/fanotify/Kconfig
> @@ -24,3 +24,16 @@ config FANOTIFY_ACCESS_PERMISSIONS
> hierarchical storage management systems.
>
> If unsure, say N.
> +
> +config FANOTIFY_FASTPATH
> + bool "fanotify fastpath handler"
> + depends on FANOTIFY
> + default y
> + help
> + Say Y here if you want to use fanotify in kernel fastpath handler.
> + The fastpath handler can be implemented in a kernel module or a
> + BPF program. The fastpath handler can speed up fanotify in many
> + use cases. For example, when the listener is only interested in
> + a subset of events.
> +
> + If unsure, say Y.
> \ No newline at end of file
> diff --git a/fs/notify/fanotify/Makefile b/fs/notify/fanotify/Makefile
> index 25ef222915e5..543cb7aa08fc 100644
> --- a/fs/notify/fanotify/Makefile
> +++ b/fs/notify/fanotify/Makefile
> @@ -1,2 +1,3 @@
> # SPDX-License-Identifier: GPL-2.0-only
> obj-$(CONFIG_FANOTIFY) += fanotify.o fanotify_user.o
> +obj-$(CONFIG_FANOTIFY_FASTPATH) += fanotify_fastpath.o
> diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
> index 224bccaab4cc..b395b628a58b 100644
> --- a/fs/notify/fanotify/fanotify.c
> +++ b/fs/notify/fanotify/fanotify.c
> @@ -18,6 +18,8 @@
>
> #include "fanotify.h"
>
> +extern struct srcu_struct fsnotify_mark_srcu;
> +
> static bool fanotify_path_equal(const struct path *p1, const struct path *p2)
> {
> return p1->mnt == p2->mnt && p1->dentry == p2->dentry;
> @@ -888,6 +890,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
> struct fsnotify_event *fsn_event;
> __kernel_fsid_t fsid = {};
> u32 match_mask = 0;
> + struct fanotify_fastpath_hook *fp_hook __maybe_unused;
>
> BUILD_BUG_ON(FAN_ACCESS != FS_ACCESS);
> BUILD_BUG_ON(FAN_MODIFY != FS_MODIFY);
> @@ -933,6 +936,27 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
> if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS))
> fsid = fanotify_get_fsid(iter_info);
>
> +#ifdef CONFIG_FANOTIFY_FASTPATH
> + fp_hook = srcu_dereference(group->fanotify_data.fp_hook, &fsnotify_mark_srcu);
> + if (fp_hook) {
> + struct fanotify_fastpath_event fp_event = {
> + .mask = mask,
> + .data = data,
> + .data_type = data_type,
> + .dir = dir,
> + .file_name = file_name,
> + .fsid = &fsid,
> + .match_mask = match_mask,
> + };
> +
> + ret = fp_hook->ops->fp_handler(group, fp_hook, &fp_event);
> + if (ret == FAN_FP_RET_SKIP_EVENT) {
> + ret = 0;
> + goto finish;
> + }
> + }
> +#endif
> +
To me it makes sense that the fastpath module could also return a negative
(deny) result for permission events.
Is there a specific reason that you did not handle this or just didn't think
of this option?
Thanks,
Amir.
More information about the Linux-security-module-archive
mailing list