Thread (12 messages) flat view 12 messages, 3 authors, 2016-12-06

Re: scsi: use-after-free in bio_copy_from_iter

From: Dmitry Vyukov <dvyukov@google.com>
Date: 2016-12-06 09:44:23
Also in: linux-scsi, lkml

On Tue, Dec 6, 2016 at 10:32 AM, Johannes Thumshirn [off-list ref] wrote:
On Mon, Dec 05, 2016 at 07:03:39PM +0000, Al Viro wrote:
quoted
On Mon, Dec 05, 2016 at 04:17:53PM +0100, Johannes Thumshirn wrote:
quoted
633         hp = &srp->header;
[...]
646                 hp->dxferp = (char __user *)buf + cmd_size;
quoted
So the memory for hp->dxferp comes from:
633         hp = &srp->header;
????
quoted
quoted
From my debug instrumentation I see that the dxferp ends up in the
iovec_iter's kvec->iov_base and the faulting address is always dxferp + n *
4k with n in [1, 16] (and we're copying 16 4k pages from the iovec into the
bio).
_Address_ of hp->dxferp comes from that assignment; the value is 'buf'
argument of sg_write() + small offset.  In this case, it should point
inside a pipe buffer, which is, indeed, at a kernel address.  Who'd
allocated srp is irrelevant.
Yes I realized that as well when I had enough distance between me and the
code...
quoted
And if you end up dereferencing more than one page worth there, you do have
a problem - pipe buffers are not going to be that large.  Could you slap
      WARN_ON((size_t)input_size > count);
right after the calculation of input_size in sg_write() and see if it triggers
on your reproducer?
I did and it didn't trigger. What triggers is (as expected) a
        WARN_ON((size_t)mxsize > count);
We have count at 80 and mxsize (which ends in hp->dxfer_len) at 65499. But the
65499 bytes are the len of the data we're suppost to be copying in via the
iov. I'm still rather confused what's happening here, sorry.

I think the critical piece here is some kind of race or timing
condition. Note that the test program executes all of
memfd_create/write/open/sendfile twice. Second time the calls race
with each other, but they also can race with the first execution of
the calls.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help