aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2022-06-22 14:28:52 -0500
committerEric Sandeen <sandeen@sandeen.net>2022-06-22 14:28:52 -0500
commit5a282e43fd719e37b866f797c9aacac199d08a19 (patch)
tree78e5e54e6a9898f20f2a8d5f71ac2722208b784d
parentb8e570fc6b5c99270bf956ff4501f0cabb7decc3 (diff)
downloadxfsprogs-dev-5a282e43fd719e37b866f797c9aacac199d08a19.tar.gz
xfs: zero inode fork buffer at allocation
Source kernel commit: cb512c921639613ce03f87e62c5e93ed9fe8c84d When we first allocate or resize an inline inode fork, we round up the allocation to 4 byte alingment to make journal alignment constraints. We don't clear the unused bytes, so we can copy up to three uninitialised bytes into the journal. Zero those bytes so we only ever copy zeros into the journal. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Allison Henderson <allison.henderson@oracle.com> Signed-off-by: Dave Chinner <david@fromorbit.com> Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r--libxfs/xfs_inode_fork.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index da59232918..ac3692b5fc 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -48,8 +48,13 @@ xfs_init_local_fork(
mem_size++;
if (size) {
+ /*
+ * As we round up the allocation here, we need to ensure the
+ * bytes we don't copy data into are zeroed because the log
+ * vectors still copy them into the journal.
+ */
real_size = roundup(mem_size, 4);
- ifp->if_u1.if_data = kmem_alloc(real_size, KM_NOFS);
+ ifp->if_u1.if_data = kmem_zalloc(real_size, KM_NOFS);
memcpy(ifp->if_u1.if_data, data, size);
if (zero_terminate)
ifp->if_u1.if_data[size] = '\0';
@@ -498,10 +503,11 @@ xfs_idata_realloc(
/*
* For inline data, the underlying buffer must be a multiple of 4 bytes
* in size so that it can be logged and stay on word boundaries.
- * We enforce that here.
+ * We enforce that here, and use __GFP_ZERO to ensure that size
+ * extensions always zero the unused roundup area.
*/
ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, roundup(new_size, 4),
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_NOFS | __GFP_NOFAIL | __GFP_ZERO);
ifp->if_bytes = new_size;
}