From: Al Viro <viro@zeniv.linux.org.uk>
To: Meng Xu <mengxu.gatech@gmail.com>
Cc: linux-fsdevel@vger.kernel.org
Subject: Re: Possible data race on file->f_mode between __fget() and generic_fadvise()
Date: Fri, 22 Nov 2019 18:47:52 +0000 [thread overview]
Message-ID: <20191122184752.GF26530@ZenIV.linux.org.uk> (raw)
In-Reply-To: <CAAwBoOKor7qvLs0OaXQ0-CLUpCssukdkfamTQN5c6OQiD2vY3w@mail.gmail.com>
On Mon, Nov 18, 2019 at 09:02:31PM -0500, Meng Xu wrote:
> __fget
> [READ] if (file->f_mode & mask)
>
> [Thread 2: SYS_fadvise64]
> __do_sys_fadvise64
> ksys_fadvise64_64
> vfs_fadvise
> generic_fadvise
> [WRITE] file->f_mode &= ~FMODE_RANDOM;
>
> However, in this particular case, there is no issues caused as the
> mask passed in __fget() is always 0 and hence, does not matter what
> the [WRITE] statement is doing.
Or FMODE_PATH. Other readers in the same area look at FMODE_ATOMIC_POS
as well. And neither FMODE_PATH nor FMODE_ATOMIC_POS is ever modified
after the time struct file instance is set up - certainly not after the
time it's present in descriptor table.
Barriers to look at:
rcu_assign_pointer(fdt->fd[fd], file);
on the insertion side (__fd_install()),
return rcu_dereference_raw(fdt->fd[fd]);
on the fetch side (fcheck_files()). All stores to *file done
prior to putting it into descriptor table should be visible
to everyone who fetches file from there.
If your struct file reaches the reader via some other mechanism, the barriers
are up to that other mechanism. These are for descriptor tables. In case of
transmission by SCM_RIGHTS datagrams, for example, we have a RELEASE/ACQUIRE
pair provided by queue lock of the AF_UNIX socket involved, etc.
Generally, if another thread could find a struct file instance, but fail to
observe the stores done by do_dentry_open(), we would be very deep in trouble;
that would include the stores done by ->open(), setting of ->f_op, etc.
So anything that makes struct file visible in shared data structures ought
to take care with barriers, with (minimal) cooperation of those who fetch it
from those. Pretty much any kind of locks will do it automatically (all
stores prior to unlock are visible to everone doing lock later); lockless
mechanisms need to take some care.
In any case, these bits of ->f_mode fall into the same category as ->f_path,
->f_op, etc. - set prior to return from the function that sets the struct
file instance up and never changed afterwards. All flags that can be
changed later are protected by ->f_lock; actually, right now it's
FMODE_RANDOM alone, but that can change.
prev parent reply other threads:[~2019-11-22 18:47 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-19 2:02 Possible data race on file->f_mode between __fget() and generic_fadvise() Meng Xu
2019-11-22 18:47 ` Al Viro [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=20191122184752.GF26530@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=linux-fsdevel@vger.kernel.org \
--cc=mengxu.gatech@gmail.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.