- Add fix and tests for nilfs2 sigsegv

This commit is contained in:
Brian C. Lane 2019-04-09 15:01:35 -07:00
parent e4f4556ff6
commit 9b87badc1f
3 changed files with 191 additions and 1 deletions

View File

@ -0,0 +1,53 @@
From b951c46fab0efe29adc43d7fff7ed4201adcde7d Mon Sep 17 00:00:00 2001
From: Michael Small <smallm@sdf.org>
Date: Fri, 8 Feb 2019 17:01:43 -0500
Subject: [PATCH 110/111] Avoid sigsegv in case 2nd nilfs2 superblock magic
accidently found.
1. is_valid_nilfs_sb: make sure the subtraction bytes - sumoff - 4
won't give a negative number. That as the len argument to
__efi_crc32() would give a very large number for the latter's for
loop limit, since len is unsigned long.
2. nilfs2_probe: Read and allocate enough sectors to hold a
struct nilfs2_super_block. is_valid_nilfs_sb() will be passing
up to 1024 bytes to __efi_crc32(). If only one 512 byte sector
had been allocated with alloca and read from disk that would cause
reads off the the end of the stack even if bytes were more than
sumoff - 4.
---
libparted/fs/nilfs2/nilfs2.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/libparted/fs/nilfs2/nilfs2.c b/libparted/fs/nilfs2/nilfs2.c
index b42a464..52f757c 100644
--- a/libparted/fs/nilfs2/nilfs2.c
+++ b/libparted/fs/nilfs2/nilfs2.c
@@ -89,7 +89,7 @@ is_valid_nilfs_sb(struct nilfs2_super_block *sb)
return 0;
bytes = PED_LE16_TO_CPU(sb->s_bytes);
- if (bytes > 1024)
+ if (bytes > 1024 || bytes < sumoff - 4)
return 0;
crc = __efi_crc32(sb, sumoff, PED_LE32_TO_CPU(sb->s_crc_seed));
@@ -113,11 +113,13 @@ nilfs2_probe (PedGeometry* geom)
const int sectors = (4096 + geom->dev->sector_size - 1) /
geom->dev->sector_size;
char *buf = alloca (sectors * geom->dev->sector_size);
- void *buff2 = alloca (geom->dev->sector_size);
+ const int sectors2 = (1024 + geom->dev->sector_size -1 ) /
+ geom->dev->sector_size;
+ void *buff2 = alloca (sectors2 * geom->dev->sector_size);
if (ped_geometry_read(geom, buf, 0, sectors))
sb = (struct nilfs2_super_block *)(buf+1024);
- if (ped_geometry_read(geom, buff2, sb2off, 1))
+ if (ped_geometry_read(geom, buff2, sb2off, sectors2))
sb2 = buff2;
if ((!sb || !is_valid_nilfs_sb(sb)) &&
--
2.20.1

View File

@ -0,0 +1,132 @@
From 4135de60aaad363644a67c6f52b7ea977a16a7b9 Mon Sep 17 00:00:00 2001
From: Michael Small <smallm@sdf.org>
Date: Wed, 13 Feb 2019 16:05:21 -0500
Subject: [PATCH 111/111] Tests case for sigsegv when false nilfs2 superblock
detected.
---
tests/Makefile.am | 2 ++
tests/t4301-nilfs2-badsb2.sh | 43 +++++++++++++++++++++++++++++
tests/t4302-nilfs2-lessbadsb2.sh | 47 ++++++++++++++++++++++++++++++++
3 files changed, 92 insertions(+)
create mode 100755 tests/t4301-nilfs2-badsb2.sh
create mode 100755 tests/t4302-nilfs2-lessbadsb2.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3fa75a9..0d7c022 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -66,6 +66,8 @@ TESTS = \
t4100-msdos-starting-sector.sh \
t4200-partprobe.sh \
t4300-nilfs2-tiny.sh \
+ t4301-nilfs2-badsb2.sh \
+ t4302-nilfs2-lessbadsb2.sh \
t5000-tags.sh \
t6000-dm.sh \
t6001-psep.sh \
diff --git a/tests/t4301-nilfs2-badsb2.sh b/tests/t4301-nilfs2-badsb2.sh
new file mode 100755
index 0000000..cef8a9a
--- /dev/null
+++ b/tests/t4301-nilfs2-badsb2.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+# Trigger a nilfs2-related bug.
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../parted
+ss=$sector_size_
+len=32
+dev=dev-file
+
+dd if=/dev/zero of=$dev bs=512 count=$(($len+$ss/512)) || framework_failure_
+
+end=$(($len * 512 / $ss))
+parted -s $dev mklabel msdos mkpart primary 1s ${end}s || framework_failure_
+
+# Write a secondary superblock with the nilfs magic number and a nilfs
+# superblock length (s_bytes) field of only 10 bytes.
+# struct nilfs2_super_block starts with these four fields...
+# uint32_t s_rev_level;
+# uint16_t s_minor_rev_level;
+# uint16_t s_magic;
+# uint16_t s_bytes;
+sb2_offset=$(( 24 / ($ss / 512) + 1))
+perl -e "print pack 'LSSS.', 0, 0, 0x3434, 10, $ss" |
+ dd of=$dev bs=$ss seek=$sb2_offset count=1 conv=notrunc
+
+# This used to give parted a sigsegv.
+parted -s $dev print || fail=1
+
+Exit $fail
diff --git a/tests/t4302-nilfs2-lessbadsb2.sh b/tests/t4302-nilfs2-lessbadsb2.sh
new file mode 100755
index 0000000..a46dccf
--- /dev/null
+++ b/tests/t4302-nilfs2-lessbadsb2.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# Trigger a nilfs2-related bug.
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This test is like t4301-nilfsbadsb2 except with an s_bytes field of
+# 1024 instead of 10. This exercises a less obvious bug.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../parted
+ss=$sector_size_
+len=32
+dev=dev-file
+
+dd if=/dev/zero of=$dev bs=512 count=$(($len+$ss/512)) || framework_failure_
+
+end=$(($len * 512 / $ss))
+parted -s $dev mklabel msdos mkpart primary 1s ${end}s || framework_failure_
+
+# Write a secondary superblock with the nilfs magic number and a nilfs
+# superblock length (s_bytes) field of only 10 bytes.
+# struct nilfs2_super_block starts with these four fields...
+# uint32_t s_rev_level;
+# uint16_t s_minor_rev_level;
+# uint16_t s_magic;
+# uint16_t s_bytes;
+sb2_offset=$(( 24 / ($ss / 512) + 1))
+perl -e "print pack 'LSSS.', 0, 0, 0x3434, 1024, $ss" |
+ dd of=$dev bs=$ss seek=$sb2_offset count=1 conv=notrunc
+
+# This used to read past the part of the stack allocated by alloca, but
+# may or may not cause a segmentation fault as a result.
+parted -s $dev print || fail=1
+
+Exit $fail
--
2.20.1

View File

@ -4,7 +4,7 @@
Summary: The GNU disk partition manipulation program Summary: The GNU disk partition manipulation program
Name: parted Name: parted
Version: 3.2 Version: 3.2
Release: 40%{?dist} Release: 41%{?dist}
License: GPLv3+ License: GPLv3+
URL: http://www.gnu.org/software/parted URL: http://www.gnu.org/software/parted
@ -129,6 +129,8 @@ Patch0106: 0106-clean-the-disk-information-when-commands-fail-in-int.patch
Patch0107: 0107-parted-Remove-PED_ASSERT-from-ped_partition_set_name.patch Patch0107: 0107-parted-Remove-PED_ASSERT-from-ped_partition_set_name.patch
Patch0108: 0108-Added-support-for-Windows-recovery-partition-WINRE-o.patch Patch0108: 0108-Added-support-for-Windows-recovery-partition-WINRE-o.patch
Patch0109: 0109-t6000-dm-Stop-using-private-lvm-root.patch Patch0109: 0109-t6000-dm-Stop-using-private-lvm-root.patch
Patch0110: 0110-Avoid-sigsegv-in-case-2nd-nilfs2-superblock-magic-ac.patch
Patch0111: 0111-Tests-case-for-sigsegv-when-false-nilfs2-superblock-.patch
BuildRequires: gcc BuildRequires: gcc
@ -241,6 +243,9 @@ make check
%changelog %changelog
* Tue Apr 09 2019 Brian C. Lane <bcl@redhat.com> - 3.2-41
- Add fix and tests for nilfs2 sigsegv
* Fri Mar 01 2019 Brian C. Lane <bcl@redhat.com> - 3.2-40 * Fri Mar 01 2019 Brian C. Lane <bcl@redhat.com> - 3.2-40
- Run the CI tests using rpmbuild - Run the CI tests using rpmbuild
- t6000-dm: Stop using private lvm root - t6000-dm: Stop using private lvm root