All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/20] fanotify: allow fanotify to be built
@ 2010-10-28 21:31 Eric Paris
  2010-10-28 21:31 ` [PATCH 02/20] fsnotify: implement ordering between notifiers Eric Paris
                   ` (18 more replies)
  0 siblings, 19 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:31 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

We disabled the ability to build fanotify in commit 7c5347733dcc4ba0ba.
This reverts that commit and allows people to build fanotify.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/Kconfig    |    2 +-
 include/linux/Kbuild |    1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/fs/notify/Kconfig b/fs/notify/Kconfig
index b388443..22c629e 100644
--- a/fs/notify/Kconfig
+++ b/fs/notify/Kconfig
@@ -3,4 +3,4 @@ config FSNOTIFY
 
 source "fs/notify/dnotify/Kconfig"
 source "fs/notify/inotify/Kconfig"
-#source "fs/notify/fanotify/Kconfig"
+source "fs/notify/fanotify/Kconfig"
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 831c463..c7fbf29 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -118,6 +118,7 @@ header-y += eventpoll.h
 header-y += ext2_fs.h
 header-y += fadvise.h
 header-y += falloc.h
+header-y += fanotify.h
 header-y += fb.h
 header-y += fcntl.h
 header-y += fd.h


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 02/20] fsnotify: implement ordering between notifiers
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
@ 2010-10-28 21:31 ` Eric Paris
  2010-10-28 21:31 ` [PATCH 03/20] fanotify: implement fanotify listener ordering Eric Paris
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:31 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fanotify needs to be able to specify that some groups get events before
others.  They use this idea to make sure that a hierarchical storage
manager gets access to files before programs which actually use them.  This
is purely infrastructure.  Everything will have a priority of 0, but the
infrastructure will exist for it to be non-zero.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/inode_mark.c           |    9 +++++++--
 fs/notify/vfsmount_mark.c        |    6 +++++-
 include/linux/fsnotify_backend.h |    8 ++++++++
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 21ed106..4c29fcf 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -177,7 +177,8 @@ void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *mark,
  * Attach an initialized mark to a given inode.
  * These marks may be used for the fsnotify backend to determine which
  * event types should be delivered to which group and for which inodes.  These
- * marks are ordered according to the group's location in memory.
+ * marks are ordered according to priority, highest number first, and then by
+ * the group's location in memory.
  */
 int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
 			    struct fsnotify_group *group, struct inode *inode,
@@ -211,7 +212,11 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
 			goto out;
 		}
 
-		if (mark->group < lmark->group)
+		if (mark->group->priority < lmark->group->priority)
+			continue;
+
+		if ((mark->group->priority == lmark->group->priority) &&
+		    (mark->group < lmark->group))
 			continue;
 
 		hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list);
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c
index 56772b5..85eebff 100644
--- a/fs/notify/vfsmount_mark.c
+++ b/fs/notify/vfsmount_mark.c
@@ -169,7 +169,11 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
 			goto out;
 		}
 
-		if (mark->group < lmark->group)
+		if (mark->group->priority < lmark->group->priority)
+			continue;
+
+		if ((mark->group->priority == lmark->group->priority) &&
+		    (mark->group < lmark->group))
 			continue;
 
 		hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index e40190d..8253295 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -129,6 +129,14 @@ struct fsnotify_group {
 	wait_queue_head_t notification_waitq;	/* read() on the notification file blocks on this waitq */
 	unsigned int q_len;			/* events on the queue */
 	unsigned int max_events;		/* maximum events allowed on the list */
+	/*
+	 * Valid fsnotify group priorities.  Events are send in order from highest
+	 * priority to lowest priority.  We default to the lowest priority.
+	 */
+	#define FS_PRIO_0	0 /* normal notifiers, no permissions */
+	#define FS_PRIO_1	1 /* fanotify content based access control */
+	#define FS_PRIO_2	2 /* fanotify pre-content access */
+	unsigned int priority;
 
 	/* stores all fastpath marks assoc with this group so they can be cleaned on unregister */
 	spinlock_t mark_lock;		/* protect marks_list */


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 03/20] fanotify: implement fanotify listener ordering
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
  2010-10-28 21:31 ` [PATCH 02/20] fsnotify: implement ordering between notifiers Eric Paris
@ 2010-10-28 21:31 ` Eric Paris
  2010-10-29 15:01   ` John Stoffel
  2010-10-28 21:31 ` [PATCH 04/20] fanotify: use __aligned_u64 in fanotify userspace metadata Eric Paris
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:31 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

The fanotify listeners needs to be able to specify what types of operations
they are going to perform so they can be ordered appropriately between other
listeners doing other types of operations.  They need this to be able to make
sure that things like hierarchichal storage managers will get access to inodes
before processes which need the data.  This patch defines 3 possible uses
which groups must indicate in the fanotify_init() flags.

FAN_CLASS_PRE_CONTENT
FAN_CLASS_CONTENT
FAN_CLASS_NOTIF

Groups will receive notification in that order.  The order between 2 groups in
the same class is undeterministic.

FAN_CLASS_PRE_CONTENT is intended to be used by listeners which need access to
the inode before they are certain that the inode contains it's final data.  A
hierarchical storage manager should choose to use this class.

FAN_CLASS_CONTENT is intended to be used by listeners which need access to the
inode after it contains its intended contents.  This would be the appropriate
level for an AV solution or document control system.

FAN_CLASS_NOTIF is intended for normal async notification about access, much the
same as inotify and dnotify.  Syncronous permissions events are not permitted
at this class.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |   25 ++++++++++++++++++++++++-
 include/linux/fanotify.h           |   11 ++++++++++-
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index bbcb98e..1c09e63 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -664,6 +664,20 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 	init_waitqueue_head(&group->fanotify_data.access_waitq);
 	INIT_LIST_HEAD(&group->fanotify_data.access_list);
 #endif
+	switch (flags & FAN_ALL_CLASS_BITS) {
+	case FAN_CLASS_NOTIF:
+		group->priority = FS_PRIO_0;
+		break;
+	case FAN_CLASS_CONTENT:
+		group->priority = FS_PRIO_1;
+		break;
+	case FAN_CLASS_PRE_CONTENT:
+		group->priority = FS_PRIO_2;
+		break;
+	default:
+		fd = -EINVAL;
+		goto out_put_group;
+	}
 
 	fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
 	if (fd < 0)
@@ -719,6 +733,16 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
 	ret = -EINVAL;
 	if (unlikely(filp->f_op != &fanotify_fops))
 		goto fput_and_out;
+	group = filp->private_data;
+
+	/*
+	 * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF.  These are not
+	 * allowed to set permissions events.
+	 */
+	ret = -EINVAL;
+	if (mask & FAN_ALL_PERM_EVENTS &&
+	    group->priority == FS_PRIO_0)
+		goto fput_and_out;
 
 	ret = fanotify_find_path(dfd, pathname, &path, flags);
 	if (ret)
@@ -729,7 +753,6 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
 		inode = path.dentry->d_inode;
 	else
 		mnt = path.mnt;
