From: Eric Paris <eparis@redhat.com>
To: linux-kernel@vger.kernel.org, malware-list@lists.printk.net
Cc: viro@zeniv.linux.org.uk, alan@lxorguk.ukuu.org.uk,
arjan@infradead.org, greg@kroah.com, tytso@mit.edu,
akpm@linux-foundation.org
Subject: [PATCH =-v3 19/21] fanotify: evict misbehaving clients
Date: Wed, 12 Nov 2008 11:12:06 -0500 [thread overview]
Message-ID: <20081112161206.25434.71743.stgit@paris.rdu.redhat.com> (raw)
In-Reply-To: <20081112161002.25434.82358.stgit@paris.rdu.redhat.com>
fanotify clients that fail to respond to access requests withing their
timeout or which registered for read permissions checking but fail to then
set fastpaths on O_NONBLOCK files should be evicted. I don't want
misbehaving clients to be able to bring down the system.
This patch tracks the number of times we hit one of these catagories. If
we have 10 more misses than hits we will evict the group from the global
fanotify group list.
Signed-off-by: Eric Paris <eparis@redhat.com>
register for read permission checks and do not then
set fastpaths on
---
fs/notify/access.c | 35 +++++++++++++++++++++++++++++++++++
fs/notify/fanotify.h | 1 +
fs/notify/group.c | 21 ++++++++++++++++++++-
include/linux/fanotify.h | 6 +++++-
4 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/fs/notify/access.c b/fs/notify/access.c
index 0c04a60..73b40e1 100644
--- a/fs/notify/access.c
+++ b/fs/notify/access.c
@@ -29,6 +29,35 @@
#include <linux/fanotify.h>
#include "fanotify.h"
+static inline void userspace_success(struct fanotify_group *group)
+{
+ if (likely(group->misbehave_count == 0))
+ return;
+
+ spin_lock(&group->misbehave_lock);
+ if (group->misbehave_count > 0)
+ group->misbehave_count--;
+ spin_unlock(&group->misbehave_lock);
+}
+
+static inline void userspace_error(struct fanotify_group *group)
+{
+ int evict = 0;
+ spin_lock(&group->misbehave_lock);
+ group->misbehave_count++;
+ if (group->misbehave_count > 10) {
+ group->misbehave_count = 10;
+ evict = 1;
+ /* don't allow it to wrap */
+ if (unlikely(group->misbehave_count >= INT_MAX))
+ group->misbehave_count = 10;
+ }
+ spin_unlock(&group->misbehave_lock);
+
+ if (evict)
+ fanotify_evict_group(group);
+}
+
int fanotify_add_event_to_access(struct fanotify_group *group, struct fanotify_event *event)
{
struct fanotify_event_holder *holder;
@@ -83,6 +112,10 @@ retry:
}
mutex_unlock(&group->access_mutex);
+ /* we timed out, userspace screwed up */
+ if (!ret) {
+ userspace_error(group);
+ }
/*
* if we took a signal, return ERESTARTSYS
* if we timed out userspace is broken so return ALLOW
@@ -90,6 +123,8 @@ retry:
return ret;
}
+ userspace_success(group);
+
/* userspace responded, convert to something usable */
spin_lock(&event->response_lock);
switch (event->response) {
diff --git a/fs/notify/fanotify.h b/fs/notify/fanotify.h
index a370ff9..b31e19a 100644
--- a/fs/notify/fanotify.h
+++ b/fs/notify/fanotify.h
@@ -82,6 +82,7 @@ struct fanotify_fastpath_entry {
extern struct srcu_struct fanotify_grp_srcu_struct;
extern struct list_head fanotify_groups;
+extern void fanotify_evict_group(struct fanotify_group *group);
extern int fanotify_check_notif_queue(struct fanotify_group *group);
extern void fanotify_get_event(struct fanotify_event *event);
diff --git a/fs/notify/group.c b/fs/notify/group.c
index 650f31e..377195c 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -86,6 +86,10 @@ struct fanotify_group *fanotify_find_group(unsigned int priority, unsigned int g
group->timeout = 5000;
+ group->evicted = 0;
+ spin_lock_init(&group->misbehave_lock);
+ group->misbehave_count = 0;
+
/* Do we need to be the first entry? */
if (list_empty(&fanotify_groups)) {
list_add_rcu(&group->group_list, &fanotify_groups);
@@ -125,11 +129,26 @@ void fanotify_kill_group(struct fanotify_group *group)
kfree(group);
}
+/*
+ * called when a group is misbehaving and needs to be kicked out. group will
+ * not get really cleared up until clients exit, but it won't be able to hurt
+ * the system any more.
+ */
+void fanotify_evict_group(struct fanotify_group *group)
+{
+ mutex_lock(&fanotify_grp_mutex);
+ if (!group->evicted)
+ list_del_rcu(&group->group_list);
+ group->evicted = 1;
+ mutex_unlock(&fanotify_grp_mutex);
+}
+
void fanotify_put_group(struct fanotify_group *group)
{
mutex_lock(&fanotify_grp_mutex);
if (atomic_dec_and_test(&group->refcnt)) {
- list_del_rcu(&group->group_list);
+ if (!group->evicted)
+ list_del_rcu(&group->group_list);
mutex_unlock(&fanotify_grp_mutex);
synchronize_srcu(&fanotify_grp_srcu_struct);
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index c6a2a3c..7a7bef6 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -104,7 +104,8 @@ struct fanotify_so_access {
struct fanotify_group {
struct list_head group_list; /* list of all groups on the system */
unsigned int group_num; /* the 'name' of the event */
- unsigned int mask; /* mask of events this group cares about */
+ unsigned int mask; /* mask of events this group cares about */
+ unsigned int evicted; /* 1 if this group has been evicted for misbehaving */
atomic_t refcnt; /* num of processes with a special file open */
/* needed to send notification to userspace */
@@ -124,6 +125,9 @@ struct fanotify_group {
unsigned int timeout; /* timeout to wait for access requests in msec */
+ unsigned int misbehave_count; /* net misbehaviours. increment on failure, dec on success */
+ spinlock_t misbehave_lock; /* protect misbehave_count */
+
unsigned int priority; /* order this group should receive msgs. low first */
};
next prev parent reply other threads:[~2008-11-12 16:16 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-12 16:10 [PATCH =-v3 00/21] fanotify: novel file access notification and permission system Eric Paris
2008-11-12 16:10 ` [PATCH =-v3 01/21] filesystem notification: create fs/notify to contain all fs notification Eric Paris
2008-11-12 16:10 ` [PATCH =-v3 02/21] fsnotify: pass a file instead of an inode to open, read, and write Eric Paris
2008-11-12 16:10 ` [PATCH =-v3 03/21] fanotify: fscking all notify, system wide file access notification Eric Paris
2008-11-12 16:10 ` [PATCH =-v3 04/21] fsnotify: sys_execve and sys_uselib do not call into fsnotify Eric Paris
2008-11-12 16:49 ` Christoph Hellwig
2008-11-12 21:15 ` Eric Paris
2008-11-12 16:10 ` [PATCH =-v3 05/21] fanotify: make use of the new fsnotify_open_exec calls Eric Paris
2008-11-12 16:10 ` [PATCH =-v3 06/21] fanotify: add a userspace interface for fanotify notifications Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 07/21] fanotify: fastpath to ignore certain in core inodes Eric Paris
2008-11-12 16:50 ` Christoph Hellwig
2008-11-12 16:56 ` Alan Cox
2008-11-12 16:58 ` Christoph Hellwig
2008-11-12 20:52 ` Eric Paris
2009-12-08 15:22 ` John Ogness
2008-11-12 22:38 ` Peter Zijlstra
2008-11-12 16:11 ` [PATCH =-v3 08/21] fanotify: add a userspace interface for fastpaths Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 09/21] fanotify: add group priorities Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 10/21] fanotify: blocking and access granting Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 11/21] fanotify: give a special access permission check Eric Paris
2008-11-12 16:53 ` Christoph Hellwig
2008-11-12 21:23 ` Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 12/21] fanotify: user interface for access decisions Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 13/21] fanotify: ability for userspace to delay responses Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 14/21] fanotify: send pid with fanotify notification events Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 15/21] fanotify: send tgid with notification messages Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 16/21] fanotify: send file f_flags along with notifications Eric Paris
2008-11-12 16:11 ` [PATCH =-v3 17/21] fanotify: add option to clear all fastpaths Eric Paris
2008-11-12 16:12 ` [PATCH =-v3 18/21] fanotify: all userspace to set timeouts Eric Paris
2008-11-12 16:56 ` Christoph Hellwig
2008-11-12 21:14 ` Eric Paris
2008-11-12 16:12 ` Eric Paris [this message]
2008-11-12 16:12 ` [PATCH =-v3 20/21] fanotify: allow fastpath entries to survive inode modification Eric Paris
2008-11-12 16:12 ` [PATCH =-v3 21/21] fanotify: add Documentation Eric Paris
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081112161206.25434.71743.stgit@paris.rdu.redhat.com \
--to=eparis@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=arjan@infradead.org \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=malware-list@lists.printk.net \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®