--- /dev/null
+From 214b7049a7929f03bbd2786aaef04b8b79db34e2 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@ZenIV.linux.org.uk>
+Date: Thu, 1 May 2008 03:52:22 +0100
+Subject: Fix dnotify/close race (CVE-2008-1375)
+
+From: Al Viro <viro@ZenIV.linux.org.uk>
+
+commit 214b7049a7929f03bbd2786aaef04b8b79db34e2 upstream.
+
+We have a race between fcntl() and close() that can lead to
+dnotify_struct inserted into inode's list *after* the last descriptor
+had been gone from current->files.
+
+Since that's the only point where dnotify_struct gets evicted, we are
+screwed - it will stick around indefinitely. Even after struct file in
+question is gone and freed. Worse, we can trigger send_sigio() on it at
+any later point, which allows to send an arbitrary signal to arbitrary
+process if we manage to apply enough memory pressure to get the page
+that used to host that struct file and fill it with the right pattern...
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/dnotify.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/fs/dnotify.c
++++ b/fs/dnotify.c
+@@ -20,6 +20,7 @@
+ #include <linux/init.h>
+ #include <linux/spinlock.h>
+ #include <linux/slab.h>
++#include <linux/file.h>
+
+ int dir_notify_enable __read_mostly = 1;
+
+@@ -66,6 +67,7 @@ int fcntl_dirnotify(int fd, struct file
+ struct dnotify_struct **prev;
+ struct inode *inode;
+ fl_owner_t id = current->files;
++ struct file *f;
+ int error = 0;
+
+ if ((arg & ~DN_MULTISHOT) == 0) {
+@@ -92,6 +94,15 @@ int fcntl_dirnotify(int fd, struct file
+ prev = &odn->dn_next;
+ }
+
++ rcu_read_lock();
++ f = fcheck(fd);
++ rcu_read_unlock();
++ /* we'd lost the race with close(), sod off silently */
++ /* note that inode->i_lock prevents reordering problems
++ * between accesses to descriptor table and ->i_dnotify */
++ if (f != filp)
++ goto out_free;
++
+ error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
+ if (error)
+ goto out_free;