diff mbox series

inotify: Added pid and uid information in inotify event.

Message ID 20240708101257.3367614-1-lizhigang.1220@bytedance.com (mailing list archive)
State New
Headers show
Series inotify: Added pid and uid information in inotify event. | expand

Commit Message

lizhigang July 8, 2024, 10:12 a.m. UTC
The inotify event only contains file name information. Sometimes we
also want to know user or process information,such as who created
or deleted a file. This patch adds information such as COMM, PID
and UID to the end of filename, which allowing us to implement
this function without modifying the current Inotify mechanism.

This function is not enabled by default and is enabled through an IOCTL

When enable this function, inotify_event->name will contain comm,
pid and uid information, with the following specific format:

filename____XXX,pid:YYY__uid:ZZZ

Pseudo code to enable this function:
int rc, bytes_to_read, inotify_fd;

inotify_fd = inotify_init();
...
// enable padding uid,pid information
rc = ioctl( inotify_fd, TIOCLINUX, &bytes_to_read);

Log example with this function:
CREATE,ISDIR /home/peter/testdir____mkdir,pid:3626__uid:1000
CREATE /home/peter/test.txt____bash,pid:3582__uid:1000
OPEN /home/peter/test.txt____bash,pid:3582__uid:1000
MODIFY /home/peter/test.txt____bash,pid:3582__uid:1000
CLOSE_WRITE,CLOSE /home/peter/test.txt____bash,pid:3582__uid:1000
OPEN,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
ACCESS,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
ACCESS,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
CLOSE_NOWRITE,CLOSE,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
DELETE,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000

Signed-off-by: lizhigang <lizhigang.1220@bytedance.com>
---
 fs/notify/inotify/Kconfig            | 24 +++++++++++++++++++++++
 fs/notify/inotify/inotify_fsnotify.c | 29 +++++++++++++++++++++++++++-
 fs/notify/inotify/inotify_user.c     | 11 ++++++++++-
 include/linux/fsnotify_backend.h     |  5 ++++-
 4 files changed, 66 insertions(+), 3 deletions(-)

Comments

Amir Goldstein July 8, 2024, 4:29 p.m. UTC | #1
On Mon, Jul 8, 2024 at 1:13 PM lizhigang <lizhigang.1220@bytedance.com> wrote:
>
> The inotify event only contains file name information. Sometimes we
> also want to know user or process information,such as who created
> or deleted a file. This patch adds information such as COMM, PID
> and UID to the end of filename, which allowing us to implement
> this function without modifying the current Inotify mechanism.
>
> This function is not enabled by default and is enabled through an IOCTL
>
> When enable this function, inotify_event->name will contain comm,
> pid and uid information, with the following specific format:
>
> filename____XXX,pid:YYY__uid:ZZZ
>
> Pseudo code to enable this function:
> int rc, bytes_to_read, inotify_fd;
>
> inotify_fd = inotify_init();
> ...
> // enable padding uid,pid information
> rc = ioctl( inotify_fd, TIOCLINUX, &bytes_to_read);
>
> Log example with this function:
> CREATE,ISDIR /home/peter/testdir____mkdir,pid:3626__uid:1000
> CREATE /home/peter/test.txt____bash,pid:3582__uid:1000
> OPEN /home/peter/test.txt____bash,pid:3582__uid:1000
> MODIFY /home/peter/test.txt____bash,pid:3582__uid:1000
> CLOSE_WRITE,CLOSE /home/peter/test.txt____bash,pid:3582__uid:1000
> OPEN,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
> ACCESS,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
> ACCESS,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
> CLOSE_NOWRITE,CLOSE,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
> DELETE,ISDIR /home/peter/testdir____rm,pid:3640__uid:1000
>

Please take a look at https://man7.org/linux/man-pages/man7/fanotify.7.html

It already reports pid and the event format already supports info extensions,
so adding uid would be easy (opt-in not via ioctl but via
fanotify_init() flags),
if you can justify the use case for this feature.

There are still some differences between inotify and fanotify that
could make people want to use inotify, but generally, I would not like
to extend inotify API like this.

Thanks,
Amir.
diff mbox series

Patch

diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig
index 1cc8be25df7e..1b2d6aef5dda 100644
--- a/fs/notify/inotify/Kconfig
+++ b/fs/notify/inotify/Kconfig
@@ -15,3 +15,27 @@  config INOTIFY_USER
 	  For more information, see <file:Documentation/filesystems/inotify.rst>
 
 	  If unsure, say Y.
