Commit c0b15574 authored by Richard W.M. Jones's avatar Richard W.M. Jones
Browse files

cache, cow: Fix data corruption in zero and trim on unaligned tail

Commit eb6009b0 ("cache, cow: Reduce use of bounce-buffer") first
introduced in nbdkit 1.14 added an optimization of the
read-modify-write mechanism used for unaligned heads and tails when
zeroing in the cache layer.

Unfortunately the part applied to the tail contained a mistake: It
zeroes the end of the buffer rather than the beginning.  This causes
data corruption when you use the zero or trim function with an offset
and count which is not aligned to the block size.

Although the bug has been around for years, a recent change made it
more likely to happen.  Commit c1905b0a ("cache, cow: Use a 64K
block size by default") increased the default block size from 4K to
64K.  Most filesystems use a 4K block size so operations like fstrim
will make 4K-aligned requests, and with a 4K block size also in the
cache or cow filter the unaligned case would never have been hit
before.

We can demonstrate the bug simply by filling a buffer with data
(100000 bytes in the example), and then trimming that data, which
ought to zero it out.

Before this commit there is data visible after the trim:

$ nbdkit --filter=cow data "0x21 * 100000" --run 'nbdsh -u $uri -c "h.trim(100000, 0)" ; nbdcopy $uri - | hexdump -C'
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00018000  21 21 21 21 21 21 21 21  21 21 21 21 21 21 21 21  |!!!!!!!!!!!!!!!!|
*
000186a0

After this commit the trim completely clears the data:

$ nbdkit --filter=cow data "0x21 * 100000" --run 'nbdsh -u $uri -c "h.trim(100000, 0)" ; nbdcopy $uri - | hexdump -C'
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000186a0

Thanks: Ming Xie for finding the bug
Fixes: commit eb6009b0
(cherry picked from commit a0ae7b21)
parent fcf57509
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment