From: Jens Axboe <jens.axboe@oracle.com>
To: Eric Dumazet <dada1@cosmosbay.com>
Cc: Andrew Morton <akpm@osdl.org>,
Nick Piggin <nickpiggin@yahoo.com.au>,
Ingo Molnar <mingo@elte.hu>,
linux-kernel <linux-kernel@vger.kernel.org>,
tytso@mit.edu
Subject: Re: [PATCH] splice : Must fully check for fifos
Date: Fri, 3 Nov 2006 09:50:36 +0100 [thread overview]
Message-ID: <20061103085035.GY13555@kernel.dk> (raw)
In-Reply-To: <20061102190700.GQ13555@kernel.dk>
On Thu, Nov 02 2006, Jens Axboe wrote:
> On Thu, Nov 02 2006, Eric Dumazet wrote:
> > With the patch this time :( Sorry guys
> >
> > Hi Andrew
> >
> > I think this patch is necessary. It's quite easy to crash a 2.6.19-rc4 box :(
> >
> > AFAIK the problem come from inode-diet (by Theodore Ts'o, (2006/Sep/27))
> >
> > Thank you
> >
> > [PATCH] splice : Must fully check for FIFO
> >
> > It appears that i_pipe, i_cdev and i_bdev share the same memory location
> > (anonymous union in struct inode) since commits
> > 577c4eb09d1034d0739e3135fd2cff50588024be
> > eaf796e7ef6014f208c409b2b14fddcfaafe7e3a
> >
> > Because of that, testing i_pipe being NULL is not anymore sufficient
> > to tell if an inode is a FIFO or not.
> >
> > Therefore, we must use the S_ISFIFO(inode->i_mode) test before
> > assuming i_pipe pointer is pointing to a struct pipe_inode_info.
>
> Indeed, the inode slimming introduced this bug. I'll queue up a test run
> of things and send it upstream, thanks for catching this.
This is the version I tested and merged.
diff --git a/fs/splice.c b/fs/splice.c
index 8d70595..87694de 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1109,6 +1109,19 @@ out_release:
EXPORT_SYMBOL(do_splice_direct);
/*
+ * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
+ * location, so checking ->i_pipe is not enough to verify that this is a
+ * pipe.
+ */
+static inline int is_pipe(struct inode *inode)
+{
+ if (inode->i_pipe && S_ISFIFO(inode->i_mode))
+ return 1;
+
+ return 0;
+}
+
+/*
* Determine where to splice to/from.
*/
static long do_splice(struct file *in, loff_t __user *off_in,
@@ -1119,8 +1132,8 @@ static long do_splice(struct file *in, l
loff_t offset, *off;
long ret;
- pipe = in->f_dentry->d_inode->i_pipe;
- if (pipe) {
+ if (is_pipe(in->f_dentry->d_inode)) {
+ pipe = in->f_dentry->d_inode->i_pipe;
if (off_in)
return -ESPIPE;
if (off_out) {
@@ -1140,8 +1153,8 @@ static long do_splice(struct file *in, l
return ret;
}
- pipe = out->f_dentry->d_inode->i_pipe;
- if (pipe) {
+ if (is_pipe(out->f_dentry->d_inode)) {
+ pipe = out->f_dentry->d_inode->i_pipe;
if (off_out)
return -ESPIPE;
if (off_in) {
@@ -1298,7 +1311,7 @@ static int get_iovec_page_array(const st
static long do_vmsplice(struct file *file, const struct iovec __user *iov,
unsigned long nr_segs, unsigned int flags)
{
- struct pipe_inode_info *pipe = file->f_dentry->d_inode->i_pipe;
+ struct pipe_inode_info *pipe;
struct page *pages[PIPE_BUFFERS];
struct partial_page partial[PIPE_BUFFERS];
struct splice_pipe_desc spd = {
@@ -1308,7 +1321,7 @@ static long do_vmsplice(struct file *fil
.ops = &user_page_pipe_buf_ops,
};
- if (unlikely(!pipe))
+ if (!is_pipe(file->f_dentry->d_inode))
return -EBADF;
if (unlikely(nr_segs > UIO_MAXIOV))
return -EINVAL;
@@ -1320,6 +1333,7 @@ static long do_vmsplice(struct file *fil
if (spd.nr_pages <= 0)
return spd.nr_pages;
+ pipe = file->f_dentry->d_inode->i_pipe;
return splice_to_pipe(pipe, &spd);
}
@@ -1535,15 +1549,20 @@ static int link_pipe(struct pipe_inode_i
static long do_tee(struct file *in, struct file *out, size_t len,
unsigned int flags)
{
- struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe;
- struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe;
+ struct pipe_inode_info *ipipe;
+ struct pipe_inode_info *opipe;
int ret = -EINVAL;
+ if (!is_pipe(in->f_dentry->d_inode) || !is_pipe(out->f_dentry->d_inode))
+ return ret;
+
/*
* Duplicate the contents of ipipe to opipe without actually
* copying the data.
*/
- if (ipipe && opipe && ipipe != opipe) {
+ ipipe = in->f_dentry->d_inode->i_pipe;
+ opipe = out->f_dentry->d_inode->i_pipe;
+ if (ipipe != opipe) {
/*
* Keep going, unless we encounter an error. The ipipe/opipe
* ordering doesn't really matter.
--
Jens Axboe
prev parent reply other threads:[~2006-11-03 8:48 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-30 9:03 [PATCH 1/2] lockdep: spin_lock_irqsave_nested() Peter Zijlstra
2006-10-30 9:06 ` [PATCH 2/2] lockdep: annotate bcsp driver Peter Zijlstra
2006-10-30 9:06 ` Ingo Molnar
2006-10-30 9:30 ` Marcel Holtmann
2006-10-30 9:31 ` [PATCH 2/2] lockdep: annotate bcsp driver - v2 Peter Zijlstra
2006-10-30 9:07 ` [PATCH 1/2] lockdep: spin_lock_irqsave_nested() Ingo Molnar
2006-10-30 13:12 ` Jarek Poplawski
2006-10-30 13:27 ` Jarek Poplawski
2006-10-30 13:40 ` [PATCH 1/2] lockdep: spin_lock_irqsave_nested() -v2 Peter Zijlstra
2006-10-30 14:12 ` Jarek Poplawski
2006-10-31 6:48 ` [PATCH 1/2] lockdep: spin_lock_irqsave_nested() Andrew Morton
2006-10-31 7:25 ` [PATCH] splice : two smp_mb() can be omitted Eric Dumazet
2006-10-31 7:32 ` Jens Axboe
2006-10-31 7:41 ` Eric Dumazet
2006-10-31 7:46 ` Jens Axboe
2006-10-31 9:40 ` Nick Piggin
2006-10-31 9:49 ` Jens Axboe
2006-10-31 10:51 ` Eric Dumazet
2006-10-31 22:16 ` Nick Piggin
2006-10-31 23:08 ` Eric Dumazet
2006-10-31 23:45 ` Nick Piggin
2006-11-02 17:02 ` [PATCH] splice : Must fully check for fifos Eric Dumazet
2006-11-02 17:05 ` Eric Dumazet
2006-11-02 19:07 ` Jens Axboe
2006-11-03 8:50 ` Jens Axboe [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=20061103085035.GY13555@kernel.dk \
--to=jens.axboe@oracle.com \
--cc=akpm@osdl.org \
--cc=dada1@cosmosbay.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=nickpiggin@yahoo.com.au \
--cc=tytso@mit.edu \
/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.