File 0013-metadump-Zero-literal-area-of-unused-inodes.patch of Package xfsprogs.5309
From 27499a0accbb6cb7b3ca79058911db120546112f Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@sandeen.net>
Date: Thu, 30 Jul 2015 09:17:43 +1000
Subject: [PATCH 13/20] metadump: Zero literal area of unused inodes
References: bsc#939367 CVE-2012-2150
When metadump copies unused inodes it should zero out
the literal area, which may contain stale on-disk data.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Acked-by: Jan Kara <jack@suse.com>
---
db/metadump.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 8520f66c1375..a1e023d3615d 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -1775,7 +1775,8 @@ static int
process_inode(
xfs_agnumber_t agno,
xfs_agino_t agino,
- xfs_dinode_t *dip)
+ xfs_dinode_t *dip,
+ bool free_inode)
{
int success;
bool crc_was_ok = false; /* no recalc by default */
@@ -1784,13 +1785,22 @@ process_inode(
success = 1;
cur_ino = XFS_AGINO_TO_INO(mp, agno, agino);
- /* we only care about crc recalculation if we are obfuscating names. */
- if (obfuscate) {
+ /* we only care about crc recalculation if we will modify the inode. */
+ if (obfuscate || zero_stale_data) {
crc_was_ok = xfs_verify_cksum((char *)dip,
mp->m_sb.sb_inodesize,
offsetof(struct xfs_dinode, di_crc));
}
+ if (free_inode) {
+ if (zero_stale_data) {
+ /* Zero all of the inode literal area */
+ memset(XFS_DFORK_DPTR(dip), 0,
+ XFS_LITINO(mp, dip->di_version));
+ }
+ goto done;
+ }
+
/* copy appropriate data fork metadata */
switch (be16_to_cpu(dip->di_mode) & S_IFMT) {
case S_IFDIR:
@@ -1832,6 +1842,11 @@ process_inode(
nametable_clear();
}
+done:
+ /* Heavy handed but low cost; just do it as a catch-all. */
+ if (zero_stale_data)
+ need_new_crc = 1;
+
if (crc_was_ok && need_new_crc)
xfs_dinode_calc_crc(mp, dip);
return success;
@@ -1897,13 +1912,12 @@ copy_inode_chunk(
for (i = 0; i < XFS_INODES_PER_CHUNK; i++) {
xfs_dinode_t *dip;
- if (XFS_INOBT_IS_FREE_DISK(rp, i))
- continue;
-
dip = (xfs_dinode_t *)((char *)iocur_top->data +
((off + i) << mp->m_sb.sb_inodelog));
- if (!process_inode(agno, agino + i, dip))
+ /* process_inode handles free inodes, too */
+ if (!process_inode(agno, agino + i, dip,
+ XFS_INOBT_IS_FREE_DISK(rp, i)))
goto pop_out;
}
skip_processing:
--
2.1.4