* [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).