File 0015-metadump-Zero-sparse-unused-regions-of-dir2.patch of Package xfsprogs.970
From 6d34e8b30e696d9a7e9bcf6e32cddbcd3bfad15a Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@sandeen.net>
Date: Thu, 30 Jul 2015 09:21:05 +1000
Subject: [PATCH 15/20] metadump: Zero sparse/unused regions of dir2
References: bsc#939367 CVE-2012-2150
dir2 data has explicitly unused regions as well as
padding between entries; zero this out to avoid copying
stale 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 | 54 +++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 43 insertions(+), 11 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 775deb5274fd..462623652b6f 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -1153,7 +1153,7 @@ process_sf_attr(
}
static void
-obfuscate_dir_data_block(
+process_dir_data_block(
char *block,
xfs_dfiloff_t offset,
int is_block_format)
@@ -1229,6 +1229,20 @@ obfuscate_dir_data_block(
return;
dir_offset += length;
ptr += length;
+ /*
+ * Zero the unused space up to the tag - the tag is
+ * actually at a variable offset, so zeroing &dup->tag
+ * is zeroing the free space in between
+ */
+ if (zero_stale_data) {
+ int zlen = length -
+ sizeof(xfs_dir2_data_unused_t);
+
+ if (zlen > 0) {
+ memset(&dup->tag, 0, zlen);
+ iocur_top->need_crc = 1;
+ }
+ }
if (dir_offset >= end_of_data || ptr >= endptr)
return;
}
@@ -1247,10 +1261,23 @@ obfuscate_dir_data_block(
if (be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) !=
dir_offset)
return;
- generate_obfuscated_name(be64_to_cpu(dep->inumber),
+
+ if (obfuscate)
+ generate_obfuscated_name(be64_to_cpu(dep->inumber),
dep->namelen, &dep->name[0]);
dir_offset += length;
ptr += length;
+ /* Zero the unused space after name, up to the tag */
+ if (zero_stale_data) {
+ /* 1 byte for ftype; don't bother with conditional */
+ int zlen =
+ (char *)xfs_dir3_data_entry_tag_p(mp, dep) -
+ (char *)&dep->name[dep->namelen] - 1;
+ if (zlen > 0) {
+ memset(&dep->name[dep->namelen] + 1, 0, zlen);
+ iocur_top->need_crc = 1;
+ }
+ }
}
}
@@ -1403,7 +1430,7 @@ process_single_fsb_objects(
}
- if (!obfuscate)
+ if (!obfuscate && !zero_stale_data)
goto write;
dp = iocur_top->data;
@@ -1412,17 +1439,21 @@ process_single_fsb_objects(
if (o >= mp->m_dirleafblk)
break;
- obfuscate_dir_data_block(dp, o,
+ process_dir_data_block(dp, o,
last == mp->m_dirblkfsbs);
iocur_top->need_crc = 1;
break;
case TYP_SYMLINK:
- obfuscate_symlink_block(dp);
- iocur_top->need_crc = 1;
+ if (obfuscate) {
+ obfuscate_symlink_block(dp);
+ iocur_top->need_crc = 1;
+ }
break;
case TYP_ATTR:
- obfuscate_attr_block(dp, o);
- iocur_top->need_crc = 1;
+ if (obfuscate) {
+ obfuscate_attr_block(dp, o);
+ iocur_top->need_crc = 1;
+ }
break;
default:
break;
@@ -1495,13 +1526,14 @@ process_multi_fsb_objects(
}
- if (!obfuscate || o >= mp->m_dirleafblk) {
+ if ((!obfuscate && !zero_stale_data) ||
+ o >= mp->m_dirleafblk) {
ret = write_buf(iocur_top);
goto out_pop;
}
- obfuscate_dir_data_block(iocur_top->data, o,
- last == mp->m_dirblkfsbs);
+ process_dir_data_block(iocur_top->data, o,
+ last == mp->m_dirblkfsbs);
iocur_top->need_crc = 1;
ret = write_buf(iocur_top);
out_pop:
--
2.1.4