lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 28 Oct 2017 20:58:23 +0800
From:   Hou Tao <houtao1@...wei.com>
To:     <linux-fsdevel@...r.kernel.org>
CC:     <linux-kernel@...r.kernel.org>, <viro@...iv.linux.org.uk>,
        <jbaron@...mai.com>, <oleg@...hat.com>, <dave@...olabs.net>,
        <koct9i@...il.com>
Subject: [RFC][PATCH 4/8] epoll: free eventpoll by rcu to provide existence guarantee

Before the removal of epmutex, it's OK to access epi->ep in
reverse_path_check_proc(), because the freeing of ep will be
blocked on ep_free().

After the removal of epmutex, when accessing epi->ep in
reverse_path_check_proc(), it's possible that it has been
release because this eventpoll struct belongs to an epoll fd
which also polls the target file.

So freeing eventpoll by rcu to ensure the accessed fields of
eventpoll are still valid when invoking reverse_path_check_proc().

Signed-off-by: Hou Tao <houtao1@...wei.com>
---
 fs/eventpoll.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 998c635..18de596 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -230,6 +230,9 @@ struct eventpoll {
 	/* used to track busy poll napi_id */
 	unsigned int napi_id;
 #endif
+
+	/* used to free itself */
+	struct rcu_head rcu;
 };
 
 /* Wait structure used by the poll hooks */
@@ -818,6 +821,12 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
 	return 0;
 }
 
+static void ep_rcu_free(struct rcu_head *head)
+{
+	struct eventpoll *ep = container_of(head, struct eventpoll, rcu);
+	kfree(ep);
+}
+
 static void ep_free(struct eventpoll *ep)
 {
 	struct rb_node *rbp;
@@ -877,7 +886,8 @@ static void ep_free(struct eventpoll *ep)
 	mutex_destroy(&ep->mtx);
 	free_uid(ep->user);
 	wakeup_source_unregister(ep->ws);
-	kfree(ep);
+
+	call_rcu(&ep->rcu, ep_rcu_free);
 }
 
 static int ep_eventpoll_release(struct inode *inode, struct file *file)
-- 
2.7.5

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