|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 0/4] libfsimage: validate untrusted on-disk metadata in pygrub filesystem plugins
libfsimage is the set of read-only filesystem parsers that pygrub links in to
read a guest's /boot and grub configuration. When pygrub runs, these parsers
are handed a disk image that is fully controlled by the guest and are executed
in dom0. The on-disk metadata of that image is therefore untrusted input, in
exactly the same way the iso9660 metadata addressed by XSA-497 was, and the
superblock sanity checking added by XSA-443 does not reach the inode-level and
directory-level fields touched here.
Auditing the ext2, reiserfs, ufs and xfs plugins turned up a number of on-disk
fields that are used without validation. This series adds bounds/validity
checks at the point each field is consumed. The four patches are independent
and each is confined to a single plugin:
[PATCH 1/4] libfsimage/ext2: validate attacker-controlled superblock and
extent fields
[PATCH 2/4] libfsimage/reiserfs: validate item counts and journal length
[PATCH 3/4] libfsimage/ufs: validate superblock divisors and directory
record length
[PATCH 4/4] libfsimage/xfs: bound inline extent count and directory
btree traversals
The 14 issues fixed fall into four classes:
- Out-of-bounds write (CWE-787): ext2 s_log_block_size sizes the fixed
FSYS_BUFLEN block buffers, so an oversized value makes ext2_rdfsb() write
a block past the buffer.
- Out-of-bounds read (CWE-125): ext4 eh_entries; reiserfs blk_nr_item,
ih_entry_count and journal j_len; xfs di_nextents. Each is iterated or
indexed as an array count without being bounded to the structure that
holds it.
- Divide-by-zero / SIGFPE (CWE-369): ext2 s_inode_size and
s_inodes_per_group; ufs fs_inopb and fs_ipg. Each is used as a divisor
and can be zero.
- Uncontrolled recursion / infinite loop, i.e. denial of service
(CWE-674 / CWE-835): ext2 ext4_recurse_extent_index() (self-referencing
index block -> stack overflow) and a zero directory rec_len; ufs a zero
d_reclen directory entry; xfs the bmap btree descent and the directory
da-btree descent in first_dentry() (a node whose child pointer never
reaches a leaf, e.g. one pointing to itself, loops forever).
Trust boundary and scope
------------------------
The attacker is a guest that supplies the disk image; the affected code runs
in the pygrub process in dom0 while parsing that image's filesystem metadata.
The impact demonstrated is limited to crashing or hanging the pygrub parse
(out-of-bounds read/write within the plugin, SIGFPE, or an unterminated
loop). No sandbox or privilege escape is claimed, and these are not proposed
as security fixes: pygrub is only security supported when run de-privileged
(XSA-508), so this series is hardening of the same unvalidated-on-disk-metadata
class as XSA-497 (iso9660) rather than a fix for a supported configuration.
Each issue was reproduced against a locally built, ASAN-instrumented static
link of the affected plugin driven through the normal mount + open path with a
hand-crafted image. As a regression control, a genuine well-formed image of
each of the four filesystems (e.g. a plain mke2fs ext2 image) still mounts and
resolves a file after the change, so the added validation does not reject
legitimate on-disk values.
SounLabs (4):
libfsimage/ext2: validate attacker-controlled superblock and extent
fields
libfsimage/reiserfs: validate item counts and journal length
libfsimage/ufs: validate superblock divisors and directory record
length
libfsimage/xfs: bound inline extent count and directory btree
traversals
tools/libfsimage/ext2fs/fsys_ext2fs.c | 48 +++++++++++++++++--
tools/libfsimage/reiserfs/fsys_reiserfs.c | 46 +++++++++++++++++-
tools/libfsimage/ufs/fsys_ufs.c | 11 ++++-
tools/libfsimage/xfs/fsys_xfs.c | 57 +++++++++++++++++++++--
4 files changed, 153 insertions(+), 9 deletions(-)
--
2.52.0.windows.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |