stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
@ 2016-12-12 15:07 Jiri Slaby
  2016-12-12 22:49 ` Greg KH
  0 siblings, 1 reply; 11+ messages in thread
From: Jiri Slaby @ 2016-12-12 15:07 UTC (permalink / raw)
  To: stable; +Cc: jslaby, Linus Torvalds, Al Viro

From: Linus Torvalds <torvalds@linux-foundation.org>

This patch does NOT apply to the 3.12 stable tree. If you still want
it applied, please provide a backport.

===============

commit a0ac402cfcdc904f9772e1762b3fda112dcc56a0 upstream.

In theory we could map other things, but there's a reason that function
is called "user_iov".  Using anything else (like splice can do) just
confuses it.

Reported-and-tested-by: Johannes Thumshirn <jthumshirn@suse.de>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 block/blk-map.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/block/blk-map.c b/block/blk-map.c
index b8657fa8dc9a..27fd8d92892d 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
 	struct iov_iter i;
 	int ret;
 
+	if (!iter_is_iovec(iter))
+		goto fail;
+
 	if (map_data)
 		copy = true;
 	else if (iov_iter_alignment(iter) & align)
@@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
 
 unmap_rq:
 	__blk_rq_unmap_user(bio);
+fail:
 	rq->bio = NULL;
 	return -EINVAL;
 }
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-12 15:07 [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov Jiri Slaby
@ 2016-12-12 22:49 ` Greg KH
  2016-12-13 14:40   ` Jiri Slaby
  0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2016-12-12 22:49 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: stable, Linus Torvalds, Al Viro

On Mon, Dec 12, 2016 at 04:07:27PM +0100, Jiri Slaby wrote:
> From: Linus Torvalds <torvalds@linux-foundation.org>
> 
> This patch does NOT apply to the 3.12 stable tree. If you still want
> it applied, please provide a backport.
> 
> ===============
> 
> commit a0ac402cfcdc904f9772e1762b3fda112dcc56a0 upstream.
> 
> In theory we could map other things, but there's a reason that function
> is called "user_iov".  Using anything else (like splice can do) just
> confuses it.
> 
> Reported-and-tested-by: Johannes Thumshirn <jthumshirn@suse.de>
> Cc: Al Viro <viro@ZenIV.linux.org.uk>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> ---
>  block/blk-map.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/block/blk-map.c b/block/blk-map.c
> index b8657fa8dc9a..27fd8d92892d 100644
> --- a/block/blk-map.c
> +++ b/block/blk-map.c
> @@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
>  	struct iov_iter i;
>  	int ret;
>  
> +	if (!iter_is_iovec(iter))
> +		goto fail;
> +
>  	if (map_data)
>  		copy = true;
>  	else if (iov_iter_alignment(iter) & align)
> @@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
>  
>  unmap_rq:
>  	__blk_rq_unmap_user(bio);
> +fail:
>  	rq->bio = NULL;
>  	return -EINVAL;
>  }

I had to re-write this, feel free to steal the version I wrote for
4.4.y, it's commit d41fb2fbb28d3a1085960edada6c046becd1fafd in the
linux-stable tree.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-12 22:49 ` Greg KH
@ 2016-12-13 14:40   ` Jiri Slaby
  2016-12-13 15:24     ` Greg KH
  0 siblings, 1 reply; 11+ messages in thread
From: Jiri Slaby @ 2016-12-13 14:40 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, Linus Torvalds, Al Viro

On 12/12/2016, 11:49 PM, Greg KH wrote:
> On Mon, Dec 12, 2016 at 04:07:27PM +0100, Jiri Slaby wrote:
>> From: Linus Torvalds <torvalds@linux-foundation.org>
>>
>> This patch does NOT apply to the 3.12 stable tree. If you still want
>> it applied, please provide a backport.
>>
>> ===============
>>
>> commit a0ac402cfcdc904f9772e1762b3fda112dcc56a0 upstream.
>>
>> In theory we could map other things, but there's a reason that function
>> is called "user_iov".  Using anything else (like splice can do) just
>> confuses it.
>>
>> Reported-and-tested-by: Johannes Thumshirn <jthumshirn@suse.de>
>> Cc: Al Viro <viro@ZenIV.linux.org.uk>
>> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
>> ---
>>  block/blk-map.c | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/block/blk-map.c b/block/blk-map.c
>> index b8657fa8dc9a..27fd8d92892d 100644
>> --- a/block/blk-map.c
>> +++ b/block/blk-map.c
>> @@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
>>  	struct iov_iter i;
>>  	int ret;
>>  
>> +	if (!iter_is_iovec(iter))
>> +		goto fail;
>> +
>>  	if (map_data)
>>  		copy = true;
>>  	else if (iov_iter_alignment(iter) & align)
>> @@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
>>  
>>  unmap_rq:
>>  	__blk_rq_unmap_user(bio);
>> +fail:
>>  	rq->bio = NULL;
>>  	return -EINVAL;
>>  }
> 
> I had to re-write this, feel free to steal the version I wrote for
> 4.4.y, it's commit d41fb2fbb28d3a1085960edada6c046becd1fafd in the
> linux-stable tree.

