linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Song Liu <song@kernel.org>
To: bpf@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org
Cc: kernel-team@meta.com, andrii@kernel.org, eddyz87@gmail.com,
	ast@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev,
	viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz,
	kpsingh@kernel.org, mattbobrowski@google.com, amir73il@gmail.com,
	repnop@google.com, jlayton@kernel.org, josef@toxicpanda.com,
	mic@digikod.net, gnoack@google.com, Song Liu <song@kernel.org>
Subject: [RFC/PATCH v2 bpf-next fanotify 2/7] samples/fanotify: Add a sample fanotify fastpath handler
Date: Thu, 14 Nov 2024 00:43:40 -0800	[thread overview]
Message-ID: <20241114084345.1564165-3-song@kernel.org> (raw)
In-Reply-To: <20241114084345.1564165-1-song@kernel.org>

This fastpath handler monitors a subtree inside a mount point.
To use it:

[root] insmod ./fastpath-mod.ko
[root] mkdir -p /tmp/a/b/c/d
[root] ./fastpath-user /tmp/ /tmp/a/b &
[root] touch /tmp/xx      # Doesn't generate event
[root]# touch /tmp/a/xxa  # Doesn't generate event
[root]# touch /tmp/a/b/xxab      # Generates an event
Accessing file xxab   # this is the output from fastpath-user
[root@]# touch /tmp/a/b/c/xxabc  # Generates an event
Accessing file xxabc  # this is the output from fastpath-user

Signed-off-by: Song Liu <song@kernel.org>
---
 MAINTAINERS                      |   1 +
 samples/Kconfig                  |  20 +++++-
 samples/Makefile                 |   2 +-
 samples/fanotify/.gitignore      |   1 +
 samples/fanotify/Makefile        |   5 +-
 samples/fanotify/fastpath-mod.c  |  82 +++++++++++++++++++++++
 samples/fanotify/fastpath-user.c | 111 +++++++++++++++++++++++++++++++
 7 files changed, 219 insertions(+), 3 deletions(-)
 create mode 100644 samples/fanotify/fastpath-mod.c
 create mode 100644 samples/fanotify/fastpath-user.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7ad507f49324..8939a48b2d99 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8658,6 +8658,7 @@ S:	Maintained
 F:	fs/notify/fanotify/
 F:	include/linux/fanotify.h
 F:	include/uapi/linux/fanotify.h
+F:	samples/fanotify/
 
 FARADAY FOTG210 USB2 DUAL-ROLE CONTROLLER
 M:	Linus Walleij <linus.walleij@linaro.org>
diff --git a/samples/Kconfig b/samples/Kconfig
index b288d9991d27..b0d3dff48bb0 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -149,15 +149,33 @@ config SAMPLE_CONNECTOR
 	  with it.
 	  See also Documentation/driver-api/connector.rst
 
+config SAMPLE_FANOTIFY
+	bool "Build fanotify monitoring sample"
+	depends on FANOTIFY && CC_CAN_LINK && HEADERS_INSTALL
+	help
+	  When enabled, this builds samples for fanotify.
+	  There multiple samples for fanotify. Please see the
+	  following configs for more details of these
+	  samples.
+
 config SAMPLE_FANOTIFY_ERROR
 	bool "Build fanotify error monitoring sample"
-	depends on FANOTIFY && CC_CAN_LINK && HEADERS_INSTALL
+	depends on SAMPLE_FANOTIFY
 	help
 	  When enabled, this builds an example code that uses the
 	  FAN_FS_ERROR fanotify mechanism to monitor filesystem
 	  errors.
 	  See also Documentation/admin-guide/filesystem-monitoring.rst.
 
+config SAMPLE_FANOTIFY_FASTPATH
+	tristate "Build fanotify fastpath sample"
+	depends on SAMPLE_FANOTIFY && m
+	help
+	  When enabled, this builds kernel module that contains a
+	  fanotify fastpath handler.
+	  The fastpath handler filters out certain filename
+	  prefixes for the fanotify user.
+
 config SAMPLE_HIDRAW
 	bool "hidraw sample"
 	depends on CC_CAN_LINK && HEADERS_INSTALL
diff --git a/samples/Makefile b/samples/Makefile
index b85fa64390c5..108360972626 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -6,7 +6,7 @@ subdir-$(CONFIG_SAMPLE_ANDROID_BINDERFS) += binderfs
 subdir-$(CONFIG_SAMPLE_CGROUP) += cgroup
 obj-$(CONFIG_SAMPLE_CONFIGFS)		+= configfs/
 obj-$(CONFIG_SAMPLE_CONNECTOR)		+= connector/
-obj-$(CONFIG_SAMPLE_FANOTIFY_ERROR)	+= fanotify/
+obj-$(CONFIG_SAMPLE_FANOTIFY)		+= fanotify/
 subdir-$(CONFIG_SAMPLE_HIDRAW)		+= hidraw
 obj-$(CONFIG_SAMPLE_HW_BREAKPOINT)	+= hw_breakpoint/
 obj-$(CONFIG_SAMPLE_KDB)		+= kdb/
