[Devel] [PATCH RHEL7 COMMIT] fs/ceph: access beyound end of iovec array in dio_get_pagev_size()

Vasily Averin vvs at virtuozzo.com
Tue Jun 22 14:02:48 MSK 2021


The commit is pushed to "branch-rh7-3.10.0-1160.31.1.vz7.181.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.31.1.vz7.181.7
------>
commit e676c3bacb2ca0e554daf91ada6cc0d64921e95f
Author: Vasily Averin <vvs at virtuozzo.com>
Date:   Tue Jun 22 14:02:47 2021 +0300

    fs/ceph: access beyound end of iovec array in dio_get_pagev_size()
    
    vz7 patch "fs/ceph: honor kernel direct aio changes v2" incorrectly
    changed dio_get_pagev_size() function. Now it does not check end of
    iovec array and access memory beyond its end.
    
    This patch resotres original behaviour.
    https://jira.sw.ru/browse/PSBM-130693
    Fixes: ff1e3991a9c2("fs/ceph: honor kernel direct aio changes v2")
    Signed-off-by: Vasily Averin <vvs at virtuozzo.com>
---
 fs/ceph/file.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 4302940..8be9868 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -75,7 +75,7 @@ static __le32 ceph_flags_sys2wire(u32 flags)
 static size_t dio_get_pagev_size(const struct iov_iter *it)
 {
     const struct iovec *iov = iov_iter_iovec(it);
-    size_t total = iov_iter_count(it);
+    const struct iovec *iovend = iov + it->nr_segs;
     size_t size;
 
     size = iov->iov_len - it->iov_offset;
@@ -84,10 +84,8 @@ static size_t dio_get_pagev_size(const struct iov_iter *it)
      * and the next base are page aligned.
      */
     while (PAGE_ALIGNED((iov->iov_base + iov->iov_len)) &&
-           PAGE_ALIGNED(((iov++)->iov_base))) {
-	    size_t n =  min(iov->iov_len, total);
-	    size += n;
-	    total -= n;
+           (++iov < iovend && PAGE_ALIGNED((iov->iov_base)))) {
+        size += iov->iov_len;
     }
     dout("dio_get_pagevlen len = %zu\n", size);
     return size;


More information about the Devel mailing list