linux/arch
Bob Haarman 00bc526dbf FROMLIST: x86_64: fix jiffies ODR violation
`jiffies` and `jiffies_64` are meant to alias (two different symbols
that share the same address).  Most architectures make the symbols alias
to the same address via linker script assignment in their
arch/<arch>/kernel/vmlinux.lds.S:

jiffies = jiffies_64;

which is effectively a definition of jiffies.

jiffies and jiffies_64 are both forward declared for all arch's in:
include/linux/jiffies.h.

jiffies_64 is defined in kernel/time/timer.c for all arch's.

x86_64 was peculiar in that it wasn't doing the above linker script
assignment, but rather was:
1. defining jiffies in arch/x86/kernel/time.c instead via linker script.
2. overriding the symbol jiffies_64 from kernel/time/timer.c in
arch/x86/kernel/vmlinux.lds.s via `jiffies_64 = jiffies;`.

As Fangrui notes:
```
In LLD, symbol assignments in linker scripts override definitions in
object files. GNU ld appears to have the same behavior. It would
probably make sense for LLD to error "duplicate symbol" but GNU ld is
unlikely to adopt for compatibility reasons.
```

So we have an ODR violation (UB), which we seem to have gotten away
with thus far. Where it becomes harmful is when we:

1. Use -fno-semantic-interposition.

As Fangrui notes:
```
Clang after LLVM
commit 5b22bcc2b70d ("[X86][ELF] Prefer to lower MC_GlobalAddress
operands to .Lfoo$local")
defaults to -fno-semantic-interposition similar semantics which help
-fpic/-fPIC code avoid GOT/PLT when the referenced symbol is defined
within the same translation unit. Unlike GCC
-fno-semantic-interposition, Clang emits such relocations referencing
local symbols for non-pic code as well.
```

This causes references to jiffies to refer to `.Ljiffies$local` when
jiffies is defined in the same translation unit. Likewise, references
to jiffies_64 become references to `.Ljiffies_64$local` in translation
units that define jiffies_64.  Because these differ from the names
used in the linker script, they will not be rewritten to alias one
another.

Combined with ...

2. Full LTO effectively treats all source files as one translation
unit, causing these local references to be produced everywhere.  When
the linker processes the linker script, there are no longer any
references to `jiffies_64` anywhere to replace with `jiffies`.  And
thus `.Ljiffies$local` and `.Ljiffies_64$local` no longer alias
at all.

In the process of porting patches enabling Full LTO from arm64 to
x86_64, we observe spooky bugs where the kernel appeared to boot, but
init doesn't get scheduled.

Instead, we can avoid the ODR violation by matching other arch's by
defining jiffies only by linker script.  For -fno-semantic-interposition
+ Full LTO, there is no longer a global definition of jiffies for the
compiler to produce a local symbol which the linker script won't ensure
aliases to jiffies_64.

Link: https://github.com/ClangBuiltLinux/linux/issues/852
Fixes: 40747ffa5a ("asmlinkage: Make jiffies visible")
Cc: stable@vger.kernel.org
Reported-by: Nathan Chancellor <natechancellor@gmail.com>
Reported-by: Alistair Delva <adelva@google.com>
Suggested-by: Fangrui Song <maskray@google.com>
Debugged-by: Nick Desaulniers <ndesaulniers@google.com>
Debugged-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Bob Haarman <inglorion@google.com>

(am from https://lore.kernel.org/lkml/20200515180544.59824-1-inglorion@google.com/T/#u)

Bug: 155426344
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
Change-Id: I6a5d3aeac388a0bc8254b83fa92e12376a04f922
2020-05-18 19:36:15 +00:00
..
alpha mm/special: create generic fallbacks for pte_special() and pte_mkspecial() 2020-04-10 15:36:21 -07:00
arc Linux 5.7-rc3 2020-04-27 13:27:01 +02:00
arm Linux 5.7-rc6 2020-05-18 08:44:32 +02:00
arm64 Linux 5.7-rc6 2020-05-18 08:44:32 +02:00
c6x mm/vma: define a default value for VM_DATA_DEFAULT_FLAGS 2020-04-10 15:36:21 -07:00
csky csky: Fixup raw_copy_from_user() 2020-05-15 00:16:30 +08:00
h8300 h8300: ignore vmlinux.lds 2020-04-23 16:41:26 +09:00
hexagon arch: split MODULE_ARCH_VERMAGIC definitions out to <asm/vermagic.h> 2020-04-23 10:50:26 +09:00
ia64 arch: split MODULE_ARCH_VERMAGIC definitions out to <asm/vermagic.h> 2020-04-23 10:50:26 +09:00
m68k m68k: Drop redundant generic-y += hardirq.h 2020-04-13 11:08:52 -07:00
microblaze mm/special: create generic fallbacks for pte_special() and pte_mkspecial() 2020-04-10 15:36:21 -07:00
mips Linux 5.7-rc3 2020-04-27 13:27:01 +02:00
nds32 arch: split MODULE_ARCH_VERMAGIC definitions out to <asm/vermagic.h> 2020-04-23 10:50:26 +09:00
nios2 nios2 update for v5.7-rc1 2020-04-11 11:38:44 -07:00
openrisc mm/special: create generic fallbacks for pte_special() and pte_mkspecial() 2020-04-10 15:36:21 -07:00
parisc mm/special: create generic fallbacks for pte_special() and pte_mkspecial() 2020-04-10 15:36:21 -07:00
powerpc powerpc fixes for 5.7 #4 2020-05-16 13:34:45 -07:00
riscv riscv: mmiowb: Fix implicit declaration of function 'smp_processor_id' 2020-05-13 17:11:46 -07:00
s390 Bugfixes, mostly for ARM and AMD, and more documentation. 2020-05-07 09:50:59 -07:00
sh Kbuild fixes for v5.7 2020-04-24 10:39:32 -07:00
sparc mm/special: create generic fallbacks for pte_special() and pte_mkspecial() 2020-04-10 15:36:21 -07:00
um Linux 5.7-rc3 2020-04-27 13:27:01 +02:00
unicore32 mm/special: create generic fallbacks for pte_special() and pte_mkspecial() 2020-04-10 15:36:21 -07:00
x86 FROMLIST: x86_64: fix jiffies ODR violation 2020-05-18 19:36:15 +00:00
xtensa arch: split MODULE_ARCH_VERMAGIC definitions out to <asm/vermagic.h> 2020-04-23 10:50:26 +09:00
.gitignore .gitignore: add SPDX License Identifier 2020-03-25 11:50:48 +01:00
Kconfig Merge 7e63420847 ("Merge tag 'acpi-5.7-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm") into android-mainline 2020-04-09 12:54:31 +02:00