Urgent: x86-32 and GNU ld 2.22.52.0.1
H. Peter Anvin
reviewerI need an urgent opinion. It seems we have an epic mess on our hands.
GNU ld 2.22.52.0.1 silently changed the semantics of section-relative symbols that are part of otherwise empty sections, and silently changes them to absolute. We rely on section-relative symbols staying section-relative, and actually have several sections in the linker script solely for this purpose.
The postprocessor for the x86-32 kernel, relocs.c, currently doesn't enforce its audited absolute symbols list. As part of the tip:x86/trampoline rework, however, I made it error out rather that silently producing bad output.
Ingo has found that with this particular version of GNU ld, the error triggers. I want to emphasize that this merely catches an error which the current version of the tool would have allowed to silently go by, which would have (possibly) caused a failure if the kernel was subsequently booted in anything but its default location.
There are a few ways we can deal with this, but I think we need to do one or the other:
1. We can blacklist this version of GNU ld.
2. We can uprev the tool to the one from the tip:x86/trampoline work, with error checking, and give it a list of symbols that should be relative but may end up as absolute. We risk build errors for some people if the list isn't complete.
3. We do a minimal forward-port of the error checking into the current tool.
4. We add to the list of relative symbols in the current version of the tool without adding the error checking.
However, since it seems clear that we're silently producing corrupt kernels out of the current build, I think we need a fix for this for 3.4.
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Quoted 32 lines · H. Peter Anvin
I need an urgent opinion. It seems we have an epic mess on our hands.
GNU ld 2.22.52.0.1 silently changed the semantics of section-relative symbols that are part of otherwise empty sections, and silently changes them to absolute. We rely on section-relative symbols staying section-relative, and actually have several sections in the linker script solely for this purpose.
The postprocessor for the x86-32 kernel,
relocs.c, currently doesn't enforce its audited absolute symbols list. As part of the tip:x86/trampoline rework, however, I made it error out rather that silently producing bad output.Ingo has found that with this particular version of GNU ld, the error triggers. I want to emphasize that this merely catches an error which the current version of the tool would have allowed to silently go by, which would have (possibly) caused a failure if the kernel was subsequently booted in anything but its default location.
There are a few ways we can deal with this, but I think we need to do one or the other:
1. We can blacklist this version of GNU ld.
2. We can uprev the tool to the one from the tip:x86/trampoline work, with error checking, and give it a list of symbols that should be relative but may end up as absolute. We risk build errors for some people if the list isn't complete.
3. We do a minimal forward-port of the error checking into the current tool.
4. We add to the list of relative symbols in the current version of the tool without adding the error checking.
Quoted 3 lines
However, since it seems clear that we're silently producing corrupt kernels out of the current build, I think we need a fix for this for 3.4.
For the record, these are the checkins out of the -tip tree. They are a little bigger than necessary because they move the tool around to make it available for reuse, and of course introduce additional functionality.
-hpa
Quoted 1 line
From
bea3f8781e30d0abc0bd0da80aa528d44c71959eMon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <[email protected]>
Date: Fri, 18 May 2012 00:24:09 -0700
Subject: [PATCH] x86, relocs: Workaround for binutils 2.22.52.0.1 section bug
GNU ld 2.22.52.0.1 has a bug that it blindly changes symbols from section-relative to absolute if they are in a section of zero length. This turns the symbols __init_begin and __init_end into absolute symbols. Let the relocs program know that those should be treated as relative symbols.
--- arch/x86/tools/relocs.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/tools/relocs.c +1 -1
@@ -56,7 +56,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {* as absolute (typically defined outside any section in the linker script.) */ [S_REL ] = - "^_end$", +"^(__init_begin|__init_end|_end)$" };
Signature · 1 line
1.7.6.5
Quoted 1 line
From
f2604c141a00c00b92b7fd2f9d2455517fdd6c15Mon Sep 17 00:00:00 2001
From: Jarkko Sakkinen <[email protected]>
Date: Tue, 8 May 2012 21:22:44 +0300
Subject: [PATCH 21/34] x86, realmode: move relocs from scripts/ to
arch/x86/tools
Moved relocs tool from scripts/ to arch/x86/tools because it is architecture specific script. Added new target archscripts that can be used to build scripts needed building an architecture.
--- Makefile | 9 +- arch/x86/Makefile | 3 + arch/x86/boot/compressed/Makefile | 4 +- arch/x86/realmode/rm/Makefile | 2 +- arch/x86/tools/.gitignore | 1 + arch/x86/tools/Makefile | 4 + arch/x86/tools/relocs.c | 804 +++++++++++++++++++++++++++++++++++++ scripts/Makefile | 1 - scripts/x86-relocs.c | 804 ------------------------------------- 9 files changed, 821 insertions(+), 811 deletions(-) create mode 100644 arch/x86/tools/.gitignore create mode 100644 arch/x86/tools/relocs.c delete mode 100644 scripts/x86-relocs.c
Makefile +6 -3
@@ -442,7 +442,7 @@ asm-generic: no-dot-config-targets := clean mrproper distclean \ cscope gtags TAGS tags help %docs check% coccicheck \ - include/linux/version.h headers_% archheaders \ + include/linux/version.h headers_% archheaders archscripts \ kernelversion %src-pkg config-targets := 0
@@ -979,7 +979,7 @@ prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \ include/config/auto.conf $(cmd_crmodverdir) -archprepare: archheaders prepare1 scripts_basic +archprepare: archheaders archscripts prepare1 scripts_basic prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=.
@@ -1049,8 +1049,11 @@ hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) PHONY += archheaders archheaders: +PHONY += archscripts +archscripts: + PHONY += __headers -__headers: include/linux/version.h scripts_basic asm-generic archheaders FORCE +__headers: include/linux/version.h scripts_basic asm-generic archheaders archscripts FORCE $(Q)$(MAKE) $(build)=scripts build_unifdef PHONY += headers_install_all
arch/x86/Makefile +3 -0
@@ -134,6 +134,9 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,) KBUILD_CFLAGS += $(mflags-y) KBUILD_AFLAGS += $(mflags-y) +archscripts: + $(Q)$(MAKE) $(build)=arch/x86/tools relocs + ### # Syscall table generation
arch/x86/boot/compressed/Makefile +2 -2
@@ -42,8 +42,8 @@ $(obj)/vmlinux.bin: vmlinux FORCE targets += vmlinux.bin.all vmlinux.relocs -CMD_RELOCS = scripts/x86-relocs -quiet_cmd_relocs = RELOCS $@ +CMD_RELOCS = arch/x86/tools/relocs +quiet_cmd_relocs = RELOCS $@ cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< $(obj)/vmlinux.relocs: vmlinux FORCE $(call if_changed,relocs)
arch/x86/realmode/rm/Makefile +1 -1
@@ -52,7 +52,7 @@ $(obj)/realmode.bin: $(obj)/realmode.elf $(call if_changed,objcopy) quiet_cmd_relocs = RELOCS $@ - cmd_relocs = scripts/x86-relocs --realmode $< > $@ + cmd_relocs = arch/x86/tools/relocs --realmode $< > $@ $(obj)/realmode.relocs: $(obj)/realmode.elf FORCE $(call if_changed,relocs)
arch/x86/tools/.gitignore new file +1 -0
@@ -0,0 +1 @@ +relocs
arch/x86/tools/Makefile +4 -0
@@ -36,3 +36,7 @@ HOSTCFLAGS_insn_sanity.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x $(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c + +HOST_EXTRACFLAGS += -I$(srctree)/tools/include +hostprogs-y += relocs +relocs: $(obj)/relocs
arch/x86/tools/relocs.c new file +804 -0
804 lines not on this page · raw message
scripts/Makefile +0 -1
@@ -15,7 +15,6 @@ hostprogs-$(CONFIG_LOGO) += pnmtologo hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(CONFIG_IKCONFIG) += bin2c hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount -hostprogs-$(CONFIG_X86) += x86-relocs always := $(hostprogs-y) $(hostprogs-m)
scripts/x86-relocs.c deleted +0 -804
804 lines not on this page · raw message
Signature · 1 line
1.7.6.5
Quoted 1 line
From
bea3f8781e30d0abc0bd0da80aa528d44c71959eMon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <[email protected]>
Date: Fri, 18 May 2012 00:24:09 -0700
Subject: [PATCH 33/34] x86, relocs: Workaround for binutils 2.22.52.0.1
section bug
GNU ld 2.22.52.0.1 has a bug that it blindly changes symbols from section-relative to absolute if they are in a section of zero length. This turns the symbols __init_begin and __init_end into absolute symbols. Let the relocs program know that those should be treated as relative symbols.
--- arch/x86/tools/relocs.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/tools/relocs.c +1 -1
@@ -56,7 +56,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {* as absolute (typically defined outside any section in the linker script.) */ [S_REL ] = - "^_end$", +"^(__init_begin|__init_end|_end)$" };
Signature · 1 line
1.7.6.5
Quoted 1 line
From
c54a354c1835e7412a53458891b9ea05361b4e8aMon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <[email protected]>
Date: Fri, 18 May 2012 08:31:44 -0700
Subject: [PATCH 34/34] x86, relocs: More relocations which may end up as
absolute
GNU ld 2.22.52.0.1 has a bug that it blindly changes symbols from section-relative to absolute if they are in a section of zero length. This turns the symbols __init_begin and __init_end into absolute symbols. Let the relocs program know that those should be treated as relative symbols.
This bug is exposed by checkin
433de739bbc2 x86, realmode: 16-bit real-mode code support for relocs tool
only in the sense that that checkin changes the relocs tool to report an error instead of silently generating a kernel which is broken if relocated.
--- arch/x86/tools/relocs.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
arch/x86/tools/relocs.c +5 -1
@@ -56,7 +56,11 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {* as absolute (typically defined outside any section in the linker script.) */ [S_REL ] = -"^(__init_begin|__init_end|_end)$" +"^(__init_(begin|end)|" +"__x86_cpu_dev_(start|end)|" +"(__parainstructions|__alt_instructions)(|_end)|" +"(__iommu_table|__apicdrivers|__smp_locks)(|_end)|" +"_end)$" };
Signature · 1 line
1.7.6.5
Quoted 7 lines · H. Peter Anvin
I need an urgent opinion. It seems we have an epic mess on our hands.
GNU ld 2.22.52.0.1 silently changed the semantics of section-relative symbols that are part of otherwise empty sections, and silently changes them to absolute. We rely on section-relative symbols staying section-relative, and actually have several sections in the linker script solely for this purpose.
That is I talked to you a couple days ago:
http://sourceware.org/bugzilla/show_bug.cgi?id=14052
Quoted 11 lines
The postprocessor for the x86-32 kernel,
relocs.c, currently doesn't enforce its audited absolute symbols list. As part of the tip:x86/trampoline rework, however, I made it error out rather that silently producing bad output.Ingo has found that with this particular version of GNU ld, the error triggers. I want to emphasize that this merely catches an error which the current version of the tool would have allowed to silently go by, which would have (possibly) caused a failure if the kernel was subsequently booted in anything but its default location.
Quoted 4 lines
There are a few ways we can deal with this, but I think we need to do one or the other:
1. We can blacklist this version of GNU ld.
I think this is the best approach.
Quoted 12 lines
2. We can uprev the tool to the one from the tip:x86/trampoline work, with error checking, and give it a list of symbols that should be relative but may end up as absolute. We risk build errors for some people if the list isn't complete.
3. We do a minimal forward-port of the error checking into the current tool.
4. We add to the list of relative symbols in the current version of the tool without adding the error checking.However, since it seems clear that we're silently producing corrupt kernels out of the current build, I think we need a fix for this for 3.4.
Signature · 1 line
H.J.
Quoted 24 lines · H.J. Lu
Quoted 7 lines · H. Peter Anvin
I need an urgent opinion. It seems we have an epic mess on our hands.
GNU ld 2.22.52.0.1 silently changed the semantics of section-relative symbols that are part of otherwise empty sections, and silently changes them to absolute. We rely on section-relative symbols staying section-relative, and actually have several sections in the linker script solely for this purpose.
That is I talked to you a couple days ago:
http://sourceware.org/bugzilla/show_bug.cgi?id=14052
Quoted 11 lines
The postprocessor for the x86-32 kernel,
relocs.c, currently doesn't enforce its audited absolute symbols list. As part of the tip:x86/trampoline rework, however, I made it error out rather that silently producing bad output.Ingo has found that with this particular version of GNU ld, the error triggers. I want to emphasize that this merely catches an error which the current version of the tool would have allowed to silently go by, which would have (possibly) caused a failure if the kernel was subsequently booted in anything but its default location.
Quoted 7 lines
Quoted 4 lines
There are a few ways we can deal with this, but I think we need to do one or the other:
1. We can blacklist this version of GNU ld.
I think this is the best approach.
Please verify that binutils 2.22.52.0.2 is broken
and binutils 2.22.52.0.1 is OK.
Signature · 1 line
H.J.
H. Peter Anvin
reviewerQuoted 4 lines · H.J. Lu
Please verify that binutils 2.22.52.0.2 is broken
and binutils 2.22.52.0.1 is OK.
I believe Ingo is using 2.22.52.0.1, and it is most definitely not okay.
<mingo> GNU ld version 2.22.52.0.1-5.fc17 20120131 <mingo> gcc version 4.7.0 20120112 (Red Hat 4.7.0-0.6) (GCC)
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Quoted 11 lines · H. Peter Anvin
Quoted 4 lines · H.J. Lu
Please verify that binutils 2.22.52.0.2 is broken
and binutils 2.22.52.0.1 is OK.I believe Ingo is using 2.22.52.0.1, and it is most definitely not okay.
<mingo> GNU ld version 2.22.52.0.1-5.fc17 20120131 <mingo> gcc version 4.7.0 20120112 (Red Hat 4.7.0-0.6) (GCC)
In that case, both 2.22.52.0.1 and 2.22.52.0.2 are bad.
Signature · 1 line
H.J.
H. Peter Anvin
reviewerQuoted 3 lines · H.J. Lu
In that case, both 2.22.52.0.1 and 2.22.52.0.2 are bad.
I suspect that really means we should have a patch which verifies by construction, and not rely on version numbers.
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Quoted 8 lines · H. Peter Anvin
Quoted 3 lines · H.J. Lu
In that case, both 2.22.52.0.1 and 2.22.52.0.2 are bad.
I suspect that really means we should have a patch which verifies by construction, and not rely on version numbers.
A small testcase:
[hjl@gnu-6 pr14052]$ cat pr14052.s
.text
.global start /* Used by SH targets. */
start:
.global _start_start:
.global __start__start:
.global main /* Used by HPPA targets. */
main:
.dc.a 0
[hjl@gnu-6 pr14052]$ cat pr14052.t
SECTIONS {
.text : {
*(.text)
}
. = ALIGN (0x1000);
.data : {
_data_start = .;
*(.data)
}
/DISCARD/ : { *(.*) }
}[hjl@gnu-6 pr14052]$ make
as -o pr14052.o pr14052.s
./ld -o pr14052 -T pr14052.t pr14052.o
readelf -s pr14052
Symbol table '.symtab' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 SECTION LOCAL DEFAULT 1
2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 __start
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 _start
4: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 _data_start
5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 main
6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 start[hjl@gnu-6 pr14052]$
There should be no symbols in ABS section.
Signature · 1 line
H.J.
H. Peter Anvin
reviewerQuoted 3 lines · H.J. Lu
A small testcase:
Right, but we can equally well just let the postprocessing tool throw an error.
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Quoted 7 lines · H. Peter Anvin
Quoted 3 lines · H.J. Lu
A small testcase:
Right, but we can equally well just let the postprocessing tool throw an error.
That would probably be the best thing to do right now, and we can backport that to the stable kernel releases also to ensure they work properly.
thanks,
greg k-h
H. Peter Anvin
reviewerQuoted 6 lines · Greg KH
Quoted 5 lines · H. Peter Anvin
Quoted 3 lines · H.J. Lu
A small testcase:
Quoted 7 lines
Quoted 2 lines
Right, but we can equally well just let the postprocessing tool throw an error.
That would probably be the best thing to do right now, and we can backport that to the stable kernel releases also to ensure they work properly.
So the question is: do you want to simply take the patches from the trampoline branch (which are reasonably tested) or do a minimal backport which only throws an error (which would not be)?
-hpa
Quoted 10 lines · H. Peter Anvin
Quoted 9 lines · Greg KH
Quoted 7 lines · H. Peter Anvin
Quoted 3 lines · H.J. Lu
A small testcase:
Right, but we can equally well just let the postprocessing tool throw an error.
Quoted 8 lines
Quoted 4 lines
That would probably be the best thing to do right now, and we can backport that to the stable kernel releases also to ensure they work properly.
So the question is: do you want to simply take the patches from the trampoline branch (which are reasonably tested) or do a minimal backport which only throws an error (which would not be)?
All 4 of those patches? They look simple and "sane" to me. They solve the problem even with the "buggy" binutils, right? If so, sure, I'll take those after they land in Linus's tree, which I'm guessing will be for 3.5-rc1, right?
thanks,
greg k-h
H. Peter Anvin
reviewerQuoted 10 lines · Greg KH
Quoted 4 lines
So the question is: do you want to simply take the patches from the trampoline branch (which are reasonably tested) or do a minimal backport which only throws an error (which would not be)?
All 4 of those patches? They look simple and "sane" to me. They solve the problem even with the "buggy" binutils, right? If so, sure, I'll take those after they land in Linus's tree, which I'm guessing will be for 3.5-rc1, right?
We think they fix the problem even with the buggy binutils... and will throw an error if they don't. I intend to push them for 3.5-rc1, but Linus may want something for 3.4.
-hpa
H. Peter Anvin
reviewerQuoted 9 lines · H.J. Lu
Quoted 7 lines · H. Peter Anvin
I need an urgent opinion. It seems we have an epic mess on our hands.
GNU ld 2.22.52.0.1 silently changed the semantics of section-relative symbols that are part of otherwise empty sections, and silently changes them to absolute. We rely on section-relative symbols staying section-relative, and actually have several sections in the linker script solely for this purpose.
Quoted 4 lines
That is I talked to you a couple days ago:
I know, which was a very good thing... otherwise we'd probably not have tracked this down anywhere near as quickly. Thank you.
The problem is that this version of binutils made it into Fedora 17, and so we now have a large number of users with a known bad binutils in the field...
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Quoted 15 lines · H. Peter Anvin
Quoted 9 lines · H.J. Lu
Quoted 7 lines · H. Peter Anvin
I need an urgent opinion. It seems we have an epic mess on our hands.
GNU ld 2.22.52.0.1 silently changed the semantics of section-relative symbols that are part of otherwise empty sections, and silently changes them to absolute. We rely on section-relative symbols staying section-relative, and actually have several sections in the linker script solely for this purpose.
Quoted 4 lines
That is I talked to you a couple days ago:
Quoted 6 lines
I know, which was a very good thing... otherwise we'd probably not have tracked this down anywhere near as quickly. Thank you.
The problem is that this version of binutils made it into Fedora 17, and so we now have a large number of users with a known bad binutils in the field...
We've not seen many kernel bugs that would seem to be blamed on this as of yet. It does seem like a problem waiting to hit us once F17 goes GA though. My limited 32-bit F17 machine collection definitely shows the __init_{begin,end} symbols being absolute, but they boot fine. Likely because the kernel isn't relocated on them.
For what it's worth, I've filed a bug against Fedora binutils here:
https://bugzilla.redhat.com/show_bug.cgi?id=822981
josh
Quoted 23 lines · Josh Boyer
Quoted 15 lines · H. Peter Anvin
Quoted 9 lines · H.J. Lu
Quoted 7 lines · H. Peter Anvin
I need an urgent opinion. It seems we have an epic mess on our hands.
GNU ld 2.22.52.0.1 silently changed the semantics of section-relative symbols that are part of otherwise empty sections, and silently changes them to absolute. We rely on section-relative symbols staying section-relative, and actually have several sections in the linker script solely for this purpose.
Quoted 4 lines
That is I talked to you a couple days ago:
Quoted 6 lines
I know, which was a very good thing... otherwise we'd probably not have tracked this down anywhere near as quickly. Thank you.
The problem is that this version of binutils made it into Fedora 17, and so we now have a large number of users with a known bad binutils in the field...
Quoted 6 lines
We've not seen many kernel bugs that would seem to be blamed on this as of yet. It does seem like a problem waiting to hit us once F17 goes GA though. My limited 32-bit F17 machine collection definitely shows the __init_{begin,end} symbols being absolute, but they boot fine. Likely because the kernel isn't relocated on them.
Relocation is rare, it typically happens with crashdump kernels.
Thanks,
Ingo
H. Peter Anvin
reviewerQuoted 3 lines · Ingo Molnar
Relocation is rare, it typically happens with crashdump kernels.
Or if you boot using EFI (fortunately EFI32 is rare), or you have a screwed-up memory map (which is still rare but is increasingly common.)
For a while some distros, including Fedora, had a messed-up config
which meant it was *always* relocated, but that was a configuration bug which has since been fixed, I believe.
-hpa