-	group = filp->private_data;
 
 	/* create/update an inode mark */
 	switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 63531a6..2c89ce7 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -25,7 +25,16 @@
 #define FAN_CLOEXEC		0x00000001
 #define FAN_NONBLOCK		0x00000002
 
-#define FAN_ALL_INIT_FLAGS	(FAN_CLOEXEC | FAN_NONBLOCK)
+/* These are NOT bitwise flags.  Both bits are used togther.  */
+#define FAN_CLASS_NOTIF		0x00000000
+#define FAN_CLASS_CONTENT	0x00000004
+#define FAN_CLASS_PRE_CONTENT	0x00000008
+
+#define FAN_ALL_CLASS_BITS	(FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
+				 FAN_CLASS_PRE_CONTENT)
+
+#define FAN_ALL_INIT_FLAGS	(FAN_CLOEXEC | FAN_NONBLOCK | \
+				 FAN_ALL_CLASS_BITS)
 
 /* flags used for fanotify_modify_mark() */
 #define FAN_MARK_ADD		0x00000001


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 04/20] fanotify: use __aligned_u64 in fanotify userspace metadata
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
  2010-10-28 21:31 ` [PATCH 02/20] fsnotify: implement ordering between notifiers Eric Paris
  2010-10-28 21:31 ` [PATCH 03/20] fanotify: implement fanotify listener ordering Eric Paris
@ 2010-10-28 21:31 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 05/20] fsnotify: correctly handle return codes from listeners Eric Paris
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:31 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

