From a7b60d7ccf8b31846a09b2d0b3e6c2f45cbee4e0 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 7 Sep 2015 13:00:00 +0200 Subject: [PATCH] 0.163-4 Add elfutils-0.163-readelf-n-undefined-shift.patch Resolves: #1259259 --- ...tils-0.163-readelf-n-undefined-shift.patch | 49 +++++++++++++++++++ elfutils.spec | 8 ++- 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 elfutils-0.163-readelf-n-undefined-shift.patch diff --git a/elfutils-0.163-readelf-n-undefined-shift.patch b/elfutils-0.163-readelf-n-undefined-shift.patch new file mode 100644 index 0000000..a26e209 --- /dev/null +++ b/elfutils-0.163-readelf-n-undefined-shift.patch @@ -0,0 +1,49 @@ +commit b00a4fa78779ff0f304fa6cb34d49622679c86d4 +Author: Mark Wielaard +Date: Thu Sep 3 10:50:58 2015 +0200 + + readelf: handle_core_item large right shift triggers undefined behaviour. + + The problem is this: + + int n = ffs (w); + w >>= n; + + The intent is to shift away up to (and including) the first least + significant bit in w. But w is an unsigned int, so 32 bits. And the + least significant bit could be bit 32 (ffs counts from 1). Unfortunately + a right shift equal to (or larger than) the length in bits of the left + hand operand is undefined behaviour. We expect w to be zero afterwards. + Which would terminate the while loop in the function. But since it is + undefined behaviour anything can happen. In this case, what will actually + happen is that w is unchanged, causing an infinite loop... + + gcc -fsanitize=undefined will catch and warn about this when w = 0x80000000 + + https://bugzilla.redhat.com/show_bug.cgi?id=1259259 + + Signed-off-by: Mark Wielaard + +diff --git a/src/readelf.c b/src/readelf.c +index d3c2b6b..aab8b5c 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -8474,8 +8474,16 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, + unsigned int w = negate ? ~*i : *i; + while (w != 0) + { +- int n = ffs (w); +- w >>= n; ++ /* Note that a right shift equal to (or greater than) ++ the number of bits of w is undefined behaviour. In ++ particular when the least significant bit is bit 32 ++ (w = 0x8000000) then w >>= n is undefined. So ++ explicitly handle that case separately. */ ++ unsigned int n = ffs (w); ++ if (n < sizeof (w) * 8) ++ w >>= n; ++ else ++ w = 0; + bit += n; + + if (lastbit != 0 && lastbit + 1 == bit) diff --git a/elfutils.spec b/elfutils.spec index 77b7a04..ec4fbfc 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,7 +1,7 @@ Name: elfutils Summary: A collection of utilities and DSOs to handle compiled objects Version: 0.163 -%global baserelease 3 +%global baserelease 4 URL: https://fedorahosted.org/elfutils/ %global source_url http://fedorahosted.org/releases/e/l/elfutils/%{version}/ License: GPLv3+ and (GPLv2+ or LGPLv3+) @@ -49,8 +49,8 @@ Source: %{?source_url}%{name}-%{version}.tar.bz2 Patch1: %{?source_url}elfutils-portability-%{version}.patch Patch2: elfutils-0.163-unstrip-shf_info_link.patch - Patch3: elfutils-0.163-default-yama-conf.patch +Patch4: elfutils-0.163-readelf-n-undefined-shift.patch %if !%{compat} Release: %{baserelease}%{?dist} @@ -236,6 +236,7 @@ sed -i.scanf-m -e 's/%m/%a/g' src/addr2line.c tests/line2addr.c %patch2 -p1 -b .shf_info_link %patch3 -p1 -b .yama_scope +%patch4 -p1 -b .right_shift find . -name \*.sh ! -perm -0100 -print | xargs chmod +x @@ -380,6 +381,9 @@ rm -rf ${RPM_BUILD_ROOT} %endif %changelog +* Mon Sep 07 2015 Mark Wielaard - 0.163-4 +- Add elfutils-0.163-readelf-n-undefined-shift.patch (#1259259) + * Tue Aug 04 2015 Mark Wielaard - 0.163-3 - Add elfutils-0.163-default-yama-conf.patch (#1250079) Provides: default-yama-scope