diff --git a/samples/fanotify/.gitignore b/samples/fanotify/.gitignore
index d74593e8b2de..306e1ddec4e0 100644
--- a/samples/fanotify/.gitignore
+++ b/samples/fanotify/.gitignore
@@ -1 +1,2 @@
 fs-monitor
+fastpath-user
diff --git a/samples/fanotify/Makefile b/samples/fanotify/Makefile
index e20db1bdde3b..f5bbd7380104 100644
--- a/samples/fanotify/Makefile
+++ b/samples/fanotify/Makefile
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
-userprogs-always-y += fs-monitor
+userprogs-always-$(CONFIG_SAMPLE_FANOTIFY_ERROR) += fs-monitor
 
 userccflags += -I usr/include -Wall
 
+obj-$(CONFIG_SAMPLE_FANOTIFY_FASTPATH) += fastpath-mod.o
+
+userprogs-always-$(CONFIG_SAMPLE_FANOTIFY_FASTPATH) += fastpath-user
diff --git a/samples/fanotify/fastpath-mod.c b/samples/fanotify/fastpath-mod.c
new file mode 100644
index 000000000000..7e2e1878f8e7
--- /dev/null
+++ b/samples/fanotify/fastpath-mod.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/fsnotify.h>
+#include <linux/fanotify.h>
+#include <linux/module.h>
+#include <linux/path.h>
+#include <linux/file.h>
+
+static int sample_fp_handler(struct fsnotify_group *group,
+			     struct fanotify_fastpath_hook *fp_hook,
+			     struct fanotify_fastpath_event *fp_event)
+{
+	struct dentry *dentry;
+	struct path *subtree;
+
+	dentry = fsnotify_data_dentry(fp_event->data, fp_event->data_type);
+	if (!dentry)
+		return FAN_FP_RET_SEND_TO_USERSPACE;
+
+	subtree = fp_hook->data;
+
+	if (is_subdir(dentry, subtree->dentry))
+		return FAN_FP_RET_SEND_TO_USERSPACE;
+	return FAN_FP_RET_SKIP_EVENT;
+}
+
+static int sample_fp_init(struct fanotify_fastpath_hook *fp_hook, void *args)
+{
+	struct path *subtree;
+	struct file *file;
+	int fd;
+
+	fd = *(int *)args;
+
+	file = fget(fd);
+	if (!file)
+		return -EBADF;
+	subtree = kzalloc(sizeof(struct path), GFP_KERNEL);
+	if (!subtree) {
+		fput(file);
+		return -ENOMEM;
+	}
+	path_get(&file->f_path);
+	*subtree = file->f_path;
+	fput(file);
+	fp_hook->data = subtree;
+	return 0;
+}
+
+static void sample_fp_free(struct fanotify_fastpath_hook *fp_hook)
+{
+	struct path *subtree = fp_hook->data;
+
+	path_put(subtree);
+	kfree(subtree);
+}
+
+static struct fanotify_fastpath_ops fan_fp_ignore_a_ops = {
+	.fp_handler = sample_fp_handler,
+	.fp_init = sample_fp_init,
+	.fp_free = sample_fp_free,
+	.name = "monitor-subtree",
+	.owner = THIS_MODULE,
+	.flags = FAN_FP_F_SYS_ADMIN_ONLY,
+	.desc = "only emit events under a subtree",
+	.init_args = "struct {\n\tint subtree_fd;\n};",
+};
+
+static int __init fanotify_fastpath_sample_init(void)
+{
+	return fanotify_fastpath_register(&fan_fp_ignore_a_ops);
+}
+static void __exit fanotify_fastpath_sample_exit(void)
+{
+	fanotify_fastpath_unregister(&fan_fp_ignore_a_ops);
+}
+
+module_init(fanotify_fastpath_sample_init);
+module_exit(fanotify_fastpath_sample_exit);
+
+MODULE_AUTHOR("Song Liu");
+MODULE_DESCRIPTION("Example fanotify fastpath handler");
+MODULE_LICENSE("GPL");
diff --git a/samples/fanotify/fastpath-user.c b/samples/fanotify/fastpath-user.c
new file mode 100644
index 000000000000..abe33a6b6b41
--- /dev/null
+++ b/samples/fanotify/fastpath-user.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/fanotify.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+static int total_event_cnt;
+
+static void handle_notifications(char *buffer, int len)
+{
+	struct fanotify_event_metadata *event =
+		(struct fanotify_event_metadata *) buffer;
+	struct fanotify_event_info_header *info;
+	struct fanotify_event_info_fid *fid;
+	struct file_handle *handle;
+	char *name;
+	int off;
+
+	for (; FAN_EVENT_OK(event, len); event = FAN_EVENT_NEXT(event, len)) {
+		for (off = sizeof(*event) ; off < event->event_len;
+		     off += info->len) {
+			info = (struct fanotify_event_info_header *)
+				((char *) event + off);
+			switch (info->info_type) {
+			case FAN_EVENT_INFO_TYPE_DFID_NAME:
+				fid = (struct fanotify_event_info_fid *) info;
+				handle = (struct file_handle *)&fid->handle;
+				name = (char *)handle + sizeof(*handle) + handle->handle_bytes;
+
+				printf("Accessing file %s\n", name);
+				total_event_cnt++;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	struct fanotify_fastpath_args args = {
+		.name = "monitor-subtree",
+		.version = 1,
+		.flags = 0,
+	};
+	char buffer[BUFSIZ];
+	const char *msg;
+	int fanotify_fd;
+	int subtree_fd;
+
+	if (argc < 3) {
+		printf("Usage:\n"
+		       "\t %s <mount point> <subtree to monitor>\n",
+			argv[0]);
+		return 1;
+	}
+
+	subtree_fd = open(argv[2], O_RDONLY | O_CLOEXEC);
+
+	if (subtree_fd < 0)
+		errx(1, "open subtree_fd");
+
+	args.init_args = (__u64)&subtree_fd;
+	args.init_args_size = sizeof(int);
+
+	fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_NAME | FAN_REPORT_DIR_FID,
+				    O_RDONLY);
+	if (fanotify_fd < 0) {
+		close(subtree_fd);
+		errx(1, "fanotify_init");
+	}
+
+	if (fanotify_mark(fanotify_fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM,
+			  FAN_OPEN | FAN_ONDIR | FAN_EVENT_ON_CHILD,
+			  AT_FDCWD, argv[1])) {
+		msg = "fanotify_mark";
+		goto err_out;
+	}
+
+	if (ioctl(fanotify_fd, FAN_IOC_ADD_FP, &args)) {
+		msg = "ioctl";
+		goto err_out;
+	}
+
+	while (total_event_cnt < 10) {
+		int n = read(fanotify_fd, buffer, BUFSIZ);
+
+		if (n < 0) {
+			msg = "read";
+			goto err_out;
+		}
+
+		handle_notifications(buffer, n);
+	}
+
+	ioctl(fanotify_fd, FAN_IOC_DEL_FP);
+	close(fanotify_fd);
+	close(subtree_fd);
+	return 0;
+
+err_out:
+	close(fanotify_fd);
+	close(subtree_fd);
+	errx(1, msg);
+	return 0;
+}
-- 
2.43.5


  parent reply	other threads:[~2024-11-14  8:44 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-14  8:43 [RFC/PATCH v2 bpf-next fanotify 0/7] Fanotify fastpath handler Song Liu
2024-11-14  8:43 ` [RFC/PATCH v2 bpf-next fanotify 1/7] fanotify: Introduce fanotify " Song Liu
2024-11-15  8:51   ` Amir Goldstein
2024-11-15 17:11     ` Song Liu
2024-11-15 17:32       ` Amir Goldstein
2024-11-14  8:43 ` Song Liu [this message]
2024-11-14  8:43 ` [RFC/PATCH v2 bpf-next fanotify 3/7] bpf: Make bpf inode storage available to tracing programs Song Liu
2024-11-14  8:43 ` [RFC/PATCH v2 bpf-next fanotify 4/7] bpf: fs: Add three kfuncs Song Liu
2024-11-14  8:43 ` [RFC/PATCH v2 bpf-next fanotify 5/7] bpf: Allow bpf map hold reference on dentry Song Liu
2024-11-14  8:43 ` [RFC/PATCH v2 bpf-next fanotify 6/7] fanotify: Enable bpf based fanotify fastpath handler Song Liu
2024-11-14  8:43 ` [RFC/PATCH v2 bpf-next fanotify 7/7] selftests/bpf: Add test for BPF " Song Liu
2024-11-14 20:14   ` Alexei Starovoitov
2024-11-14 23:02     ` Song Liu
2024-11-15  0:41       ` Alexei Starovoitov
2024-11-15  1:10         ` Song Liu
2024-11-15  1:31           ` Alexei Starovoitov
2024-11-15  7:01             ` Song Liu
2024-11-15 19:41               ` Alexei Starovoitov
2024-11-15 21:05                 ` Song Liu
2024-11-18 20:51                   ` Song Liu
2024-11-19  0:10                     ` Alexei Starovoitov
2024-11-19  1:10                       ` Song Liu
2024-11-19  7:59                         ` Amir Goldstein
2024-11-19  8:35                           ` Song Liu
2024-11-15  7:26     ` Amir Goldstein
2024-11-15 20:04       ` Alexei Starovoitov

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=20241114084345.1564165-3-song@kernel.org \
    --to=song@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brauner@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=gnoack@google.com \
    --cc=jack@suse.cz \
    --cc=jlayton@kernel.org \
    --cc=josef@toxicpanda.com \
    --cc=kernel-team@meta.com \
    --cc=kpsingh@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=mattbobrowski@google.com \
    --cc=mic@digikod.net \
    --cc=repnop@google.com \
    --cc=viro@zeniv.linux.org.uk \
    /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;
as well as URLs for NNTP newsgroup(s).