Currently the userspace struct exposed by fanotify uses
__attribute__((packed)) to make sure that alignment works on multiarch
platforms.  Since this causes a severe performance penalty on some
platforms we are going to switch to using explicit alignment notation on
the 64bit values so we don't have to use 'packed'

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 include/linux/fanotify.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 2c89ce7..8a621c1 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -79,10 +79,10 @@
 struct fanotify_event_metadata {
 	__u32 event_len;
 	__u32 vers;
-	__u64 mask;
+	__aligned_u64 mask;
 	__s32 fd;
 	__s32 pid;
-} __attribute__ ((packed));
+};
 
 struct fanotify_response {
 	__s32 fd;


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 05/20] fsnotify: correctly handle return codes from listeners
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (2 preceding siblings ...)
  2010-10-28 21:31 ` [PATCH 04/20] fanotify: use __aligned_u64 in fanotify userspace metadata Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 06/20] fsnotify: call fsnotify_parent in perm events Eric Paris
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

When fsnotify groups return errors they are ignored.  For permissions
events these should be passed back up the stack, but for most events these
should continue to be ignored.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fsnotify.c             |   20 ++++++++++++--------
 include/linux/fsnotify_backend.h |    2 ++
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 4498a20..57ecadd 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -252,20 +252,23 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
 
 		if (inode_group > vfsmount_group) {
 			/* handle inode */
-			send_to_group(to_tell, NULL, inode_mark, NULL, mask, data,
-				      data_is, cookie, file_name, &event);
+			ret = send_to_group(to_tell, NULL, inode_mark, NULL, mask, data,
+					    data_is, cookie, file_name, &event);
 			/* we didn't use the vfsmount_mark */
 			vfsmount_group = NULL;
 		} else if (vfsmount_group > inode_group) {
-			send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,
-				      data_is, cookie, file_name, &event);
+			ret = send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,
+					    data_is, cookie, file_name, &event);
 			inode_group = NULL;
 		} else {
-			send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,
-				      mask, data, data_is, cookie, file_name,
-				      &event);
+			ret = send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,
+					    mask, data, data_is, cookie, file_name,
+					    &event);
 		}
 
+		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
+			goto out;
+
 		if (inode_group)
 			inode_node = srcu_dereference(inode_node->next,
 						      &fsnotify_mark_srcu);
@@ -273,7 +276,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
 			vfsmount_node = srcu_dereference(vfsmount_node->next,
 							 &fsnotify_mark_srcu);
 	}
-
+	ret = 0;
+out:
 	srcu_read_unlock(&fsnotify_mark_srcu, idx);
 	/*
 	 * fsnotify_create_event() took a reference so the event can't be cleaned
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 8253295..0268921 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -64,6 +64,8 @@
 
 #define FS_MOVE			(FS_MOVED_FROM | FS_MOVED_TO)
 
+#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM)
+
 #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
 			     FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
 			     FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 06/20] fsnotify: call fsnotify_parent in perm events
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (3 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 05/20] fsnotify: correctly handle return codes from listeners Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 07/20] fanotify: allow userspace to flush all marks Eric Paris
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fsnotify perm events do not call fsnotify parent.  That means you cannot
register a perm event on a directory and enforce permissions on all inodes in
that directory.  This patch fixes that situation.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fsnotify.c             |   15 +++++++++------
 include/linux/fsnotify.h         |    9 +++++++--
 include/linux/fsnotify_backend.h |    8 +++++---
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 57ecadd..20dc218 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -84,16 +84,17 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
 }
 
 /* Notify this dentry's parent about a child's events. */
-void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
+int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
 {
 	struct dentry *parent;
 	struct inode *p_inode;
+	int ret = 0;
 
 	if (!dentry)
 		dentry = path->dentry;
 
 	if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
-		return;
+		return 0;
 
 	parent = dget_parent(dentry);
 	p_inode = parent->d_inode;
@@ -106,14 +107,16 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
 		mask |= FS_EVENT_ON_CHILD;
 
 		if (path)
-			fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
-				 dentry->d_name.name, 0);
+			ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
+				       dentry->d_name.name, 0);
 		else
-			fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
-				 dentry->d_name.name, 0);
+			ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
+				       dentry->d_name.name, 0);
 	}
 
 	dput(parent);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(__fsnotify_parent);
 
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 59d0df4..5059faa 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -26,12 +26,12 @@ static inline void fsnotify_d_instantiate(struct dentry *dentry,
 }
 
 /* Notify this dentry's parent about a child's events. */
-static inline void fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
+static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
 {
 	if (!dentry)
 		dentry = path->dentry;
 
-	__fsnotify_parent(path, dentry, mask);
+	return __fsnotify_parent(path, dentry, mask);
 }
 
 /* simple call site for access decisions */
@@ -40,6 +40,7 @@ static inline int fsnotify_perm(struct file *file, int mask)
 	struct path *path = &file->f_path;
 	struct inode *inode = path->dentry->d_inode;
 	__u32 fsnotify_mask = 0;
+	int ret;
 
 	if (file->f_mode & FMODE_NONOTIFY)
 		return 0;
@@ -52,6 +53,10 @@ static inline int fsnotify_perm(struct file *file, int mask)
 	else
 		BUG();
 
+	ret = fsnotify_parent(path, NULL, fsnotify_mask);
+	if (ret)
+		return ret;
+
 	return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
 }
 
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 0268921..b37f3a7 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -304,7 +304,7 @@ struct fsnotify_mark {
 /* main fsnotify call to send events */
 extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
 		    const unsigned char *name, u32 cookie);
-extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
+extern int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
 extern void __fsnotify_inode_delete(struct inode *inode);
 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
 extern u32 fsnotify_get_cookie(void);
@@ -433,8 +433,10 @@ static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int da
 	return 0;
 }
 
-static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
-{}
+static inline int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
+{
+	return 0;
+}
 
 static inline void __fsnotify_inode_delete(struct inode *inode)
 {}


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 07/20] fanotify: allow userspace to flush all marks
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (4 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 06/20] fsnotify: call fsnotify_parent in perm events Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 08/20] fanotify: ignore fanotify ignore marks if open writers Eric Paris
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fanotify is supposed to be able to flush all marks.  This is mostly useful
for the AV community to flush all cached decisions on a security policy
change.  This functionality has existed in the kernel but wasn't correctly
exposed to userspace.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 include/linux/fanotify.h |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 8a621c1..a97c96d 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -52,7 +52,8 @@
 				 FAN_MARK_ONLYDIR |\
 				 FAN_MARK_MOUNT |\
 				 FAN_MARK_IGNORED_MASK |\
-				 FAN_MARK_IGNORED_SURV_MODIFY)
+				 FAN_MARK_IGNORED_SURV_MODIFY |\
+				 FAN_MARK_FLUSH)
 
 /*
  * All of the events - we build the list by hand so that we can add flags in


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 08/20] fanotify: ignore fanotify ignore marks if open writers
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (5 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 07/20] fanotify: allow userspace to flush all marks Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 09/20] fsnotify: implement a default maximum queue depth Eric Paris
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fanotify will clear ignore marks if a task changes the contents of an
inode.  The problem is with the races around when userspace finishes
checking a file and when that result is actually attached to the inode.
This race was described as such:

Consider the following scenario with hostile processes A and B, and
victim process C:
1. Process A opens new file for writing. File check request is generated.
2. File check is performed in userspace. Check result is "file has no malware".
3. The "permit" response is delivered to kernel space.
4. File ignored mark set.
5. Process A writes dummy bytes to the file. File ignored flags are cleared.
6. Process B opens the same file for reading. File check request is generated.
7. File check is performed in userspace. Check result is "file has no malware".
8. Process A writes malware bytes to the file. There is no cached response yet.
9. The "permit" response is delivered to kernel space and is cached in fanotify.
10. File ignored mark set.
11. Now any process C will be permitted to open the malware file.
There is a race between steps 8 and 10

While fanotify makes no strong guarantees about systems with hostile
processes there is no reason we cannot harden against this race.  We do
that by simply ignoring any ignore marks if the inode has open writers (aka
i_writecount > 0).  (We actually do not ignore ignore marks if the
FAN_MARK_SURV_MODIFY flag is set)

Reported-by: Vasily Novikov <vasily.novikov@kaspersky.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 1c09e63..b265936 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -610,6 +610,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 
 	pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
+	/*
+	 * If some other task has this inode open for write we should not add
+	 * an ignored mark, unless that ignored mark is supposed to survive
+	 * modification changes anyway.
+	 */
+	if ((flags & FAN_MARK_IGNORED_MASK) &&
+	    !(flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
+	    (atomic_read(&inode->i_writecount) > 0))
+		return 0;
+
 	fsn_mark = fsnotify_find_inode_mark(group, inode);
 	if (!fsn_mark) {
 		int ret;


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 09/20] fsnotify: implement a default maximum queue depth
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (6 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 08/20] fanotify: ignore fanotify ignore marks if open writers Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 10/20] fanotify: allow userspace to override max " Eric Paris
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

Currently fanotify has no maximum queue depth.  Since fanotify is
CAP_SYS_ADMIN only this does not pose a normal user DoS issue, but it
certianly is possible that an fanotify listener which can't keep up could
OOM the box.  This patch implements a default 16k depth.  This is the same
default depth used by inotify, but given fanotify's better queue merging in
many situations this queue will contain many additional useful events by
comparison.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |    4 ++++
 include/linux/fanotify.h           |    1 -
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index b265936..04f2fe4 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -16,6 +16,8 @@
 
 #include <asm/ioctls.h>
 
+#define FANOTIFY_DEFAULT_MAX_EVENTS	16384
+
 extern const struct fsnotify_ops fanotify_fsnotify_ops;
 
 static struct kmem_cache *fanotify_mark_cache __read_mostly;
@@ -689,6 +691,8 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 		goto out_put_group;
 	}
 
+	group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
+
 	fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
 	if (fd < 0)
 		goto out_put_group;
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index a97c96d..ed479b6 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -12,7 +12,6 @@
 
 #define FAN_EVENT_ON_CHILD	0x08000000	/* interested in child events */
 
-/* FIXME currently Q's have no limit.... */
 #define FAN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */
 
 #define FAN_OPEN_PERM		0x00010000	/* File open in perm check */


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 10/20] fanotify: allow userspace to override max queue depth
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (7 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 09/20] fsnotify: implement a default maximum queue depth Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-11-01 17:09   ` Tvrtko Ursulin
  2010-10-28 21:32 ` [PATCH 11/20] fanotify: limit the number of marks in a single fanotify group Eric Paris
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fanotify has a defualt max queue depth.  This patch allows processes which
explicitly request it to have an 'unlimited' queue depth.  These processes
need to be very careful to make sure they cannot fall far enough behind
that they OOM the box.  Thus this flag is gated on CAP_SYS_ADMIN.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |    9 ++++++++-
 include/linux/fanotify.h           |    5 +++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 04f2fe4..43d66d9 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -691,7 +691,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 		goto out_put_group;
 	}
 
-	group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
+	if (flags & FAN_UNLIMITED_QUEUE) {
+		fd = -EPERM;
+		if (!capable(CAP_SYS_ADMIN))
+			goto out_put_group;
+		group->max_events = UINT_MAX;
+	} else {
+		group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
+	}
 
 	fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
 	if (fd < 0)
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index ed479b6..e37f559 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -28,12 +28,13 @@
 #define FAN_CLASS_NOTIF		0x00000000
 #define FAN_CLASS_CONTENT	0x00000004
 #define FAN_CLASS_PRE_CONTENT	0x00000008
-
 #define FAN_ALL_CLASS_BITS	(FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
 				 FAN_CLASS_PRE_CONTENT)
 
+#define FAN_UNLIMITED_QUEUE	0x00000010
+
 #define FAN_ALL_INIT_FLAGS	(FAN_CLOEXEC | FAN_NONBLOCK | \
-				 FAN_ALL_CLASS_BITS)
+				 FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE)
 
 /* flags used for fanotify_modify_mark() */
 #define FAN_MARK_ADD		0x00000001


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 11/20] fanotify: limit the number of marks in a single fanotify group
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (8 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 10/20] fanotify: allow userspace to override max " Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 12/20] fanotify: allow userspace to override max marks Eric Paris
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

There is currently no limit on the number of marks a given fanotify group
can have.  Since fanotify is gated on CAP_SYS_ADMIN this was not seen as
a serious DoS threat.  This patch implements a default of 8192, the same as
inotify to work towards removing the CAP_SYS_ADMIN gating and eliminating
the default DoS'able status.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |    9 +++++++++
 include/linux/fsnotify_backend.h   |    1 +
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 43d66d9..1d33d7d 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -17,6 +17,7 @@
 #include <asm/ioctls.h>
 
 #define FANOTIFY_DEFAULT_MAX_EVENTS	16384
+#define FANOTIFY_DEFAULT_MAX_MARKS	8192
 
 extern const struct fsnotify_ops fanotify_fsnotify_ops;
 
@@ -584,6 +585,9 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 	if (!fsn_mark) {
 		int ret;
 
+		if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
+			return -ENOSPC;
+
 		fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
 		if (!fsn_mark)
 			return -ENOMEM;
@@ -626,6 +630,9 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 	if (!fsn_mark) {
 		int ret;
 
+		if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
+			return -ENOSPC;
+
 		fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
 		if (!fsn_mark)
 			return -ENOMEM;
@@ -700,6 +707,8 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 		group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
 	}
 
+	group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
+
 	fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
 	if (fd < 0)
 		goto out_put_group;
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index b37f3a7..49ceed6 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -169,6 +169,7 @@ struct fsnotify_group {
 			bool bypass_perm; /* protected by access_mutex */
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
 			int f_flags;
+			unsigned int max_marks;
 		} fanotify_data;
 #endif /* CONFIG_FANOTIFY */
 	};


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 12/20] fanotify: allow userspace to override max marks
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (9 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 11/20] fanotify: limit the number of marks in a single fanotify group Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-11-01 17:16   ` Tvrtko Ursulin
  2010-10-28 21:32 ` [PATCH 13/20] fanotify: limit number of listeners per user Eric Paris
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

Some fanotify groups, especially those like AV scanners, will need to place
lots of marks, particularly ignore marks.  Since ignore marks do not pin
inodes in cache and are cleared if the inode is removed from core (usually
under memory pressure) we expose an interface for listeners, with
CAP_SYS_ADMIN, to override the maximum number of marks and be allowed to
set and 'unlimited' number of marks.  Programs which make use of this
feature will be able to OOM a machine.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |    9 ++++++++-
 include/linux/fanotify.h           |    4 +++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 1d33d7d..f921610 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -707,7 +707,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 		group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
 	}
 
-	group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
+	if (flags & FAN_UNLIMITED_MARKS) {
+		fd = -EPERM;
+		if (!capable(CAP_SYS_ADMIN))
+			goto out_put_group;
+		group->fanotify_data.max_marks = UINT_MAX;
+	} else {
+		group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
+	}
 
 	fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
 	if (fd < 0)
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index e37f559..7592a36 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -32,9 +32,11 @@
 				 FAN_CLASS_PRE_CONTENT)
 
 #define FAN_UNLIMITED_QUEUE	0x00000010
+#define FAN_UNLIMITED_MARKS	0x00000020
 
 #define FAN_ALL_INIT_FLAGS	(FAN_CLOEXEC | FAN_NONBLOCK | \
-				 FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE)
+				 FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
+				 FAN_UNLIMITED_MARKS)
 
 /* flags used for fanotify_modify_mark() */
 #define FAN_MARK_ADD		0x00000001


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 13/20] fanotify: limit number of listeners per user
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (10 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 12/20] fanotify: allow userspace to override max marks Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:32 ` [PATCH 14/20] fanotify: do not send events for irregular files Eric Paris
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fanotify currently has no limit on the number of listeners a given user can
have open.  This patch limits the total number of listeners per user to
128.  This is the same as the inotify default limit.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify.c      |   11 ++++++++++-
 fs/notify/fanotify/fanotify_user.c |   11 +++++++++++
 include/linux/fsnotify_backend.h   |    1 +
 include/linux/sched.h              |    3 +++
 4 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 85366c7..60c11c3 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -200,10 +200,19 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
 	return false;
 }
 
