iomap: don't skip reading in !uptodate folios when unsharing a range
authorDarrick J. Wong <djwong@kernel.org>
Mon, 18 Sep 2023 22:57:39 +0000 (15:57 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 18 Sep 2023 22:57:39 +0000 (15:57 -0700)
commit35d30c9cf12730a1e37053dfde4007c7cc452d1a
tree17d3c34b71470b2e6c647e494e1c07b251f8416b
parent4aa8cdd5e523d2d8ec8df29dcd696bf207d7a494
iomap: don't skip reading in !uptodate folios when unsharing a range

Prior to commit a01b8f225248e, we would always read in the contents of a
!uptodate folio prior to writing userspace data into the folio,
allocated a folio state object, etc.  Ritesh introduced an optimization
that skips all of that if the write would cover the entire folio.

Unfortunately, the optimization misses the unshare case, where we always
have to read in the folio contents since there isn't a data buffer
supplied by userspace.  This can result in stale kernel memory exposure
if userspace issues a FALLOC_FL_UNSHARE_RANGE call on part of a shared
file that isn't already cached.

This was caught by observing fstests regressions in the "unshare around"
mechanism that is used for unaligned writes to a reflinked realtime
volume when the realtime extent size is larger than 1FSB, though I think
it applies to any shared file.

Cc: ritesh.list@gmail.com, willy@infradead.org
Fixes: a01b8f225248e ("iomap: Allocate ifs in ->write_begin() early")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
fs/iomap/buffered-io.c