I tried, but unfortunately, 3.12 has no iter_is_iovec :(.

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 14:40   ` Jiri Slaby
@ 2016-12-13 15:24     ` Greg KH
  2016-12-13 15:32       ` Jiri Slaby
  0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2016-12-13 15:24 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: stable, Linus Torvalds, Al Viro

On Tue, Dec 13, 2016 at 03:40:53PM +0100, Jiri Slaby wrote:
> On 12/12/2016, 11:49 PM, Greg KH wrote:
> > On Mon, Dec 12, 2016 at 04:07:27PM +0100, Jiri Slaby wrote:
> >> From: Linus Torvalds <torvalds@linux-foundation.org>
> >>
> >> This patch does NOT apply to the 3.12 stable tree. If you still want
> >> it applied, please provide a backport.
> >>
> >> ===============
> >>
> >> commit a0ac402cfcdc904f9772e1762b3fda112dcc56a0 upstream.
> >>
> >> In theory we could map other things, but there's a reason that function
> >> is called "user_iov".  Using anything else (like splice can do) just
> >> confuses it.
> >>
> >> Reported-and-tested-by: Johannes Thumshirn <jthumshirn@suse.de>
> >> Cc: Al Viro <viro@ZenIV.linux.org.uk>
> >> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> >> ---
> >>  block/blk-map.c | 4 ++++
> >>  1 file changed, 4 insertions(+)
> >>
> >> diff --git a/block/blk-map.c b/block/blk-map.c
> >> index b8657fa8dc9a..27fd8d92892d 100644
> >> --- a/block/blk-map.c
> >> +++ b/block/blk-map.c
> >> @@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
> >>  	struct iov_iter i;
> >>  	int ret;
> >>  
> >> +	if (!iter_is_iovec(iter))
> >> +		goto fail;
> >> +
> >>  	if (map_data)
> >>  		copy = true;
> >>  	else if (iov_iter_alignment(iter) & align)
> >> @@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
> >>  
> >>  unmap_rq:
> >>  	__blk_rq_unmap_user(bio);
> >> +fail:
> >>  	rq->bio = NULL;
> >>  	return -EINVAL;
> >>  }
> > 
> > I had to re-write this, feel free to steal the version I wrote for
> > 4.4.y, it's commit d41fb2fbb28d3a1085960edada6c046becd1fafd in the
> > linux-stable tree.
> 
> I tried, but unfortunately, 3.12 has no iter_is_iovec :(.

And you can't "open code" it for 3.12 by just checking the bitfields?  I
haven't looked at 3.12 in a long time and I know the iovec code has
changed a lot, sorry if this is a stupid question.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 15:24     ` Greg KH
@ 2016-12-13 15:32       ` Jiri Slaby
  2016-12-13 16:46         ` Linus Torvalds
  0 siblings, 1 reply; 11+ messages in thread
From: Jiri Slaby @ 2016-12-13 15:32 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, Linus Torvalds, Al Viro

On 12/13/2016, 04:24 PM, Greg KH wrote:
>>>> --- a/block/blk-map.c
>>>> +++ b/block/blk-map.c
>>>> @@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
>>>>  	struct iov_iter i;
>>>>  	int ret;
>>>>  
>>>> +	if (!iter_is_iovec(iter))
>>>> +		goto fail;
>>>> +
...
>> I tried, but unfortunately, 3.12 has no iter_is_iovec :(.
> 
> And you can't "open code" it for 3.12 by just checking the bitfields?

Nope, blk_rq_map_user_iov above does not even have "const struct
iov_iter *iter" as a parameter yet. Instead, "struct sg_iovec *iov" is
there.

So maybe, the patch is not even needed. But whoever can tell me for
sure, please do so.

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 15:32       ` Jiri Slaby
@ 2016-12-13 16:46         ` Linus Torvalds
  2016-12-13 17:05           ` Al Viro
  0 siblings, 1 reply; 11+ messages in thread
From: Linus Torvalds @ 2016-12-13 16:46 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Greg KH, stable, Al Viro

On Tue, Dec 13, 2016 at 7:32 AM, Jiri Slaby <jslaby@suse.cz> wrote:
>
> Nope, blk_rq_map_user_iov above does not even have "const struct
> iov_iter *iter" as a parameter yet. Instead, "struct sg_iovec *iov" is
> there.
>
> So maybe, the patch is not even needed. But whoever can tell me for
> sure, please do so.

The issue is that we don't wand to get there through splice() creating
an iov that has kernel addresses in it, but I don't think 3.12 can do
that anyway - it would need an explicit splice function in the file
operations.

So I think 3.12 is fine without this. Al?

            Linus

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 16:46         ` Linus Torvalds
@ 2016-12-13 17:05           ` Al Viro
  2016-12-13 17:09             ` Linus Torvalds
  0 siblings, 1 reply; 11+ messages in thread
From: Al Viro @ 2016-12-13 17:05 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jiri Slaby, Greg KH, stable

On Tue, Dec 13, 2016 at 08:46:56AM -0800, Linus Torvalds wrote:
> On Tue, Dec 13, 2016 at 7:32 AM, Jiri Slaby <jslaby@suse.cz> wrote:
> >
> > Nope, blk_rq_map_user_iov above does not even have "const struct
> > iov_iter *iter" as a parameter yet. Instead, "struct sg_iovec *iov" is
> > there.
> >
> > So maybe, the patch is not even needed. But whoever can tell me for
> > sure, please do so.
> 
> The issue is that we don't wand to get there through splice() creating
> an iov that has kernel addresses in it, but I don't think 3.12 can do
> that anyway - it would need an explicit splice function in the file
> operations.

Not really - for 3.12 NULL ->splice_write() means going for
default_file_splice_write(), which will call write_pipe_buf() on the kmapped
pipe buffers, which will call __kernel_write(), which will do
set_fs(get_ds()); and call ->write().

And sg_write() called under set_fs(KERNEL_DS) is vulnerable there as well -
if nothing else, sg_write() -> sg_new_write():
694)        if (__copy_from_user(hp, buf, SZ_SG_IO_HDR)) {
...
722)        if (!access_ok(VERIFY_READ, hp->cmdp, hp->cmd_len)) {
723)                sg_remove_request(sfp, srp);
724)                return -EFAULT; /* protects following copy_from_user()s + get_user()s */
725)        }
726)        if (__copy_from_user(cmnd, hp->cmdp, hp->cmd_len)) {
already gives you read from arbitrary kernel address, and when you get
to sg_start_req() you have
701)                iov = memdup_user(hp->dxferp, size);
702)                if (IS_ERR(iov))
703)                        return PTR_ERR(iov);
704) 
705)                len = iov_length(iov, iov_count);
706)                if (hp->dxfer_len < len) {
707)                        iov_count = iov_shorten(iov, iov_count, hp->dxfer_len);
708)                        len = hp->dxfer_len;
709)                }
710) 
711)                res = blk_rq_map_user_iov(q, rq, md, (struct sg_iovec *)iov,
712)                                          iov_count,
713)                                          len, GFP_ATOMIC);
and there's your kernel-backed iovec passed to blk_rq_map_user_iov().  All
access_ok() will pass, of course, and if you have misaligned iovec array
element you'll force it into __bio_copy_vec(), with copy_{to,from}_user()
on user-supplied kernel address under set_fs(KERNEL_DS).  IOW, reads
and writes at arbitrary kernel address...

> So I think 3.12 is fine without this. Al?

I really doubt it - there might be something subtle I'd missed, but AFAICS
it is vulnerable to the scenario above.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 17:05           ` Al Viro
@ 2016-12-13 17:09             ` Linus Torvalds
  2016-12-13 17:12               ` Jiri Slaby
  2016-12-15  1:54               ` Al Viro
  0 siblings, 2 replies; 11+ messages in thread
From: Linus Torvalds @ 2016-12-13 17:09 UTC (permalink / raw)
  To: Al Viro; +Cc: Jiri Slaby, Greg KH, stable

On Tue, Dec 13, 2016 at 9:05 AM, Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> I really doubt it - there might be something subtle I'd missed, but AFAICS
> it is vulnerable to the scenario above.

Hmm. So maybe just add

        if (segment_eq(get_fs(), KERNEL_DS))
                return -EINVAL;

to blk_rq_map_user_iov()?

            Linus

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 17:09             ` Linus Torvalds
@ 2016-12-13 17:12               ` Jiri Slaby
  2016-12-13 17:42                 ` Linus Torvalds
  2016-12-15  1:54               ` Al Viro
  1 sibling, 1 reply; 11+ messages in thread
From: Jiri Slaby @ 2016-12-13 17:12 UTC (permalink / raw)
  To: Linus Torvalds, Al Viro; +Cc: Greg KH, stable