+static void fanotify_free_group_priv(struct fsnotify_group *group)
+{
+	struct user_struct *user;
+
+	user = group->fanotify_data.user;
+	atomic_dec(&user->fanotify_listeners);
+	free_uid(user);
+}
+
 const struct fsnotify_ops fanotify_fsnotify_ops = {
 	.handle_event = fanotify_handle_event,
 	.should_send_event = fanotify_should_send_event,
-	.free_group_priv = NULL,
+	.free_group_priv = fanotify_free_group_priv,
 	.free_event_priv = NULL,
 	.freeing_mark = NULL,
 };
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index f921610..a7d9369 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -18,6 +18,7 @@
 
 #define FANOTIFY_DEFAULT_MAX_EVENTS	16384
 #define FANOTIFY_DEFAULT_MAX_MARKS	8192
+#define FANOTIFY_DEFAULT_MAX_LISTENERS	128
 
 extern const struct fsnotify_ops fanotify_fsnotify_ops;
 
@@ -656,6 +657,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 {
 	struct fsnotify_group *group;
 	int f_flags, fd;
+	struct user_struct *user;
 
 	pr_debug("%s: flags=%d event_f_flags=%d\n",
 		__func__, flags, event_f_flags);
@@ -666,6 +668,12 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 	if (flags & ~FAN_ALL_INIT_FLAGS)
 		return -EINVAL;
 
+	user = get_current_user();
+	if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) {
+		free_uid(user);
+		return -EMFILE;
+	}
+
 	f_flags = O_RDWR | FMODE_NONOTIFY;
 	if (flags & FAN_CLOEXEC)
 		f_flags |= O_CLOEXEC;
@@ -677,6 +685,9 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 	if (IS_ERR(group))
 		return PTR_ERR(group);
 
+	group->fanotify_data.user = user;
+	atomic_inc(&user->fanotify_listeners);
+
 	group->fanotify_data.f_flags = event_f_flags;
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
 	mutex_init(&group->fanotify_data.access_mutex);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 49ceed6..4366f45 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -170,6 +170,7 @@ struct fsnotify_group {
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
 			int f_flags;
 			unsigned int max_marks;
+			struct user_struct *user;
 		} fanotify_data;
 #endif /* CONFIG_FANOTIFY */
 	};
