+++ /dev/null
-From 8eeee4e2f04fc551f50c9d9847da2d73d7d33728 Mon Sep 17 00:00:00 2001
-From: Oleg Nesterov <oleg@redhat.com>
-Date: Wed, 17 Jun 2009 00:27:10 +0200
-Subject: send_sigio_to_task: sanitize the usage of fown->signum
-
-From: Oleg Nesterov <oleg@redhat.com>
-
-commit 8eeee4e2f04fc551f50c9d9847da2d73d7d33728 upstream.
-
-send_sigio_to_task() reads fown->signum several times, we can race with
-F_SETSIG which changes ->signum lockless. In theory, this can fool
-security checks or we can call group_send_sig_info() with the wrong
-->si_signo which does not match "int sig".
-
-Change the code to cache ->signum.
-
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- fs/fcntl.c | 16 +++++++++++-----
- 1 file changed, 11 insertions(+), 5 deletions(-)
-
---- a/fs/fcntl.c
-+++ b/fs/fcntl.c
-@@ -417,14 +417,20 @@ static inline int sigio_perm(struct task
- }
-
- static void send_sigio_to_task(struct task_struct *p,
-- struct fown_struct *fown,
-+ struct fown_struct *fown,
- int fd,
- int reason)
- {
-- if (!sigio_perm(p, fown, fown->signum))
-+ /*
-+ * F_SETSIG can change ->signum lockless in parallel, make
-+ * sure we read it once and use the same value throughout.
-+ */
-+ int signum = ACCESS_ONCE(fown->signum);
-+
-+ if (!sigio_perm(p, fown, signum))
- return;
-
-- switch (fown->signum) {
-+ switch (signum) {
- siginfo_t si;
- default:
- /* Queue a rt signal with the appropriate fd as its
-@@ -433,7 +439,7 @@ static void send_sigio_to_task(struct ta
- delivered even if we can't queue. Failure to
- queue in this case _should_ be reported; we fall
- back to SIGIO in that case. --sct */
-- si.si_signo = fown->signum;
-+ si.si_signo = signum;
- si.si_errno = 0;
- si.si_code = reason;
- /* Make sure we are called with one of the POLL_*
-@@ -445,7 +451,7 @@ static void send_sigio_to_task(struct ta
- else
- si.si_band = band_table[reason - POLL_IN];
- si.si_fd = fd;
-- if (!group_send_sig_info(fown->signum, &si, p))
-+ if (!group_send_sig_info(signum, &si, p))
- break;
- /* fall-through: fall back on the old plain SIGIO signal */
- case 0: