Blob Blame History Raw
From f58d2a04338edc647e2334ff58b49508424e3f3b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 17 May 2022 13:20:17 +0100
Subject: [PATCH] scan: Fix bound so we don't try to prefetch beyond end of
 disk

An off-by-one error in the bound could cause the filter to try to
prefetch beyond the end of the underlying plugin.  This would cause
nbdkit to crash with this assertion failure:

nbdkit: backend.c:782: backend_cache: Assertion `backend_valid_range (c, offset, count)' failed.

The sequence of events was:

 - scan filter background thread started

 - client reads to the end of the disk

 - background thread skips ahead to end of disk (offset == size)

 - background thread tries to prefetch from this point

In the final step the calculations caused to the background thread to
prefetch a scan-size block beyond the end of the plugin.

Fixes: commit 65c20a09ceacb4431986a2982f2c2e746df63fcb
(cherry picked from commit 953643429b8c57b4dd20a6c0e5b83704ae9a0e88)
---
 filters/scan/bgthread.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/filters/scan/bgthread.c b/filters/scan/bgthread.c
index 384e79b6..5fa5f27f 100644
--- a/filters/scan/bgthread.c
+++ b/filters/scan/bgthread.c
@@ -113,12 +113,12 @@ scan_thread (void *vp)
     }
 
     adjust_clock (offset);
-    if (offset > size)
-      continue;
 
-    /* Issue the next prefetch. */
-    n = MIN (scan_size, size - offset);
-    ctrl->next->cache (ctrl->next, n, offset, 0, NULL);
+    if (offset < size) {
+      /* Issue the next prefetch. */
+      n = MIN (scan_size, size - offset);
+      ctrl->next->cache (ctrl->next, n, offset, 0, NULL);
+    }
   }
 
   if (scan_forever) {
-- 
2.31.1