+
+config INOTIFY_NAME_UID
+	bool "Inotify filename with uid information"
+	default n
+	help
+	  Say Y here to enable inotify file name with uid, pid and comm information.
+	  Added the current context information with file name.
+	  The inotify event only contains file name information. Sometimes we
+	  also want to know user or process information,such as who created
+	  or deleted a file. This patch adds information such as COMM, PID
+	  and UID to the end of filename, which allowing us to implement
+	  this function without modifying the current Inotify mechanism.
+	  This function is not enabled by default and is enabled through an IOCTL
+	  When enable this function, inotify_event->name will contain comm,
+	  pid and uid information, with the following specific format:
+	  filename____XXX,pid:YYY__uid:ZZZ
+	  Pseudo code to enable this function:
+	  int rc, bytes_to_read, inotify_fd;
+	  inotify_fd = inotify_init();
+	  ...
+	  // enable padding uid,pid information
+	  rc = ioctl( inotify_fd, TIOCLINUX, &bytes_to_read);
+
+	  If unsure, say n.
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 993375f0db67..d6d2d11f1e8c 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -23,9 +23,16 @@ 
 #include <linux/sched.h>
 #include <linux/sched/user.h>
 #include <linux/sched/mm.h>
+#ifdef CONFIG_INOTIFY_NAME_UID
+#include <linux/cred.h>
+#endif
 
 #include "inotify.h"
 
+#ifdef CONFIG_INOTIFY_NAME_UID
+#define UID_INFO_MAX_SIZE   64
+#endif
+
 /*
  * Check if 2 events contain the same information.
  */
@@ -68,9 +75,21 @@  int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
 	int len = 0, wd;
 	int alloc_len = sizeof(struct inotify_event_info);
 	struct mem_cgroup *old_memcg;
+#ifdef CONFIG_INOTIFY_NAME_UID
+	char uid_info[UID_INFO_MAX_SIZE];
+	struct user_struct *user_info;
+#endif
 
 	if (name) {
 		len = name->len;
+#ifdef CONFIG_INOTIFY_NAME_UID
+		if (group->user_flag & USER_FLAG_TASK_INFO) {
+			user_info = current_user();
+			sprintf(uid_info, "____%s,pid:%d__uid:%d",
+				current->comm, current->pid, user_info->uid.val);
+			len += strlen(uid_info);
+		}
+#endif
 		alloc_len += len + 1;
 	}
 
@@ -120,9 +139,17 @@  int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
 	event->wd = wd;
 	event->sync_cookie = cookie;
 	event->name_len = len;
+#ifdef CONFIG_INOTIFY_NAME_UID
+	if (len) {
+		if (group->user_flag & USER_FLAG_TASK_INFO)
+			sprintf(event->name, "%s%s", name->name, uid_info);
+		else
+			strcpy(event->name, name->name);
+	}
+#else
 	if (len)
 		strcpy(event->name, name->name);
-
+#endif
 	ret = fsnotify_add_event(group, fsn_event, inotify_merge);
 	if (ret) {
 		/* Our event wasn't used in the end. Free it. */
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 4ffc30606e0b..f1538cafdc1d 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -349,6 +349,13 @@  static long inotify_ioctl(struct file *file, unsigned int cmd,
 		}
 		break;
 #endif /* CONFIG_CHECKPOINT_RESTORE */
+
+#ifdef CONFIG_INOTIFY_NAME_UID
+	case TIOCLINUX:
+		group->user_flag |=  USER_FLAG_TASK_INFO;
+		ret = 0;
+		break;
+#endif /* CONFIG_INOTIFY_NAME_UID */
 	}
 
 	return ret;
@@ -674,7 +681,9 @@  static struct fsnotify_group *inotify_new_group(unsigned int max_events)
 
 	group->max_events = max_events;
 	group->memcg = get_mem_cgroup_from_mm(current->mm);
-
+#ifdef CONFIG_INOTIFY_NAME_UID
+	group->user_flag = 0;
+#endif
 	spin_lock_init(&group->inotify_data.idr_lock);
 	idr_init(&group->inotify_data.idr);
 	group->inotify_data.ucounts = inc_ucount(current_user_ns(),
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 4dd6143db271..d4f57b16f1d3 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -234,7 +234,10 @@  struct fsnotify_group {
 						 * full */
 
 	struct mem_cgroup *memcg;	/* memcg to charge allocations */
-
+#ifdef CONFIG_INOTIFY_NAME_UID
+	#define USER_FLAG_TASK_INFO     1   /* output task infor with filename */
+	unsigned int user_flag;             /* user added control flag */
+#endif
 	/* groups can define private fields here or use the void *private */
 	union {
 		void *private;