Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b0a383a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'fsnotify_for_v4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull fsnotify updates from Jan Kara:
 "Support for new FAN_OPEN_EXEC event and couple of cleanups around
  fsnotify"

* tag 'fsnotify_for_v4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  fanotify: Use inode_is_open_for_write
  fanotify: Make sure to check event_len when copying
  fsnotify/fdinfo: include fdinfo.h for inotify_show_fdinfo()
  fanotify: introduce new event mask FAN_OPEN_EXEC_PERM
  fsnotify: refactor fsnotify_parent()/fsnotify() paired calls when event is on path
  fanotify: introduce new event mask FAN_OPEN_EXEC
  fanotify: return only user requested event types in event mask
parents 4de3aea3 ac9498d6
Loading
Loading
Loading
Loading
+19 −13
Original line number Original line Diff line number Diff line
@@ -89,7 +89,13 @@ static int fanotify_get_response(struct fsnotify_group *group,
	return ret;
	return ret;
}
}


static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
/*
 * This function returns a mask for an event that only contains the flags
 * that have been specifically requested by the user. Flags that may have
 * been included within the event mask, but have not been explicitly
 * requested by the user, will not be present in the returned mask.
 */
static u32 fanotify_group_event_mask(struct fsnotify_iter_info *iter_info,
				       u32 event_mask, const void *data,
				       u32 event_mask, const void *data,
				       int data_type)
				       int data_type)
{
{
@@ -101,14 +107,14 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
	pr_debug("%s: report_mask=%x mask=%x data=%p data_type=%d\n",
	pr_debug("%s: report_mask=%x mask=%x data=%p data_type=%d\n",
		 __func__, iter_info->report_mask, event_mask, data, data_type);
		 __func__, iter_info->report_mask, event_mask, data, data_type);


	/* if we don't have enough info to send an event to userspace say no */
	/* If we don't have enough info to send an event to userspace say no */
	if (data_type != FSNOTIFY_EVENT_PATH)
	if (data_type != FSNOTIFY_EVENT_PATH)
		return false;
		return 0;


	/* sorry, fanotify only gives a damn about files and dirs */
	/* Sorry, fanotify only gives a damn about files and dirs */
	if (!d_is_reg(path->dentry) &&
	if (!d_is_reg(path->dentry) &&
	    !d_can_lookup(path->dentry))
	    !d_can_lookup(path->dentry))
		return false;
		return 0;


	fsnotify_foreach_obj_type(type) {
	fsnotify_foreach_obj_type(type) {
		if (!fsnotify_iter_should_report_type(iter_info, type))
		if (!fsnotify_iter_should_report_type(iter_info, type))
@@ -129,13 +135,10 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,


	if (d_is_dir(path->dentry) &&
	if (d_is_dir(path->dentry) &&
	    !(marks_mask & FS_ISDIR & ~marks_ignored_mask))
	    !(marks_mask & FS_ISDIR & ~marks_ignored_mask))
		return false;
		return 0;

	if (event_mask & FANOTIFY_OUTGOING_EVENTS &
	    marks_mask & ~marks_ignored_mask)
		return true;


	return false;
	return event_mask & FANOTIFY_OUTGOING_EVENTS & marks_mask &
		~marks_ignored_mask;
}
}


struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
@@ -207,10 +210,13 @@ static int fanotify_handle_event(struct fsnotify_group *group,
	BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM);
	BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM);
	BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
	BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
	BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
	BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
	BUILD_BUG_ON(FAN_OPEN_EXEC != FS_OPEN_EXEC);
	BUILD_BUG_ON(FAN_OPEN_EXEC_PERM != FS_OPEN_EXEC_PERM);


	BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 10);
	BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 12);


	if (!fanotify_should_send_event(iter_info, mask, data, data_type))
	mask = fanotify_group_event_mask(iter_info, mask, data, data_type);
	if (!mask)
		return 0;
		return 0;


	pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
	pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
