From: Pavel Kankovsky <peak@argo.troja.mff.cuni.cz>
To: linux-kernel@vger.kernel.org
Subject: Re: Linux kernel file offset pointer races
Date: Wed, 4 Aug 2004 22:36:02 +0200 (MET DST) [thread overview]
Message-ID: <20040804214056.6369.0@argo.troja.mff.cuni.cz> (raw)
In-Reply-To: <Pine.LNX.4.44.0408041220550.26961-100000@isec.pl>
On Wed, 4 Aug 2004, Paul Starzetz wrote:
> static ssize_t mtrr_read(struct file *file, char *buf, size_t len,
> loff_t *ppos)
> {
> [1] if (*ppos >= ascii_buf_bytes) return 0;
> [2] if (*ppos + len > ascii_buf_bytes) len = ascii_buf_bytes - *ppos;
> if ( copy_to_user (buf, ascii_buffer + *ppos, len) ) return -EFAULT;
> [3] *ppos += len;
> return len;
> } /* End Function mtrr_read */
>
> It is quite easy to see that since copy_to_user can sleep, the second
> reference to *ppos may use another value. Or in other words, code
> operating on the file->f_pos variable through a pointer must be atomic
> in respect to the current thread. We expect even more troubles in the
> SMP case though.
Oh no! Another old bug getting bored of being ignored and promoting itself
into a security vulnerability (see Bugtraq/Full-Disclosure archive for a
complete story).
IMHO, the proper fix is to serialize all operations modifying a shared
file pointer (file->f_pos): read(), readv(), write(), writev(),
lseek()/llseek(). As far as I can tell, this is required by POSIX:
[read() specification]
On files that support seeking (for example, a regular file), the
read() shall start at a position in the file given by the file offset
associated with fildes. The file offset shall be incremented by the
number of bytes actually read.
[write() specification]
On a regular file or other file capable of seeking, the actual writing
of data shall proceed from the position in the file indicated by the
file offset associated with fildes. Before successful return from
write(), the file offset shall be incremented by the number of bytes
actually written.
[write() specification]
If the O_APPEND flag of the file status flags is set, the file offset
shall be set to the end of the file prior to each write and no
intervening file modification operation shall occur between changing the
file offset and the write operation.
Moreover, there should probably be some kind of serialization between
groups of reads from a file (read: inode) and individual writes to the
same file even among different struct file:
[read() rationale]
I/O is intended to be atomic to ordinary files and pipes and
FIFOs. Atomic means that all the bytes from a single operation that
started out together end up together, without interleaving from other
I/O operations.
[write() rationale]
Writes can be serialized with respect to other reads and writes. If a
read() of file data can be proven (by any means) to occur after a
write() of the data, it must reflect that write(), even if the calls are
made by different processes. A similar requirement applies to multiple
write operations to the same file position.
--Pavel Kankovsky aka Peak [ Boycott Microsoft--http://www.vcnet.com/bms ]
"Resistance is futile. Open your source code and prepare for assimilation."
next parent reply other threads:[~2004-08-04 20:36 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Pine.LNX.4.44.0408041220550.26961-100000@isec.pl>
2004-08-04 20:36 ` Pavel Kankovsky [this message]
2004-08-06 12:56 ` Alan Cox
2004-08-07 12:38 ` Amon Ott
2004-08-07 13:18 ` viro
2004-08-07 16:02 ` Amon Ott
2004-08-12 21:38 ` Pavel Kankovsky
2004-08-12 21:12 ` Alan Cox
2004-08-18 11:03 ` Pavel Kankovsky
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=20040804214056.6369.0@argo.troja.mff.cuni.cz \
--to=peak@argo.troja.mff.cuni.cz \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®