File 0014-metadump-Zero-unused-portions-of-inode-literal-area.patch of Package xfsprogs.8514
From 87c955c38317de8cfd189082bb8d214a59280472 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@sandeen.net>
Date: Thu, 30 Jul 2015 09:17:43 +1000
Subject: [PATCH 14/20] metadump: Zero unused portions of inode literal area
References: bsc#939367 CVE-2012-2150
The data & attr regions of the inode literal area
are rarely full; unused portions should be zeroed
out so that we don't copy stale 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 | 54 ++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 40 insertions(+), 14 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index a1e023d3615d..775deb5274fd 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -963,7 +963,7 @@ generate_obfuscated_name(
}
static void
-obfuscate_sf_dir(
+process_sf_dir(
xfs_dinode_t *dip)
{
struct xfs_dir2_sf_hdr *sfp;
@@ -1010,12 +1010,18 @@ obfuscate_sf_dir(
(char *)sfp);
}
- generate_obfuscated_name(xfs_dir3_sfe_get_ino(mp, sfp, sfep),
+ if (obfuscate)
+ generate_obfuscated_name(
+ xfs_dir3_sfe_get_ino(mp, sfp, sfep),
namelen, &sfep->name[0]);
sfep = (xfs_dir2_sf_entry_t *)((char *)sfep +
xfs_dir3_sf_entsize(mp, sfp, namelen));
}
+
+ /* zero stale data in rest of space in data fork, if any */
+ if (zero_stale_data && (ino_dir_size < XFS_DFORK_DSIZE(dip, mp)))
+ memset(sfep, 0, XFS_DFORK_DSIZE(dip, mp) - ino_dir_size);
}
/*
@@ -1062,7 +1068,7 @@ obfuscate_path_components(
}
static void
-obfuscate_sf_symlink(
+process_sf_symlink(
xfs_dinode_t *dip)
{
__uint64_t len;
@@ -1077,11 +1083,16 @@ obfuscate_sf_symlink(
}
buf = (char *)XFS_DFORK_DPTR(dip);
- obfuscate_path_components(buf, len);
+ if (obfuscate)
+ obfuscate_path_components(buf, len);
+
+ /* zero stale data in rest of space in data fork, if any */
+ if (zero_stale_data && len < XFS_DFORK_DSIZE(dip, mp))
+ memset(&buf[len], 0, XFS_DFORK_DSIZE(dip, mp) - len);
}
static void
-obfuscate_sf_attr(
+process_sf_attr(
xfs_dinode_t *dip)
{
/*
@@ -1125,12 +1136,20 @@ obfuscate_sf_attr(
break;
}
- generate_obfuscated_name(0, asfep->namelen, &asfep->nameval[0]);
- memset(&asfep->nameval[asfep->namelen], 'v', asfep->valuelen);
+ if (obfuscate) {
+ generate_obfuscated_name(0, asfep->namelen,
+ &asfep->nameval[0]);
+ memset(&asfep->nameval[asfep->namelen], 'v',
+ asfep->valuelen);
+ }
asfep = (xfs_attr_sf_entry_t *)((char *)asfep +
XFS_ATTR_SF_ENTSIZE(asfep));
}
+
+ /* zero stale data in rest of space in attr fork, if any */
+ if (zero_stale_data && (ino_attr_size < XFS_DFORK_ASIZE(dip, mp)))
+ memset(asfep, 0, XFS_DFORK_ASIZE(dip, mp) - ino_attr_size);
}
static void
@@ -1717,19 +1736,26 @@ process_exinode(
typnm_t itype)
{
int whichfork;
+ int used;
xfs_extnum_t nex;
whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
nex = XFS_DFORK_NEXTENTS(dip, whichfork);
- if (nex < 0 || nex > XFS_DFORK_SIZE(dip, mp, whichfork) /
- sizeof(xfs_bmbt_rec_t)) {
+ used = nex * sizeof(xfs_bmbt_rec_t);
+ if (nex < 0 || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
if (show_warnings)
print_warning("bad number of extents %d in inode %lld",
nex, (long long)cur_ino);
return 1;
}
+ /* Zero unused data fork past used extents */
+ if (zero_stale_data && (used < XFS_DFORK_SIZE(dip, mp, whichfork)))
+ memset(XFS_DFORK_PTR(dip, whichfork) + used, 0,
+ XFS_DFORK_SIZE(dip, mp, whichfork) - used);
+
+
return process_bmbt_reclist((xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip,
whichfork), nex, itype);
}
@@ -1741,14 +1767,14 @@ process_inode_data(
{
switch (dip->di_format) {
case XFS_DINODE_FMT_LOCAL:
- if (obfuscate)
+ if (obfuscate || zero_stale_data)
switch (itype) {
case TYP_DIR2:
- obfuscate_sf_dir(dip);
+ process_sf_dir(dip);
break;
case TYP_SYMLINK:
- obfuscate_sf_symlink(dip);
+ process_sf_symlink(dip);
break;
default: ;
@@ -1827,8 +1853,8 @@ process_inode(
switch (dip->di_aformat) {
case XFS_DINODE_FMT_LOCAL:
need_new_crc = 1;
- if (obfuscate)
- obfuscate_sf_attr(dip);
+ if (obfuscate || zero_stale_data)
+ process_sf_attr(dip);
break;
case XFS_DINODE_FMT_EXTENTS:
--
2.1.4