All of lore.kernel.org
 help / color / mirror / Atom feed
* leak in O_DIRECT readv past the EOF
@ 2017-09-30  4:28 Al Viro
  0 siblings, 0 replies; only message in thread
From: Al Viro @ 2017-09-30  4:28 UTC (permalink / raw)
  To: stable

In all versions from 2.5.62 to 3.15, on each iteration through the loop
by iovec array in do_blockdev_direct_IO() we used to do this:
                sdio.head = 0;
                sdio.tail = 0;
...
                retval = do_direct_IO(dio, &sdio, &map_bh);

                if (retval) {
                        dio_cleanup(dio, &sdio);
                        break;
                }                                                                                                        

with another dio_cleanup() done after the loop, catching the situation when
retval had been 0.  Consider the situation when e.g. the 3rd iovec in 4-iovec
array passed to readv() has crossed the EOF.  do_direct_IO() returns 0 and
buggers off *without* exhausting the page array.  The loop proceeds to the
next iovec without calling dio_cleanup() and resets sdio.head and sdio.tail.
That reset of sdio.{head,tail} has prevented the eventual dio_cleanup() from
seeing anything and the page reference end up leaking.

Commit 7b2c99d15559 (new helper: iov_iter_get_pages()) in 3.16 had eliminated
the loop by iovec array, along with sdio.head and sdio.tail resets.  Backporting
that is too much work - the minimal fix is simply to make sure that the only case
when do_direct_IO() buggers off early without returning non-zero will not skip
dio_cleanup().

The fix applies to all versions from 2.5.62 to 3.15.

Reported-and-tested-by: Venki Pallipadi <venki@cohesity.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 387d919..d0288b8 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -997,6 +997,7 @@ do_holes:
 						i_size_aligned >> blkbits) {
 					/* We hit eof */
 					page_cache_release(page);
+					dio_cleanup(dio, sdio);
 					goto out;
 				}
 				zero_user(page, block_in_page << blkbits,

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-09-30  4:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-30  4:28 leak in O_DIRECT readv past the EOF Al Viro

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.