diff mbox series

[03/10] fsnotify: generate pre-content permission event on open

Message ID c105b804f1f6e14d7536b98fea428211b131473a.1721931241.git.josef@toxicpanda.com (mailing list archive)
State New
Headers show
Series fanotify: add pre-content hooks | expand

Commit Message

Josef Bacik July 25, 2024, 6:19 p.m. UTC
From: Amir Goldstein <amir73il@gmail.com>

FS_PRE_ACCESS or FS_PRE_MODIFY will be generated on open depending on
file open mode.  The pre-content event will be generated in addition to
FS_OPEN_PERM, but without sb_writers held and after file was truncated
in case file was opened with O_CREAT and/or O_TRUNC.

The event will have a range info of (0..0) to provide an opportunity
to fill entire file content on open.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/namei.c               |  9 +++++++++
 include/linux/fsnotify.h | 10 +++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

Comments

Jan Kara Aug. 1, 2024, 5:01 p.m. UTC | #1
On Thu 25-07-24 14:19:40, Josef Bacik wrote:
> From: Amir Goldstein <amir73il@gmail.com>
> 
> FS_PRE_ACCESS or FS_PRE_MODIFY will be generated on open depending on
> file open mode.  The pre-content event will be generated in addition to
> FS_OPEN_PERM, but without sb_writers held and after file was truncated
> in case file was opened with O_CREAT and/or O_TRUNC.
> 
> The event will have a range info of (0..0) to provide an opportunity
> to fill entire file content on open.
> 
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>

...

> @@ -176,10 +180,14 @@ static inline int fsnotify_file_area_perm(struct file *file, int perm_mask,
>  
>  /*
>   * fsnotify_file_perm - permission hook before file access
> + *
> + * Called from read()/write() with perm_mas MAY_READ/MAY_WRITE.
					^^^ perm_mask

> + * Called from open() with MAY_OPEN in addition to fsnotify_open_perm(),
> + * but without sb_writers held and after the file was truncated.

This sentence is a bit confusing to me (although I think I understand what
you want to say). How about just:

 * Called from open() with MAY_OPEN without sb_writers held and after the
 * file was truncated. Note that this is a different event from
 * fsnotify_open_perm().

>   */
>  static inline int fsnotify_file_perm(struct file *file, int perm_mask)
>  {
> -	return fsnotify_file_area_perm(file, perm_mask, NULL, 0);
> +	return fsnotify_file_area_perm(file, perm_mask, &file->f_pos, 0);
>  }

								Honza
Amir Goldstein Aug. 3, 2024, 4:53 p.m. UTC | #2
On Thu, Aug 1, 2024 at 7:01 PM Jan Kara <jack@suse.cz> wrote:
>
> On Thu 25-07-24 14:19:40, Josef Bacik wrote:
> > From: Amir Goldstein <amir73il@gmail.com>
> >
> > FS_PRE_ACCESS or FS_PRE_MODIFY will be generated on open depending on
> > file open mode.  The pre-content event will be generated in addition to
> > FS_OPEN_PERM, but without sb_writers held and after file was truncated
> > in case file was opened with O_CREAT and/or O_TRUNC.
> >
> > The event will have a range info of (0..0) to provide an opportunity
> > to fill entire file content on open.
> >
> > Signed-off-by: Amir Goldstein <amir73il@gmail.com>
>
> ...
>
> > @@ -176,10 +180,14 @@ static inline int fsnotify_file_area_perm(struct file *file, int perm_mask,
> >
> >  /*
> >   * fsnotify_file_perm - permission hook before file access
> > + *
> > + * Called from read()/write() with perm_mas MAY_READ/MAY_WRITE.
>                                         ^^^ perm_mask
>
> > + * Called from open() with MAY_OPEN in addition to fsnotify_open_perm(),
> > + * but without sb_writers held and after the file was truncated.
>
> This sentence is a bit confusing to me (although I think I understand what
> you want to say). How about just:
>
>  * Called from open() with MAY_OPEN without sb_writers held and after the
>  * file was truncated. Note that this is a different event from
>  * fsnotify_open_perm().

sounds good.

Thanks,
Amir,
diff mbox series

Patch

diff --git a/fs/namei.c b/fs/namei.c
index 3a4c40e12f78..c16487e3742d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3735,6 +3735,15 @@  static int do_open(struct nameidata *nd,
 	}
 	if (do_truncate)
 		mnt_drop_write(nd->path.mnt);
+
+	/*
+	 * This permission hook is different than fsnotify_open_perm() hook.
+	 * This is a pre-content hook that is called without sb_writers held
+	 * and after the file was truncated.
+	 */
+	if (!error)
+		error = fsnotify_file_perm(file, MAY_OPEN);
+
 	return error;
 }
 
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 028ce807805a..4103dd797477 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -168,6 +168,10 @@  static inline int fsnotify_file_area_perm(struct file *file, int perm_mask,
 		fsnotify_mask = FS_PRE_MODIFY;
 	else if (perm_mask & MAY_READ)
 		fsnotify_mask = FS_PRE_ACCESS;
+	else if (perm_mask & MAY_OPEN && file->f_mode & FMODE_WRITER)
+		fsnotify_mask = FS_PRE_MODIFY;
+	else if (perm_mask & MAY_OPEN)
+		fsnotify_mask = FS_PRE_ACCESS;
 	else
 		return 0;
 
@@ -176,10 +180,14 @@  static inline int fsnotify_file_area_perm(struct file *file, int perm_mask,
 
 /*
  * fsnotify_file_perm - permission hook before file access
+ *
+ * Called from read()/write() with perm_mas MAY_READ/MAY_WRITE.
+ * Called from open() with MAY_OPEN in addition to fsnotify_open_perm(),
+ * but without sb_writers held and after the file was truncated.
  */
 static inline int fsnotify_file_perm(struct file *file, int perm_mask)
 {
-	return fsnotify_file_area_perm(file, perm_mask, NULL, 0);
+	return fsnotify_file_area_perm(file, perm_mask, &file->f_pos, 0);
 }
 
 /*