diff --git a/include/linux/sched.h b/include/linux/sched.h
index be7adb7..6f420ba 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -672,6 +672,9 @@ struct user_struct {
 	atomic_t inotify_watches; /* How many inotify watches does this user have? */
 	atomic_t inotify_devs;	/* How many inotify devs does this user have opened? */
 #endif
+#ifdef CONFIG_FANOTIFY
+	atomic_t fanotify_listeners;
+#endif
 #ifdef CONFIG_EPOLL
 	atomic_t epoll_watches;	/* The number of file descriptors currently watched */
 #endif


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 14/20] fanotify: do not send events for irregular files
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (11 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 13/20] fanotify: limit number of listeners per user Eric Paris
@ 2010-10-28 21:32 ` Eric Paris
  2010-10-28 21:33 ` [PATCH 15/20] fsnotify: rename FS_IN_ISDIR to FS_ISDIR Eric Paris
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:32 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fanotify_should_send_event has a test to see if an object is a file or
directory and does not send an event otherwise.  The problem is that the
test is actually checking if the object with a mark is a file or directory,
not if the object the event happened on is a file or directory.  We should
check the latter.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 60c11c3..8d98e1f 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -160,20 +160,21 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
 				       __u32 event_mask, void *data, int data_type)
 {
 	__u32 marks_mask, marks_ignored_mask;
+	struct path *path = data;
 
 	pr_debug("%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p "
 		 "mask=%x data=%p data_type=%d\n", __func__, group, to_tell,
 		 inode_mark, vfsmnt_mark, event_mask, data, data_type);
 
-	/* sorry, fanotify only gives a damn about files and dirs */
-	if (!S_ISREG(to_tell->i_mode) &&
-	    !S_ISDIR(to_tell->i_mode))
-		return false;
-
 	/* if we don't have enough info to send an event to userspace say no */
 	if (data_type != FSNOTIFY_EVENT_PATH)
 		return false;
 
+	/* sorry, fanotify only gives a damn about files and dirs */
+	if (!S_ISREG(path->dentry->d_inode->i_mode) &&
+	    !S_ISDIR(path->dentry->d_inode->i_mode))
+		return false;
+
 	if (inode_mark && vfsmnt_mark) {
 		marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
 		marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 15/20] fsnotify: rename FS_IN_ISDIR to FS_ISDIR
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (12 preceding siblings ...)
  2010-10-28 21:32 ` [PATCH 14/20] fanotify: do not send events for irregular files Eric Paris
@ 2010-10-28 21:33 ` Eric Paris
  2010-10-28 21:33 ` [PATCH 16/20] fanotify: ignore events on directories unless specifically requested Eric Paris
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:33 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

The _IN_ in the naming is reserved for flags only used by inotify.  Since I
am about to use this flag for fanotify rename it to be generic like the
rest.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/inotify/inotify_user.c |    2 +-
 include/linux/fsnotify.h         |   20 ++++++++++----------
 include/linux/fsnotify_backend.h |    4 ++--
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 24edc11..444c305 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -862,7 +862,7 @@ static int __init inotify_user_setup(void)
 	BUILD_BUG_ON(IN_Q_OVERFLOW != FS_Q_OVERFLOW);
 	BUILD_BUG_ON(IN_IGNORED != FS_IN_IGNORED);
 	BUILD_BUG_ON(IN_EXCL_UNLINK != FS_EXCL_UNLINK);
-	BUILD_BUG_ON(IN_ISDIR != FS_IN_ISDIR);
+	BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
 	BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
 
 	BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 5059faa..ecb43b3 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -98,8 +98,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
 		old_dir_mask |= FS_DN_RENAME;
 
 	if (isdir) {
-		old_dir_mask |= FS_IN_ISDIR;
-		new_dir_mask |= FS_IN_ISDIR;
+		old_dir_mask |= FS_ISDIR;
+		new_dir_mask |= FS_ISDIR;
 	}
 
 	fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie);
@@ -137,7 +137,7 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
 	__u32 mask = FS_DELETE;
 
 	if (isdir)
-		mask |= FS_IN_ISDIR;
+		mask |= FS_ISDIR;
 
 	fsnotify_parent(NULL, dentry, mask);
 }
@@ -179,7 +179,7 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct
  */
 static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
 {
-	__u32 mask = (FS_CREATE | FS_IN_ISDIR);
+	__u32 mask = (FS_CREATE | FS_ISDIR);
 	struct inode *d_inode = dentry->d_inode;
 
 	audit_inode_child(dentry, inode);
@@ -197,7 +197,7 @@ static inline void fsnotify_access(struct file *file)
 	__u32 mask = FS_ACCESS;
 
 	if (S_ISDIR(inode->i_mode))
-		mask |= FS_IN_ISDIR;
+		mask |= FS_ISDIR;
 
 	if (!(file->f_mode & FMODE_NONOTIFY)) {
 		fsnotify_parent(path, NULL, mask);
@@ -215,7 +215,7 @@ static inline void fsnotify_modify(struct file *file)
 	__u32 mask = FS_MODIFY;
 
 	if (S_ISDIR(inode->i_mode))
-		mask |= FS_IN_ISDIR;
+		mask |= FS_ISDIR;
 
 	if (!(file->f_mode & FMODE_NONOTIFY)) {
 		fsnotify_parent(path, NULL, mask);
@@ -233,7 +233,7 @@ static inline void fsnotify_open(struct file *file)
 	__u32 mask = FS_OPEN;
 
 	if (S_ISDIR(inode->i_mode))
-		mask |= FS_IN_ISDIR;
+		mask |= FS_ISDIR;
 
 	if (!(file->f_mode & FMODE_NONOTIFY)) {
 		fsnotify_parent(path, NULL, mask);
@@ -252,7 +252,7 @@ static inline void fsnotify_close(struct file *file)
 	__u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
 
 	if (S_ISDIR(inode->i_mode))
-		mask |= FS_IN_ISDIR;
+		mask |= FS_ISDIR;
 
 	if (!(file->f_mode & FMODE_NONOTIFY)) {
 		fsnotify_parent(path, NULL, mask);
@@ -269,7 +269,7 @@ static inline void fsnotify_xattr(struct dentry *dentry)
 	__u32 mask = FS_ATTRIB;
 
 	if (S_ISDIR(inode->i_mode))
-		mask |= FS_IN_ISDIR;
+		mask |= FS_ISDIR;
 
 	fsnotify_parent(NULL, dentry, mask);
 	fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
@@ -304,7 +304,7 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
 
 	if (mask) {
 		if (S_ISDIR(inode->i_mode))
-			mask |= FS_IN_ISDIR;
+			mask |= FS_ISDIR;
 
 		fsnotify_parent(NULL, dentry, mask);
 		fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 4366f45..b36041e 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -45,7 +45,7 @@
 #define FS_ACCESS_PERM		0x00020000	/* access event in a permissions hook */
 
 #define FS_EXCL_UNLINK		0x04000000	/* do not send events if object is unlinked */
-#define FS_IN_ISDIR		0x40000000	/* event occurred against dir */
+#define FS_ISDIR		0x40000000	/* event occurred against dir */
 #define FS_IN_ONESHOT		0x80000000	/* only send event once */
 
 #define FS_DN_RENAME		0x10000000	/* file renamed */
@@ -72,7 +72,7 @@
 			     FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
 			     FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
 			     FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \
-			     FS_IN_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
+			     FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
 			     FS_DN_MULTISHOT | FS_EVENT_ON_CHILD)
 
 struct fsnotify_group;


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 16/20] fanotify: ignore events on directories unless specifically requested
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (13 preceding siblings ...)
  2010-10-28 21:33 ` [PATCH 15/20] fsnotify: rename FS_IN_ISDIR to FS_ISDIR Eric Paris
@ 2010-10-28 21:33 ` Eric Paris
  2010-10-28 21:33 ` [PATCH 17/20] fanotify: do not recalculate the mask if the ignored mask changed Eric Paris
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:33 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

fanotify has a very limited number of events it sends on directories.  The
usefulness of these events is yet to be seen and still we send them.  This
is particularly painful for mount marks where one might receive many of
these useless events.  As such this patch will drop events on IS_DIR()
inodes unless they were explictly requested with FAN_ON_DIR.

This means that a mark on a directory without FAN_EVENT_ON_CHILD or
FAN_ON_DIR is meaningless and will result in no events ever (although it
will still be allowed since detecting it is hard)

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify.c      |    5 +++++
 fs/notify/fanotify/fanotify_user.c |   12 ++++++++++++
 include/linux/fanotify.h           |   10 ++++++++--
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 8d98e1f..b04f88e 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -131,6 +131,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
 	BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW);
 	BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM);
 	BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
