History

x86/vdso: Prevent segfaults due to hoisted vclock reads

GCC 5.5.0 sometimes cleverly hoists reads of the pvclock and/or hvclock pages before the vclock mode checks. This creates a path through vclock_gettime() in which no vclock is enabled at all (due to disabled TSC on old CPUs, for example) but the pvclock or hvclock page nevertheless read. This will segfault on bare metal. This fixes commit 459e3a21535a ("gcc-9: properly declare the {pv,hv}clock_page storage") in the sense that, before that commit, GCC didn't seem to generate the offending code. There was nothing wrong with that commit per se, and -stable maintainers should backport this to all supported kernels regardless of whether the offending commit was present, since the same crash could just as easily be triggered by the phase of the moon. On GCC 9.1.1, this doesn't seem to affect the generated code at all, so I'm not too concerned about performance regressions from this fix.

Andy Lutomirski committed 7 years ago

Commit ff17bbe1 parent a4c33bb1 file · +13 −2Browse files

Unified · Split

arch/x86/entry/vdso/vclock_gettime.c+13−2
@@ -128,13 +128,24 @@ notrace static inline u64 vgetcyc(int mode) · 127 unmodified lines
128{128{
129 if (mode == VCLOCK_TSC)129 if (mode == VCLOCK_TSC)
130 return (u64)rdtsc_ordered();130 return (u64)rdtsc_ordered();
131
132 /*
133 * For any memory-mapped vclock type, we need to make sure that gcc
134 * doesn't cleverly hoist a load before the mode check. Otherwise we
135 * might end up touching the memory-mapped page even if the vclock in
136 * question isn't enabled, which will segfault. Hence the barriers.
137 */
131#ifdef CONFIG_PARAVIRT_CLOCK138#ifdef CONFIG_PARAVIRT_CLOCK
132 else if (mode == VCLOCK_PVCLOCK)139 if (mode == VCLOCK_PVCLOCK) {
140 barrier();
133 return vread_pvclock();141 return vread_pvclock();
142 }
134#endif143#endif
135#ifdef CONFIG_HYPERV_TSCPAGE144#ifdef CONFIG_HYPERV_TSCPAGE
136 else if (mode == VCLOCK_HVCLOCK)145 if (mode == VCLOCK_HVCLOCK) {
146 barrier();
137 return vread_hvclock();147 return vread_hvclock();
148 }
138#endif149#endif
139 return U64_MAX;150 return U64_MAX;
140}151}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t