Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752969AbdDKD2l (ORCPT ); Mon, 10 Apr 2017 23:28:41 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:59660 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751587AbdDKD2k (ORCPT ); Mon, 10 Apr 2017 23:28:40 -0400 Date: Tue, 11 Apr 2017 04:28:39 +0100 From: Al Viro To: Dave Jones , Linux Kernel Subject: Re: iov_iter_pipe warning. Message-ID: <20170411032839.GF29622@ZenIV.linux.org.uk> References: <20170321205901.mojmjd2fxmykq3df@codemonkey.org.uk> <20170410192800.GC29622@ZenIV.linux.org.uk> <20170410194206.loesu5licstif7or@codemonkey.org.uk> <20170410195711.GD29622@ZenIV.linux.org.uk> <20170410234830.tmqdhpjtfdveor3c@codemonkey.org.uk> <20170411002215.GE29622@ZenIV.linux.org.uk> <20170411030532.vcam25fz6224ny2h@codemonkey.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20170411030532.vcam25fz6224ny2h@codemonkey.org.uk> User-Agent: Mutt/1.7.1 (2016-10-04) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1514 Lines: 43 On Mon, Apr 10, 2017 at 11:05:32PM -0400, Dave Jones wrote: > On Tue, Apr 11, 2017 at 01:22:15AM +0100, Al Viro wrote: > > > * in do_splice_to(): WARN_ON(pipe->nrbufs == pipe->buffers) > > Hit this one. But not WARN_ON(pipe->nrbufs) in its caller *or* WARN_ON(!pipe->buffers) in do_splice_to() itself? How the devil can that be possible? Again, to make sure we are on the same page: in if (WARN_ON(pipe->nrbufs)) { printk(KERN_ERR "->splice_write = %p", sd->u.file->f_op->splice_write); } while (len) { size_t read_len; loff_t pos = sd->pos, prev_pos = pos; ret = do_splice_to(in, &pos, pipe, len, flags); ... ... (not a single continue in sight) ... if (WARN_ON(pipe->nrbufs)) { printk(KERN_ERR "->splice_write = %p", sd->u.file->f_op->splice_write); } } neither of those WARN_ON() triggers. In do_splice_to() WARN_ON(pipe->nrbufs == pipe->buffers); does trigger, but WARN_ON(!pipe->buffers); does not. And pipe is equal to current->splice_pipe, so nobody else could see it, let alone be messing with it. How can that be possible? Non-triggering WARN_ON() in caller of do_splice_to() mean that pipe->nrbufs is zero. Triggering WARN_ON() in do_splice_to() means that it's equal to pipe->buffers, but WARN_ON(!pipe->buffers) manages to avoid being triggered? Can you confirm all that? Because if that's the case, the next possibility is random memory corruption and/or pipe_info dangling pointers/use-after-free/etc.