All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Jonathan Corbet <corbet@lwn.net>,
	LKML <linux-kernel@vger.kernel.org>,
	Andi Kleen <andi@firstfloor.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>,
	bfields@fieldses.org, xfs-masters@oss.sgi.com
Subject: Re: RFC: Fix f_flags races without the BKL
Date: Sat, 3 Jan 2009 17:45:44 +0100	[thread overview]
Message-ID: <20090103164544.GA17282@redhat.com> (raw)
In-Reply-To: <20090102195446.GJ28946@ZenIV.linux.org.uk>

On 01/02, Al Viro wrote:
>
> FWIW, it's still bloody tempting to try.  How about hlist from struct file
> through fasync_struct?  Possibly with reference from fasync_struct back
> to the queue it's on, while we are at it - would make fasync_helper simpler...

Well, don't ask me ;) I don't know whether this change is good or bad...

Let's forget about files with several fasync_struct's, suppose we have a
pointer ->f_xxx to fasync_struct in struct file. Now __fput() can check
f_xxx != NULL and call ->fasync() if true. But how can we ensure that
(->f_flags & FASYNC) matches (->f_xxx != NULL) ? Looks like we should
kill FASYNC and uglify the code which sets/gets ->f_flags, for example
do_fcntl(F_GETFL) should do

	case F_GETFL:
		err = filp->f_flags | (filp->f_xxx ? FASYNC : 0)

And what if some strange driver doesn't use the "standard" fasync_helper/
kill_fasync helpers?


Offtopic, but while we are here...

	pipe_rdwr_fasync:

		retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);

		if (retval >= 0)
			retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);

Suppose that on == 1 and the first fasync_helper(fasync_readers) succeeds,
but the second fasync_helper(fasync_writers) fails. We return the error and
this file doesn't get FASYNC, but still it is placed on ->fasync_readers.
This looks just wrong, we return the error to the user-space, but the file
owner can receive the notifications from ->fasync_readers.

And. Don't we leak fasync_struct in this case? With the recent changes,
pipe_rdwr_release() does not call pipe_rdwr_fasync(on => 0) unconditionally.
Instead, __fput() does this, but depending on ->f_flags & FASYNC.

IOW, perhaps we need something like the patch below?

--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -702,9 +702,11 @@ pipe_rdwr_fasync(int fd, struct file *fi
 
 	retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
 
-	if (retval >= 0)
+	if (retval >= 0) {
 		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
-
+		if (retval < 0) /* can only happen if on == true */
+			fasync_helper(-1, filp, 0, &pipe->fasync_readers);
+	}
 	mutex_unlock(&inode->i_mutex);
 
 	if (retval < 0)


And why pipe_xxx_fasync() take ->i_mutex around fasync_helper() ?
Afaics, nothing bad can happen if pipe_xxx_fasync() races with, say,
pipe_read().

Oleg.


      reply	other threads:[~2009-01-03 16:48 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-29 11:13 RFC: Fix f_flags races without the BKL Jonathan Corbet
2008-12-29 11:57 ` Sam Ravnborg
2008-12-30 12:49   ` Jonathan Corbet
2008-12-29 12:41 ` Oleg Nesterov
2008-12-29 15:27   ` Andi Kleen
2008-12-30 12:59     ` Jonathan Corbet
2008-12-30 13:04       ` [xfs-masters] " Christoph Hellwig
2008-12-30 13:37         ` Andi Kleen
2008-12-30 14:48           ` Christoph Hellwig
2008-12-31  9:52             ` Jonathan Corbet
2008-12-30 14:55       ` Andi Kleen
2009-01-08 23:28   ` Jonathan Corbet
2009-01-09 10:08     ` Oleg Nesterov
2009-01-09 13:18       ` Jonathan Corbet
2009-01-09 14:03         ` Oleg Nesterov
2009-01-09 15:09         ` Andi Kleen
2008-12-29 12:50 ` [xfs-masters] " Christoph Hellwig
2008-12-29 15:15   ` Andi Kleen
2009-01-02 18:29     ` Al Viro
2009-01-02 18:27   ` Al Viro
2009-01-02 18:42 ` Al Viro
2009-01-02 19:09   ` Oleg Nesterov
2009-01-02 19:54     ` Al Viro
2009-01-03 16:45       ` Oleg Nesterov [this message]

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=20090103164544.GA17282@redhat.com \
    --to=oleg@redhat.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=andi@firstfloor.org \
    --cc=bfields@fieldses.org \
    --cc=corbet@lwn.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@ZenIV.linux.org.uk \
    --cc=xfs-masters@oss.sgi.com \
    /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 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.