+	BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
 
 	pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
@@ -195,6 +196,10 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
 		BUG();
 	}
 
+	if (S_ISDIR(path->dentry->d_inode->i_mode) &&
+	    (marks_ignored_mask & FS_ISDIR))
+		return false;
+
 	if (event_mask & marks_mask & ~marks_ignored_mask)
 		return true;
 
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index a7d9369..ff1a908 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -570,6 +570,12 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
 		if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
 			fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
 	}
+
+	if (!(flags & FAN_MARK_ONDIR)) {
+		__u32 tmask = fsn_mark->ignored_mask | FAN_ONDIR;
+		fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask);
+	}
+
 	spin_unlock(&fsn_mark->lock);
 
 	return mask & ~oldmask;
@@ -766,6 +772,12 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
 	default:
 		return -EINVAL;
 	}
+
+	if (mask & FAN_ONDIR) {
+		flags |= FAN_MARK_ONDIR;
+		mask &= ~FAN_ONDIR;
+	}
+
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
 	if (mask & ~(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD))
 #else
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 7592a36..5e0400a 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -10,13 +10,15 @@
 #define FAN_CLOSE_NOWRITE	0x00000010	/* Writtable file closed */
 #define FAN_OPEN		0x00000020	/* File was opened */
 
-#define FAN_EVENT_ON_CHILD	0x08000000	/* interested in child events */
-
 #define FAN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */
 
 #define FAN_OPEN_PERM		0x00010000	/* File open in perm check */
 #define FAN_ACCESS_PERM		0x00020000	/* File accessed in perm check */
 
+#define FAN_ONDIR		0x40000000	/* event occurred against dir */
+
+#define FAN_EVENT_ON_CHILD	0x08000000	/* interested in child events */
+
 /* helper events */
 #define FAN_CLOSE		(FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */
 
@@ -47,6 +49,10 @@
 #define FAN_MARK_IGNORED_MASK	0x00000020
 #define FAN_MARK_IGNORED_SURV_MODIFY	0x00000040
 #define FAN_MARK_FLUSH		0x00000080
+#ifdef __KERNEL__
+/* not valid from userspace, only kernel internal */
+#define FAN_MARK_ONDIR		0x00000100
+#endif
 
 #define FAN_ALL_MARK_FLAGS	(FAN_MARK_ADD |\
 				 FAN_MARK_REMOVE |\


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 17/20] fanotify: do not recalculate the mask if the ignored mask changed
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (14 preceding siblings ...)
  2010-10-28 21:33 ` [PATCH 16/20] fanotify: ignore events on directories unless specifically requested Eric Paris
@ 2010-10-28 21:33 ` Eric Paris
  2010-10-28 21:33 ` [PATCH 18/20] fanotify: Fix FAN_CLOSE comments Eric Paris
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:33 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

If fanotify sets a new bit in the ignored mask it will cause the generic
fsnotify layer to recalculate the real mask.  This is stupid since we
didn't change that part.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index ff1a908..fa71d5d 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -558,15 +558,15 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
 				       __u32 mask,
 				       unsigned int flags)
 {
-	__u32 oldmask;
+	__u32 oldmask = -1;
 
 	spin_lock(&fsn_mark->lock);
 	if (!(flags & FAN_MARK_IGNORED_MASK)) {
 		oldmask = fsn_mark->mask;
 		fsnotify_set_mark_mask_locked(fsn_mark, (oldmask | mask));
 	} else {
-		oldmask = fsn_mark->ignored_mask;
-		fsnotify_set_mark_ignored_mask_locked(fsn_mark, (oldmask | mask));
+		__u32 tmask = fsn_mark->ignored_mask | mask;
+		fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask);
 		if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
 			fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
 	}


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 18/20] fanotify: Fix FAN_CLOSE comments
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (15 preceding siblings ...)
  2010-10-28 21:33 ` [PATCH 17/20] fanotify: do not recalculate the mask if the ignored mask changed Eric Paris
@ 2010-10-28 21:33 ` Eric Paris
  2010-10-28 21:33 ` [PATCH 19/20] fs/notify/fanotify/fanotify_user.c: fix warnings Eric Paris
  2010-10-28 21:33 ` [PATCH 20/20] fsnotify: remove alignment padding from fsnotify_mark on 64 bit builds Eric Paris
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:33 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

The comments for FAN_CLOSE_WRITE and FAN_CLOSE_NOWRITE do not match
FS_CLOSE_WRITE and FS_CLOSE_NOWRITE, respectively.  WRITE is for
writable files while NOWRITE is for non-writable files.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
---

 include/linux/fanotify.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 5e0400a..0f01214 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -6,8 +6,8 @@
 /* the following events that user-space can register for */
 #define FAN_ACCESS		0x00000001	/* File was accessed */
 #define FAN_MODIFY		0x00000002	/* File was modified */
-#define FAN_CLOSE_WRITE		0x00000008	/* Unwrittable file closed */
-#define FAN_CLOSE_NOWRITE	0x00000010	/* Writtable file closed */
+#define FAN_CLOSE_WRITE		0x00000008	/* Writtable file closed */
+#define FAN_CLOSE_NOWRITE	0x00000010	/* Unwrittable file closed */
 #define FAN_OPEN		0x00000020	/* File was opened */
 
 #define FAN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 19/20] fs/notify/fanotify/fanotify_user.c: fix warnings
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (16 preceding siblings ...)
  2010-10-28 21:33 ` [PATCH 18/20] fanotify: Fix FAN_CLOSE comments Eric Paris
@ 2010-10-28 21:33 ` Eric Paris
  2010-10-28 21:33 ` [PATCH 20/20] fsnotify: remove alignment padding from fsnotify_mark on 64 bit builds Eric Paris
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:33 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

From: Andrew Morton <akpm@linux-foundation.org>

fs/notify/fanotify/fanotify_user.c: In function 'fanotify_release':
fs/notify/fanotify/fanotify_user.c:375: warning: unused variable 'lre'
fs/notify/fanotify/fanotify_user.c:375: warning: unused variable 're'

this is really ugly.