On 12/13/2016, 06:09 PM, Linus Torvalds wrote:
> On Tue, Dec 13, 2016 at 9:05 AM, Al Viro <viro@zeniv.linux.org.uk> wrote:
>>
>> I really doubt it - there might be something subtle I'd missed, but AFAICS
>> it is vulnerable to the scenario above.
> 
> Hmm. So maybe just add
> 
>         if (segment_eq(get_fs(), KERNEL_DS))
>                 return -EINVAL;
> 
> to blk_rq_map_user_iov()?

BTW, is this a fix (or related):
https://patchwork.kernel.org/patch/9467743/
?

This seems to land into SUSE repositories as a fix for the CVE if I am
looking correctly.

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 17:12               ` Jiri Slaby
@ 2016-12-13 17:42                 ` Linus Torvalds
  0 siblings, 0 replies; 11+ messages in thread
From: Linus Torvalds @ 2016-12-13 17:42 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Al Viro, Greg KH, stable

On Tue, Dec 13, 2016 at 9:12 AM, Jiri Slaby <jslaby@suse.cz> wrote:
>
> BTW, is this a fix (or related):
> https://patchwork.kernel.org/patch/9467743/

That's a "we're probably going to restrict splice to people who
explicitly sign off on it". But not in that particular format.

It should fix the issue too.

               Linus

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov
  2016-12-13 17:09             ` Linus Torvalds
  2016-12-13 17:12               ` Jiri Slaby
@ 2016-12-15  1:54               ` Al Viro
  1 sibling, 0 replies; 11+ messages in thread
From: Al Viro @ 2016-12-15  1:54 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jiri Slaby, Greg KH, stable

On Tue, Dec 13, 2016 at 09:09:25AM -0800, Linus Torvalds wrote:
> On Tue, Dec 13, 2016 at 9:05 AM, Al Viro <viro@zeniv.linux.org.uk> wrote:
> >
> > I really doubt it - there might be something subtle I'd missed, but AFAICS
> > it is vulnerable to the scenario above.
> 
> Hmm. So maybe just add
> 
>         if (segment_eq(get_fs(), KERNEL_DS))
>                 return -EINVAL;
> 
> to blk_rq_map_user_iov()?

To sg_write(), actually.  And we need it both in old branches and in
the mainline - sg_new_write() problem applies in mainline as well, and
if nothing else, it allows to perform reads from arbitrary kernel
space address; I'm not sure how easy it is to see the value it has
fetched, but it certainly can do unpleasant things to memory-mapped
IO registers.

As the matter of fact, bsg_write() is no better - blk_fill_sgv4_hdr_rq()
is called before we get to blk_rq_map_user() where your test would make
it fail, and it does
        if (copy_from_user(rq->cmd, (void __user *)(unsigned long)hdr->request,
                           hdr->request_len))   
                return -EFAULT;
with *hdr, including hrd->request, has come from the data fed to bsg_write().

So I think we should make both sg_write() and bsg_write() to fail as early
as possible when called with KERNEL_DS, mainline and all -stable branches.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-12-15  1:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-12 15:07 [patch NOT added to 3.12 stable tree] Don't feed anything but regular iovec's to blk_rq_map_user_iov Jiri Slaby
2016-12-12 22:49 ` Greg KH
2016-12-13 14:40   ` Jiri Slaby
2016-12-13 15:24     ` Greg KH
2016-12-13 15:32       ` Jiri Slaby
2016-12-13 16:46         ` Linus Torvalds
2016-12-13 17:05           ` Al Viro
2016-12-13 17:09             ` Linus Torvalds
2016-12-13 17:12               ` Jiri Slaby
2016-12-13 17:42                 ` Linus Torvalds
2016-12-15  1:54               ` Al Viro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).