From 9b87badc1f6165e33bc4d0b8c4c445aa935a2cc4 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Tue, 9 Apr 2019 15:01:35 -0700 Subject: [PATCH] - Add fix and tests for nilfs2 sigsegv --- ...-case-2nd-nilfs2-superblock-magic-ac.patch | 53 +++++++ ...igsegv-when-false-nilfs2-superblock-.patch | 132 ++++++++++++++++++ parted.spec | 7 +- 3 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 0110-Avoid-sigsegv-in-case-2nd-nilfs2-superblock-magic-ac.patch create mode 100644 0111-Tests-case-for-sigsegv-when-false-nilfs2-superblock-.patch diff --git a/0110-Avoid-sigsegv-in-case-2nd-nilfs2-superblock-magic-ac.patch b/0110-Avoid-sigsegv-in-case-2nd-nilfs2-superblock-magic-ac.patch new file mode 100644 index 0000000..c1a51ee --- /dev/null +++ b/0110-Avoid-sigsegv-in-case-2nd-nilfs2-superblock-magic-ac.patch @@ -0,0 +1,53 @@ +From b951c46fab0efe29adc43d7fff7ed4201adcde7d Mon Sep 17 00:00:00 2001 +From: Michael Small +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 + diff --git a/0111-Tests-case-for-sigsegv-when-false-nilfs2-superblock-.patch b/0111-Tests-case-for-sigsegv-when-false-nilfs2-superblock-.patch new file mode 100644 index 0000000..ab78aef --- /dev/null +++ b/0111-Tests-case-for-sigsegv-when-false-nilfs2-superblock-.patch @@ -0,0 +1,132 @@ +From 4135de60aaad363644a67c6f52b7ea977a16a7b9 Mon Sep 17 00:00:00 2001 +From: Michael Small +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 . ++ ++. "${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 . ++ ++# 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 + diff --git a/parted.spec b/parted.spec index fe466cf..d4cb3d4 100644 --- a/parted.spec +++ b/parted.spec @@ -4,7 +4,7 @@ Summary: The GNU disk partition manipulation program Name: parted Version: 3.2 -Release: 40%{?dist} +Release: 41%{?dist} License: GPLv3+ 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 Patch0108: 0108-Added-support-for-Windows-recovery-partition-WINRE-o.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 @@ -241,6 +243,9 @@ make check %changelog +* Tue Apr 09 2019 Brian C. Lane - 3.2-41 +- Add fix and tests for nilfs2 sigsegv + * Fri Mar 01 2019 Brian C. Lane - 3.2-40 - Run the CI tests using rpmbuild - t6000-dm: Stop using private lvm root