Cc: Eric Paris <eparis@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eric Paris <eparis@redhat.com>
---

 fs/notify/fanotify/fanotify_user.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index fa71d5d..fce66df 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -376,11 +376,10 @@ static ssize_t fanotify_write(struct file *file, const char __user *buf, size_t
 static int fanotify_release(struct inode *ignored, struct file *file)
 {
 	struct fsnotify_group *group = file->private_data;
-	struct fanotify_response_event *re, *lre;
-
-	pr_debug("%s: file=%p group=%p\n", __func__, file, group);
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+	struct fanotify_response_event *re, *lre;
+
 	mutex_lock(&group->fanotify_data.access_mutex);
 
 	group->fanotify_data.bypass_perm = true;


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 20/20] fsnotify: remove alignment padding from fsnotify_mark on 64 bit builds
  2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
                   ` (17 preceding siblings ...)
  2010-10-28 21:33 ` [PATCH 19/20] fs/notify/fanotify/fanotify_user.c: fix warnings Eric Paris
@ 2010-10-28 21:33 ` Eric Paris
  18 siblings, 0 replies; 25+ messages in thread
From: Eric Paris @ 2010-10-28 21:33 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel; +Cc: agruen, tvrtko.ursulin

From: Richard Kennedy <richard@rsk.demon.co.uk>

Reorder struct fsnotfiy_mark to remove 8 bytes of alignment padding on 64
bit builds.  Shrinks fsnotfiy_mark to 128 bytes allowing more objects per
slab in its kmem_cache and reduces the number of cachelines needed for
each structure.

Signed-off-by: Richard Kennedy <richard@rsk.demon.co.uk>
Cc: Eric Paris <eparis@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eric Paris <eparis@redhat.com>
---

 include/linux/fsnotify_backend.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index b36041e..0a68f92 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -287,8 +287,8 @@ struct fsnotify_mark {
 		struct fsnotify_inode_mark i;
 		struct fsnotify_vfsmount_mark m;
 	};
-	__u32 ignored_mask;		/* events types to ignore */
 	struct list_head free_g_list;	/* tmp list used when freeing this mark */
+	__u32 ignored_mask;		/* events types to ignore */
 #define FSNOTIFY_MARK_FLAG_INODE		0x01
 #define FSNOTIFY_MARK_FLAG_VFSMOUNT		0x02
 #define FSNOTIFY_MARK_FLAG_OBJECT_PINNED	0x04


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 03/20] fanotify: implement fanotify listener ordering
  2010-10-28 21:31 ` [PATCH 03/20] fanotify: implement fanotify listener ordering Eric Paris
@ 2010-10-29 15:01   ` John Stoffel
  0 siblings, 0 replies; 25+ messages in thread
From: John Stoffel @ 2010-10-29 15:01 UTC (permalink / raw)
  To: Eric Paris; +Cc: linux-kernel, linux-fsdevel, agruen, tvrtko.ursulin

>>>>> "Eric" == Eric Paris <eparis@redhat.com> writes:

Eric> The fanotify listeners needs to be able to specify what types of
Eric> operations they are going to perform so they can be ordered
Eric> appropriately between other listeners doing other types of
Eric> operations.  They need this to be able to make sure that things
Eric> like hierarchichal storage managers will get access to inodes
Eric> before processes which need the data.  This patch defines 3
Eric> possible uses which groups must indicate in the fanotify_init()
Eric> flags.

Eric> FAN_CLASS_PRE_CONTENT
Eric> FAN_CLASS_CONTENT
Eric> FAN_CLASS_NOTIF

Reviewed-By: john@stoffel.org

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 10/20] fanotify: allow userspace to override max queue depth
  2010-10-28 21:32 ` [PATCH 10/20] fanotify: allow userspace to override max " Eric Paris
@ 2010-11-01 17:09   ` Tvrtko Ursulin
  2010-11-01 17:23     ` Eric Paris
  0 siblings, 1 reply; 25+ messages in thread
From: Tvrtko Ursulin @ 2010-11-01 17:09 UTC (permalink / raw)
  To: Eric Paris; +Cc: linux-kernel, linux-fsdevel, agruen

On Thursday 28 Oct 2010 22:32:32 Eric Paris wrote:
> fanotify has a defualt max queue depth.  This patch allows processes which
> explicitly request it to have an 'unlimited' queue depth.  These processes
> need to be very careful to make sure they cannot fall far enough behind
> that they OOM the box.  Thus this flag is gated on CAP_SYS_ADMIN.
>
> Signed-off-by: Eric Paris <eparis@redhat.com>
> ---
>
>  fs/notify/fanotify/fanotify_user.c |    9 ++++++++-
>  include/linux/fanotify.h           |    5 +++--
>  2 files changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/fs/notify/fanotify/fanotify_user.c
> b/fs/notify/fanotify/fanotify_user.c index 04f2fe4..43d66d9 100644
> --- a/fs/notify/fanotify/fanotify_user.c
> +++ b/fs/notify/fanotify/fanotify_user.c
> @@ -691,7 +691,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags,
> unsigned int, event_f_flags) goto out_put_group;
>       }
>
> -     group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
> +     if (flags & FAN_UNLIMITED_QUEUE) {
> +             fd = -EPERM;
> +             if (!capable(CAP_SYS_ADMIN))
> +                     goto out_put_group;

Either this capable call is not needed or the one at the top of the syscall
needs to go if you intended to allow non-privileged access.

Tvrtko

Sophos Plc, The Pentagon, Abingdon Science Park, Abingdon, OX14 3YP, United Kingdom.
Company Reg No 2096520. VAT Reg No GB 348 3873 20.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 12/20] fanotify: allow userspace to override max marks
  2010-10-28 21:32 ` [PATCH 12/20] fanotify: allow userspace to override max marks Eric Paris
@ 2010-11-01 17:16   ` Tvrtko Ursulin
  0 siblings, 0 replies; 25+ messages in thread
From: Tvrtko Ursulin @ 2010-11-01 17:16 UTC (permalink / raw)
  To: Eric Paris; +Cc: linux-kernel, linux-fsdevel, agruen

On Thursday 28 Oct 2010 22:32:44 Eric Paris wrote:
> Some fanotify groups, especially those like AV scanners, will need to place
> lots of marks, particularly ignore marks.  Since ignore marks do not pin
> inodes in cache and are cleared if the inode is removed from core (usually
> under memory pressure) we expose an interface for listeners, with
> CAP_SYS_ADMIN, to override the maximum number of marks and be allowed to
> set and 'unlimited' number of marks.  Programs which make use of this
> feature will be able to OOM a machine.
>
> Signed-off-by: Eric Paris <eparis@redhat.com>
> ---
>
>  fs/notify/fanotify/fanotify_user.c |    9 ++++++++-
>  include/linux/fanotify.h           |    4 +++-
>  2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/fs/notify/fanotify/fanotify_user.c
> b/fs/notify/fanotify/fanotify_user.c index 1d33d7d..f921610 100644
> --- a/fs/notify/fanotify/fanotify_user.c
> +++ b/fs/notify/fanotify/fanotify_user.c
> @@ -707,7 +707,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags,
> unsigned int, event_f_flags) group->max_events =
> FANOTIFY_DEFAULT_MAX_EVENTS;
>       }
>
> -     group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
> +     if (flags & FAN_UNLIMITED_MARKS) {
> +             fd = -EPERM;
> +             if (!capable(CAP_SYS_ADMIN))
> +                     goto out_put_group;

Same redundant (or not) capable as with queue depth.

Tvrtko

Sophos Plc, The Pentagon, Abingdon Science Park, Abingdon, OX14 3YP, United Kingdom.
Company Reg No 2096520. VAT Reg No GB 348 3873 20.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 10/20] fanotify: allow userspace to override max queue depth
  2010-11-01 17:09   ` Tvrtko Ursulin
@ 2010-11-01 17:23     ` Eric Paris
  2010-11-01 17:34       ` Tvrtko Ursulin
  0 siblings, 1 reply; 25+ messages in thread
From: Eric Paris @ 2010-11-01 17:23 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: linux-kernel, linux-fsdevel, agruen

On Mon, 2010-11-01 at 17:09 +0000, Tvrtko Ursulin wrote:
> On Thursday 28 Oct 2010 22:32:32 Eric Paris wrote:
> > fanotify has a defualt max queue depth.  This patch allows processes which
> > explicitly request it to have an 'unlimited' queue depth.  These processes
> > need to be very careful to make sure they cannot fall far enough behind
> > that they OOM the box.  Thus this flag is gated on CAP_SYS_ADMIN.
> >
> > Signed-off-by: Eric Paris <eparis@redhat.com>
> > ---
> >
> >  fs/notify/fanotify/fanotify_user.c |    9 ++++++++-
> >  include/linux/fanotify.h           |    5 +++--
> >  2 files changed, 11 insertions(+), 3 deletions(-)
> >
> > diff --git a/fs/notify/fanotify/fanotify_user.c
> > b/fs/notify/fanotify/fanotify_user.c index 04f2fe4..43d66d9 100644
> > --- a/fs/notify/fanotify/fanotify_user.c
> > +++ b/fs/notify/fanotify/fanotify_user.c
> > @@ -691,7 +691,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags,
> > unsigned int, event_f_flags) goto out_put_group;
> >       }
> >
> > -     group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
> > +     if (flags & FAN_UNLIMITED_QUEUE) {
> > +             fd = -EPERM;
> > +             if (!capable(CAP_SYS_ADMIN))
> > +                     goto out_put_group;
> 
> Either this capable call is not needed or the one at the top of the syscall
> needs to go if you intended to allow non-privileged access.

I realize they are redundant.  But it is starting down the path of
unpriv'd users.  I figure I already have to go back and audit everything
we do looking for places we shouldn't allow unpriv users, so no need to
add new ones without explicitly checking.

-Eric


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 10/20] fanotify: allow userspace to override max queue depth
  2010-11-01 17:23     ` Eric Paris