+9 −3
Original line number Original line Diff line number Diff line
@@ -206,7 +206,7 @@ static int process_access_response(struct fsnotify_group *group,


static ssize_t copy_event_to_user(struct fsnotify_group *group,
static ssize_t copy_event_to_user(struct fsnotify_group *group,
				  struct fsnotify_event *event,
				  struct fsnotify_event *event,
				  char __user *buf)
				  char __user *buf, size_t count)
{
{
	struct fanotify_event_metadata fanotify_event_metadata;
	struct fanotify_event_metadata fanotify_event_metadata;
	struct file *f;
	struct file *f;
@@ -220,6 +220,12 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,


	fd = fanotify_event_metadata.fd;
	fd = fanotify_event_metadata.fd;
	ret = -EFAULT;
	ret = -EFAULT;
	/*
	 * Sanity check copy size in case get_one_event() and
	 * fill_event_metadata() event_len sizes ever get out of sync.
	 */
	if (WARN_ON_ONCE(fanotify_event_metadata.event_len > count))
		goto out_close_fd;
	if (copy_to_user(buf, &fanotify_event_metadata,
	if (copy_to_user(buf, &fanotify_event_metadata,
			 fanotify_event_metadata.event_len))
			 fanotify_event_metadata.event_len))
		goto out_close_fd;
		goto out_close_fd;
@@ -295,7 +301,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
			continue;
			continue;
		}
		}


		ret = copy_event_to_user(group, kevent, buf);
		ret = copy_event_to_user(group, kevent, buf, count);
		if (unlikely(ret == -EOPENSTALE)) {
		if (unlikely(ret == -EOPENSTALE)) {
			/*
			/*
			 * We cannot report events with stale fd so drop it.
			 * We cannot report events with stale fd so drop it.
@@ -669,7 +675,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
	 */
	 */
	if ((flags & FAN_MARK_IGNORED_MASK) &&
	if ((flags & FAN_MARK_IGNORED_MASK) &&
	    !(flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
	    !(flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
	    (atomic_read(&inode->i_writecount) > 0))
	    inode_is_open_for_write(inode))
		return 0;
		return 0;


	return fanotify_add_mark(group, &inode->i_fsnotify_marks,
	return fanotify_add_mark(group, &inode->i_fsnotify_marks,
+1 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/exportfs.h>
#include <linux/exportfs.h>


#include "inotify/inotify.h"
#include "inotify/inotify.h"
#include "fdinfo.h"
#include "fsnotify.h"
#include "fsnotify.h"


#if defined(CONFIG_PROC_FS)
#if defined(CONFIG_PROC_FS)
+1 −1
Original line number Original line Diff line number Diff line
@@ -401,7 +401,7 @@ static __init int fsnotify_init(void)
{
{
	int ret;
	int ret;


	BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 23);
	BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 25);


	ret = init_srcu_struct(&fsnotify_mark_srcu);
	ret = init_srcu_struct(&fsnotify_mark_srcu);
	if (ret)
	if (ret)
+3 −2
Original line number Original line Diff line number Diff line
@@ -37,10 +37,11 @@


/* Events that user can request to be notified on */
/* Events that user can request to be notified on */
#define FANOTIFY_EVENTS		(FAN_ACCESS | FAN_MODIFY | \
#define FANOTIFY_EVENTS		(FAN_ACCESS | FAN_MODIFY | \
				 FAN_CLOSE | FAN_OPEN)
				 FAN_CLOSE | FAN_OPEN | FAN_OPEN_EXEC)


/* Events that require a permission response from user */
/* Events that require a permission response from user */
#define FANOTIFY_PERM_EVENTS	(FAN_OPEN_PERM | FAN_ACCESS_PERM)
#define FANOTIFY_PERM_EVENTS	(FAN_OPEN_PERM | FAN_ACCESS_PERM | \
				 FAN_OPEN_EXEC_PERM)


/* Extra flags that may be reported with event or control handling of events */
/* Extra flags that may be reported with event or control handling of events */
#define FANOTIFY_EVENT_FLAGS	(FAN_EVENT_ON_CHILD | FAN_ONDIR)
#define FANOTIFY_EVENT_FLAGS	(FAN_EVENT_ON_CHILD | FAN_ONDIR)
Loading