Blob Blame History Raw
From 4223e680382586628d6650e289596c3a217326c0 Mon Sep 17 00:00:00 2001
From: Liu Hua <weldonliu@tencent.com>
Date: Thu, 6 Jan 2022 20:44:21 +0800
Subject: [PATCH 112/120] pagemap: tiny fix on truncating memory image

When requested iovs are huge, criu needs to invoke more then one
preadv()s. In this situation criu truncates memory image with
offset of first preadv() and length of last one, which leads
to leakage of memory image. This patch fixs truncating with right
offset and length.

Signed-off-by: Liu Hua <weldonliu@tencent.com>
---
 criu/pagemap.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/criu/pagemap.c b/criu/pagemap.c
index d996db7fc..83f69bba3 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -535,7 +535,6 @@ static int process_async_reads(struct page_read *pr)
 	fd = img_raw_fd(pr->pi);
 	list_for_each_entry_safe(piov, n, &pr->async, l) {
 		ssize_t ret;
-		off_t start = piov->from;
 		struct iovec *iovs = piov->to;
 
 		pr_debug("Read piov iovs %d, from %ju, len %ju, first %p:%zu\n", piov->nr, piov->from,
@@ -554,13 +553,16 @@ static int process_async_reads(struct page_read *pr)
 			}
 		}
 
-		if (ret != piov->end - piov->from) {
-			if (ret < 0) {
-				pr_err("Can't read async pr bytes (%zd / %ju read, %ju off, %d iovs)\n", ret,
-				       piov->end - piov->from, piov->from, piov->nr);
-				return -1;
-			}
+		if (ret < 0) {
+			pr_err("Can't read async pr bytes (%zd / %ju read, %ju off, %d iovs)\n", ret,
+			       piov->end - piov->from, piov->from, piov->nr);
+			return -1;
+		}
 
+		if (opts.auto_dedup && punch_hole(pr, piov->from, ret, false))
+			return -1;
+
+		if (ret != piov->end - piov->from) {
 			/*
 			 * The preadv() can return less than requested. It's
 			 * valid and doesn't mean error or EOF. We should advance
@@ -574,9 +576,6 @@ static int process_async_reads(struct page_read *pr)
 			goto more;
 		}
 
-		if (opts.auto_dedup && punch_hole(pr, start, ret, false))
-			return -1;
-
 		BUG_ON(pr->io_complete); /* FIXME -- implement once needed */
 
 		list_del(&piov->l);
-- 
2.34.1