@ 2010-11-01 17:34       ` Tvrtko Ursulin
  0 siblings, 0 replies; 25+ messages in thread
From: Tvrtko Ursulin @ 2010-11-01 17:34 UTC (permalink / raw)
  To: Eric Paris; +Cc: linux-kernel, linux-fsdevel, agruen

On Monday 01 Nov 2010 17:23:51 Eric Paris wrote:
> On Mon, 2010-11-01 at 17:09 +0000, Tvrtko Ursulin wrote:
> > On Thursday 28 Oct 2010 22:32:32 Eric Paris wrote:
> > > fanotify has a defualt max queue depth.  This patch allows processes
> > > which explicitly request it to have an 'unlimited' queue depth.  These
> > > processes need to be very careful to make sure they cannot fall far
> > > enough behind that they OOM the box.  Thus this flag is gated on
> > > CAP_SYS_ADMIN.
> > >
> > > Signed-off-by: Eric Paris <eparis@redhat.com>
> > > ---
> > >
> > >  fs/notify/fanotify/fanotify_user.c |    9 ++++++++-
> > >  include/linux/fanotify.h           |    5 +++--
> > >  2 files changed, 11 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/fs/notify/fanotify/fanotify_user.c
> > > b/fs/notify/fanotify/fanotify_user.c index 04f2fe4..43d66d9 100644
> > > --- a/fs/notify/fanotify/fanotify_user.c
> > > +++ b/fs/notify/fanotify/fanotify_user.c
> > > @@ -691,7 +691,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int,
> > > flags, unsigned int, event_f_flags) goto out_put_group;
> > >
> > >       }
> > >
> > > -     group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
> > > +     if (flags & FAN_UNLIMITED_QUEUE) {
> > > +             fd = -EPERM;
> > > +             if (!capable(CAP_SYS_ADMIN))
> > > +                     goto out_put_group;
> >
> > Either this capable call is not needed or the one at the top of the
> > syscall needs to go if you intended to allow non-privileged access.
>
> I realize they are redundant.  But it is starting down the path of
> unpriv'd users.  I figure I already have to go back and audit everything
> we do looking for places we shouldn't allow unpriv users, so no need to
> add new ones without explicitly checking.

True, next patch mentions this higher motive, sorry for the noise.

Tvrtko

Sophos Plc, The Pentagon, Abingdon Science Park, Abingdon, OX14 3YP, United Kingdom.
Company Reg No 2096520. VAT Reg No GB 348 3873 20.

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2010-11-01 17:35 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-28 21:31 [PATCH 01/20] fanotify: allow fanotify to be built Eric Paris
2010-10-28 21:31 ` [PATCH 02/20] fsnotify: implement ordering between notifiers Eric Paris
2010-10-28 21:31 ` [PATCH 03/20] fanotify: implement fanotify listener ordering Eric Paris
2010-10-29 15:01   ` John Stoffel
2010-10-28 21:31 ` [PATCH 04/20] fanotify: use __aligned_u64 in fanotify userspace metadata Eric Paris
2010-10-28 21:32 ` [PATCH 05/20] fsnotify: correctly handle return codes from listeners Eric Paris
2010-10-28 21:32 ` [PATCH 06/20] fsnotify: call fsnotify_parent in perm events Eric Paris
2010-10-28 21:32 ` [PATCH 07/20] fanotify: allow userspace to flush all marks Eric Paris
2010-10-28 21:32 ` [PATCH 08/20] fanotify: ignore fanotify ignore marks if open writers Eric Paris
2010-10-28 21:32 ` [PATCH 09/20] fsnotify: implement a default maximum queue depth Eric Paris
2010-10-28 21:32 ` [PATCH 10/20] fanotify: allow userspace to override max " Eric Paris
2010-11-01 17:09   ` Tvrtko Ursulin
2010-11-01 17:23     ` Eric Paris
2010-11-01 17:34       ` Tvrtko Ursulin
2010-10-28 21:32 ` [PATCH 11/20] fanotify: limit the number of marks in a single fanotify group Eric Paris
2010-10-28 21:32 ` [PATCH 12/20] fanotify: allow userspace to override max marks Eric Paris
2010-11-01 17:16   ` Tvrtko Ursulin
2010-10-28 21:32 ` [PATCH 13/20] fanotify: limit number of listeners per user Eric Paris
2010-10-28 21:32 ` [PATCH 14/20] fanotify: do not send events for irregular files Eric Paris
2010-10-28 21:33 ` [PATCH 15/20] fsnotify: rename FS_IN_ISDIR to FS_ISDIR Eric Paris
2010-10-28 21:33 ` [PATCH 16/20] fanotify: ignore events on directories unless specifically requested Eric Paris
2010-10-28 21:33 ` [PATCH 17/20] fanotify: do not recalculate the mask if the ignored mask changed Eric Paris
2010-10-28 21:33 ` [PATCH 18/20] fanotify: Fix FAN_CLOSE comments Eric Paris
2010-10-28 21:33 ` [PATCH 19/20] fs/notify/fanotify/fanotify_user.c: fix warnings Eric Paris
2010-10-28 21:33 ` [PATCH 20/20] fsnotify: remove alignment padding from fsnotify_mark on 64 bit builds Eric Paris

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.