* [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw [not found] <[email protected]> @ 2019-11-24 8:58 ` Pavel Begunkov 2019-11-24 17:10 ` Jens Axboe 0 siblings, 1 reply; 10+ messages in thread From: Pavel Begunkov @ 2019-11-24 8:58 UTC (permalink / raw) To: Jens Axboe, io-uring Read/write requests to devices without implemented read/write_iter using fixed buffers causes general protection fault, which totally hangs a machine. io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() accesses it as iovec, so dereferencing random address. kmap() page by page in this case Signed-off-by: Pavel Begunkov <[email protected]> --- v2: use kmap P.S. this one passes all tests well fs/io_uring.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 8119cbae4fb6..1a9f34645586 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1613,9 +1613,19 @@ static ssize_t loop_rw_iter(int rw, struct file *file, struct kiocb *kiocb, return -EAGAIN; while (iov_iter_count(iter)) { - struct iovec iovec = iov_iter_iovec(iter); + struct iovec iovec; ssize_t nr; + if (!iov_iter_is_bvec(iter)) { + iovec = iov_iter_iovec(iter); + } else { + /* fixed buffers import bvec */ + iovec.iov_base = kmap(iter->bvec->bv_page) + + iter->iov_offset; + iovec.iov_len = min(iter->count, + iter->bvec->bv_len - iter->iov_offset); + } + if (rw == READ) { nr = file->f_op->read(file, iovec.iov_base, iovec.iov_len, &kiocb->ki_pos); @@ -1624,6 +1634,9 @@ static ssize_t loop_rw_iter(int rw, struct file *file, struct kiocb *kiocb, iovec.iov_len, &kiocb->ki_pos); } + if (iov_iter_is_bvec(iter)) + kunmap(iter->bvec->bv_page); + if (nr < 0) { if (!ret) ret = nr; -- 2.24.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-24 8:58 ` [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw Pavel Begunkov @ 2019-11-24 17:10 ` Jens Axboe 2019-11-24 17:52 ` Pavel Begunkov 0 siblings, 1 reply; 10+ messages in thread From: Jens Axboe @ 2019-11-24 17:10 UTC (permalink / raw) To: Pavel Begunkov, io-uring On 11/24/19 1:58 AM, Pavel Begunkov wrote: > Read/write requests to devices without implemented read/write_iter > using fixed buffers causes general protection fault, which totally > hangs a machine. > > io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() > accesses it as iovec, so dereferencing random address. > > kmap() page by page in this case This looks good to me, much cleaner/simpler. I've added a few pipe fixed buffer tests to liburing as well. Didn't crash for me, but obvious garbage coming out. I've flagged this for stable as well. -- Jens Axboe ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-24 17:10 ` Jens Axboe @ 2019-11-24 17:52 ` Pavel Begunkov 2019-11-25 0:43 ` Jackie Liu 2019-11-25 2:37 ` Jens Axboe 0 siblings, 2 replies; 10+ messages in thread From: Pavel Begunkov @ 2019-11-24 17:52 UTC (permalink / raw) To: Jens Axboe, io-uring [-- Attachment #1.1: Type: text/plain, Size: 1034 bytes --] On 24/11/2019 20:10, Jens Axboe wrote: > On 11/24/19 1:58 AM, Pavel Begunkov wrote: >> Read/write requests to devices without implemented read/write_iter >> using fixed buffers causes general protection fault, which totally >> hangs a machine. >> >> io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() >> accesses it as iovec, so dereferencing random address. >> >> kmap() page by page in this case > > This looks good to me, much cleaner/simpler. I've added a few pipe fixed > buffer tests to liburing as well. Didn't crash for me, but obvious > garbage coming out. I've flagged this for stable as well. > The problem I have is that __user pointer is meant to be checked for not being a kernel address. I suspect, it could fail in some device, which double checks the pointer after vfs (e.g. using access_ok()). Am I wrong? Not a fault at least... #define access_ok(...) __range_not_ok(addr, user_addr_max()); BTW, is there anybody testing it for non x86-64 arch? -- Pavel Begunkov [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-24 17:52 ` Pavel Begunkov @ 2019-11-25 0:43 ` Jackie Liu 2019-11-25 2:38 ` Jens Axboe 2019-11-25 2:37 ` Jens Axboe 1 sibling, 1 reply; 10+ messages in thread From: Jackie Liu @ 2019-11-25 0:43 UTC (permalink / raw) To: Pavel Begunkov; +Cc: Jens Axboe, io-uring > 2019年11月25日 01:52,Pavel Begunkov <[email protected]> 写道: > > On 24/11/2019 20:10, Jens Axboe wrote: >> On 11/24/19 1:58 AM, Pavel Begunkov wrote: >>> Read/write requests to devices without implemented read/write_iter >>> using fixed buffers causes general protection fault, which totally >>> hangs a machine. >>> >>> io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() >>> accesses it as iovec, so dereferencing random address. >>> >>> kmap() page by page in this case >> >> This looks good to me, much cleaner/simpler. I've added a few pipe fixed >> buffer tests to liburing as well. Didn't crash for me, but obvious >> garbage coming out. I've flagged this for stable as well. >> > The problem I have is that __user pointer is meant to be checked > for not being a kernel address. I suspect, it could fail in some > device, which double checks the pointer after vfs (e.g. using access_ok()). > Am I wrong? Not a fault at least... > > #define access_ok(...) __range_not_ok(addr, user_addr_max()); > > BTW, is there anybody testing it for non x86-64 arch? > I have some aarch64 platform, What test do you want me to do? -- Jackie Liu ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-25 0:43 ` Jackie Liu @ 2019-11-25 2:38 ` Jens Axboe 2019-11-25 3:33 ` Jackie Liu 0 siblings, 1 reply; 10+ messages in thread From: Jens Axboe @ 2019-11-25 2:38 UTC (permalink / raw) To: Jackie Liu, Pavel Begunkov; +Cc: io-uring On 11/24/19 5:43 PM, Jackie Liu wrote: > > >> 2019年11月25日 01:52,Pavel Begunkov <[email protected]> 写道: >> >> On 24/11/2019 20:10, Jens Axboe wrote: >>> On 11/24/19 1:58 AM, Pavel Begunkov wrote: >>>> Read/write requests to devices without implemented read/write_iter >>>> using fixed buffers causes general protection fault, which totally >>>> hangs a machine. >>>> >>>> io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() >>>> accesses it as iovec, so dereferencing random address. >>>> >>>> kmap() page by page in this case >>> >>> This looks good to me, much cleaner/simpler. I've added a few pipe fixed >>> buffer tests to liburing as well. Didn't crash for me, but obvious >>> garbage coming out. I've flagged this for stable as well. >>> >> The problem I have is that __user pointer is meant to be checked >> for not being a kernel address. I suspect, it could fail in some >> device, which double checks the pointer after vfs (e.g. using access_ok()). >> Am I wrong? Not a fault at least... >> >> #define access_ok(...) __range_not_ok(addr, user_addr_max()); >> >> BTW, is there anybody testing it for non x86-64 arch? >> > > I have some aarch64 platform, What test do you want me to do? A basic one to try would be: axboe@x1:/home/axboe/git/liburing $ test/stdout This is a pipe test This is a fixed pipe test But in general I'd just run make runtests in the liburing directory and go through all of them. -- Jens Axboe ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-25 2:38 ` Jens Axboe @ 2019-11-25 3:33 ` Jackie Liu 2019-11-25 3:47 ` Jens Axboe 2019-11-25 10:12 ` Pavel Begunkov 0 siblings, 2 replies; 10+ messages in thread From: Jackie Liu @ 2019-11-25 3:33 UTC (permalink / raw) To: Jens Axboe; +Cc: Pavel Begunkov, io-uring > 2019年11月25日 10:38,Jens Axboe <[email protected]> 写道: > > On 11/24/19 5:43 PM, Jackie Liu wrote: >> >> >>> 2019年11月25日 01:52,Pavel Begunkov <[email protected]> 写道: >>> >>> On 24/11/2019 20:10, Jens Axboe wrote: >>>> On 11/24/19 1:58 AM, Pavel Begunkov wrote: >>>>> Read/write requests to devices without implemented read/write_iter >>>>> using fixed buffers causes general protection fault, which totally >>>>> hangs a machine. >>>>> >>>>> io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() >>>>> accesses it as iovec, so dereferencing random address. >>>>> >>>>> kmap() page by page in this case >>>> >>>> This looks good to me, much cleaner/simpler. I've added a few pipe fixed >>>> buffer tests to liburing as well. Didn't crash for me, but obvious >>>> garbage coming out. I've flagged this for stable as well. >>>> >>> The problem I have is that __user pointer is meant to be checked >>> for not being a kernel address. I suspect, it could fail in some >>> device, which double checks the pointer after vfs (e.g. using access_ok()). >>> Am I wrong? Not a fault at least... >>> >>> #define access_ok(...) __range_not_ok(addr, user_addr_max()); >>> >>> BTW, is there anybody testing it for non x86-64 arch? >>> >> >> I have some aarch64 platform, What test do you want me to do? > > A basic one to try would be: > > axboe@x1:/home/axboe/git/liburing $ test/stdout > This is a pipe test > This is a fixed pipe test > > But in general I'd just run make runtests in the liburing directory > and go through all of them. > For test/stdout is PASS. Tested-by: Jackie Liu <[email protected]> But test/accept-link and test/fixed-link failed in for-5.5/io_uring-post branch. that is expect? -- Jackie Liu ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-25 3:33 ` Jackie Liu @ 2019-11-25 3:47 ` Jens Axboe 2019-11-25 10:12 ` Pavel Begunkov 1 sibling, 0 replies; 10+ messages in thread From: Jens Axboe @ 2019-11-25 3:47 UTC (permalink / raw) To: Jackie Liu; +Cc: Pavel Begunkov, io-uring > On Nov 24, 2019, at 8:38 PM, Jackie Liu <[email protected]> wrote: > > > >> 2019年11月25日 10:38,Jens Axboe <[email protected]> 写道: >> >>> On 11/24/19 5:43 PM, Jackie Liu wrote: >>> >>> >>>> 2019年11月25日 01:52,Pavel Begunkov <[email protected]> 写道: >>>> >>>> On 24/11/2019 20:10, Jens Axboe wrote: >>>>> On 11/24/19 1:58 AM, Pavel Begunkov wrote: >>>>>> Read/write requests to devices without implemented read/write_iter >>>>>> using fixed buffers causes general protection fault, which totally >>>>>> hangs a machine. >>>>>> >>>>>> io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() >>>>>> accesses it as iovec, so dereferencing random address. >>>>>> >>>>>> kmap() page by page in this case >>>>> >>>>> This looks good to me, much cleaner/simpler. I've added a few pipe fixed >>>>> buffer tests to liburing as well. Didn't crash for me, but obvious >>>>> garbage coming out. I've flagged this for stable as well. >>>>> >>>> The problem I have is that __user pointer is meant to be checked >>>> for not being a kernel address. I suspect, it could fail in some >>>> device, which double checks the pointer after vfs (e.g. using access_ok()). >>>> Am I wrong? Not a fault at least... >>>> >>>> #define access_ok(...) __range_not_ok(addr, user_addr_max()); >>>> >>>> BTW, is there anybody testing it for non x86-64 arch? >>>> >>> >>> I have some aarch64 platform, What test do you want me to do? >> >> A basic one to try would be: >> >> axboe@x1:/home/axboe/git/liburing $ test/stdout >> This is a pipe test >> This is a fixed pipe test >> >> But in general I'd just run make runtests in the liburing directory >> and go through all of them. >> > > For test/stdout is PASS. Tested-by: Jackie Liu <[email protected]> Thanks! > But test/accept-link and test/fixed-link failed in for-5.5/io_uring-post branch. > that is expect? Yes, the fix for that is in 5.4, didn’t merge it into the 5.5 branch. It’ll pass once Linus pulls the 5.5 bits and the branches merge. — Jens Axboe ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-25 3:33 ` Jackie Liu 2019-11-25 3:47 ` Jens Axboe @ 2019-11-25 10:12 ` Pavel Begunkov 1 sibling, 0 replies; 10+ messages in thread From: Pavel Begunkov @ 2019-11-25 10:12 UTC (permalink / raw) To: Jackie Liu, Jens Axboe; +Cc: io-uring >>> I have some aarch64 platform, What test do you want me to do? >> >> A basic one to try would be: >> >> axboe@x1:/home/axboe/git/liburing $ test/stdout >> This is a pipe test >> This is a fixed pipe test >> >> But in general I'd just run make runtests in the liburing directory >> and go through all of them. >> > > For test/stdout is PASS. Tested-by: Jackie Liu <[email protected]> > Great, thanks! -- Pavel Begunkov ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-24 17:52 ` Pavel Begunkov 2019-11-25 0:43 ` Jackie Liu @ 2019-11-25 2:37 ` Jens Axboe 2019-11-25 10:46 ` Pavel Begunkov 1 sibling, 1 reply; 10+ messages in thread From: Jens Axboe @ 2019-11-25 2:37 UTC (permalink / raw) To: Pavel Begunkov, io-uring On 11/24/19 10:52 AM, Pavel Begunkov wrote: > On 24/11/2019 20:10, Jens Axboe wrote: >> On 11/24/19 1:58 AM, Pavel Begunkov wrote: >>> Read/write requests to devices without implemented read/write_iter >>> using fixed buffers causes general protection fault, which totally >>> hangs a machine. >>> >>> io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() >>> accesses it as iovec, so dereferencing random address. >>> >>> kmap() page by page in this case >> >> This looks good to me, much cleaner/simpler. I've added a few pipe fixed >> buffer tests to liburing as well. Didn't crash for me, but obvious >> garbage coming out. I've flagged this for stable as well. >> > The problem I have is that __user pointer is meant to be checked > for not being a kernel address. I suspect, it could fail in some > device, which double checks the pointer after vfs (e.g. using access_ok()). > Am I wrong? Not a fault at least... > > #define access_ok(...) __range_not_ok(addr, user_addr_max()); They are user pages! So this should be totally fine. The only difference is that we have them pre-mapped. But it's not like we're pretending these kernel pages are user pages, and hence access_ok() should be totally happy with them. > BTW, is there anybody testing it for non x86-64 arch? Would be nice, I've mostly failed at getting other archs interested enough to actually make hardware available. Which seems pretty lame, but only so much I can do there. There _shouldn't_ be anything arch specific, but it would be great to have archs with eg weaker ordering as part of the regular test arsenal. -- Jens Axboe ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw 2019-11-25 2:37 ` Jens Axboe @ 2019-11-25 10:46 ` Pavel Begunkov 0 siblings, 0 replies; 10+ messages in thread From: Pavel Begunkov @ 2019-11-25 10:46 UTC (permalink / raw) To: Jens Axboe, io-uring On 11/25/2019 5:37 AM, Jens Axboe wrote: > On 11/24/19 10:52 AM, Pavel Begunkov wrote: >> On 24/11/2019 20:10, Jens Axboe wrote: >>> On 11/24/19 1:58 AM, Pavel Begunkov wrote: >>>> Read/write requests to devices without implemented read/write_iter >>>> using fixed buffers causes general protection fault, which totally >>>> hangs a machine. >>>> >>>> io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter() >>>> accesses it as iovec, so dereferencing random address. >>>> >>>> kmap() page by page in this case >>> >>> This looks good to me, much cleaner/simpler. I've added a few pipe fixed >>> buffer tests to liburing as well. Didn't crash for me, but obvious >>> garbage coming out. I've flagged this for stable as well. >>> >> The problem I have is that __user pointer is meant to be checked >> for not being a kernel address. I suspect, it could fail in some >> device, which double checks the pointer after vfs (e.g. using access_ok()). >> Am I wrong? Not a fault at least... >> >> #define access_ok(...) __range_not_ok(addr, user_addr_max()); > > They are user pages! So this should be totally fine. The only difference > is that we have them pre-mapped. But it's not like we're pretending > these kernel pages are user pages, and hence access_ok() should be > totally happy with them. > Good, if you say so, but I'll take the liberty of asking a little bit more :) Yes, they are user pages, but that's rather about used virtual addresses. Having virtual address space separation (e.g. [0-n): user's virtual address space part, [n-m): kernel's one), I'd expect __user ptr to be checked to be bounded by [0-n). E.g. copy_to_user() obviously shouldn't write into kernel's addresses. And I also assume that kmap() maps into [n-m), at least because the kernel may want to allocate and kmap() pages, and use them internally. And that's why I thought it may fail. E.g. vfs_read_sys((__user void*)kmap()) _should_ fail. Where is my mistake? >> BTW, is there anybody testing it for non x86-64 arch? > > Would be nice, I've mostly failed at getting other archs interested > enough to actually make hardware available. Which seems pretty lame, but > only so much I can do there. There _shouldn't_ be anything arch > specific, but it would be great to have archs with eg weaker ordering as > part of the regular test arsenal. > Yeah, that's the point. It probably needs some use in Android to turn the things over. -- Pavel Begunkov ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-11-25 10:46 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <[email protected]>
2019-11-24 8:58 ` [PATCH v2] io_uring: fix dead-hung for non-iter fixed rw Pavel Begunkov
2019-11-24 17:10 ` Jens Axboe
2019-11-24 17:52 ` Pavel Begunkov
2019-11-25 0:43 ` Jackie Liu
2019-11-25 2:38 ` Jens Axboe
2019-11-25 3:33 ` Jackie Liu
2019-11-25 3:47 ` Jens Axboe
2019-11-25 10:12 ` Pavel Begunkov
2019-11-25 2:37 ` Jens Axboe
2019-11-25 10:46 ` Pavel Begunkov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox