Gold Linker Patch: Introduce the "retpoline" x86 mitigation technique for variant #2 of the speculative execution vulnerabilities disclosed today, specifically identified by CVE-2017-5715 and in some places called "spectre".
Ian Lance Taylor via binutils
Fri Jan 5 15:00:00 GMT 2018
On Fri, Jan 5, 2018 at 3:42 AM, Florian Weimer <firstname.lastname@example.org> wrote:
> On 01/05/2018 12:08 AM, Cary Coutant wrote:
>>> * options.h (retpolineplt): New -z option to use retpoline PLT.
>>> * x86_64.cc (Output_data_plt_x86_64_retpoline): New class.
>>> (Target_x86_64<64>::do_make_data_plt): Create retpoline PLT when
>>> the option is used.
>>> * testsuite/Makefile.am (retpoline_plt_1.sh): New test.
>>> * testsuite/Makefile.in: Regenerate.
>>> * testsuite/retpoline_plt_1.sh: New test script.
>>> * testsuite/retpoline_plt_1.s: New test source.
>> This makes the -z bndplt and -z retpolineplt options mutually
>> exclusive. Please add a check in options.cc
>> (General_options::finalize) for this.
> It's also incompatible with shadow stack support, so the binary marker for
> that needs to be removed.
> I don't think this is the right approach at all. What is this trying to
> accomplish? What kind of speculation barrier does this implement on current
> CPUs? Isn't this *extremely* costly?
As I understand it (and I may not) this option would be appropriate to
use with dynamically linked programs that hold high value private
information, run on the same machine as untrusted code, and have some
communication path with untrusted code. If the untrusted code can
cause the trusted program to make indirect branches, it can extract
information from the trusted program's address space. No specific
control is needed over where the untrusted branch goes; the attack
works by having the untrusted program seed the branch target buffer,
thus causing the processor to speculatively execute instructions that
would never normally be executed. The results of that speculative
execution, though discarded, will affect the memory cache, and this
can be used to read the address space of the trusted program. The
attack only works if there is some way to cause the trusted program to
execute an indirect branch; for many programs the PLT provides such a
mechanism, as many communication paths with the trusted program will
cause the trusted program to make some sort of libc call.
It seems to me that it would be appropriate to use this option with
programs like web browsers and ssh-agent, which are long-lived, hold
high value private information, and by the nature of their operation
must communicate with untrusted code.
The change is clearly extremely costly for programs that spend all of
their time making calls through the PLT. I doubt that describes the
kinds of programs that need to worry about this vulnerability.
> If we think this is a problem that needs to be fixed, we should remove the
> indirect call altogether, and have the dynamic linker generate a direct call
> at load time. There are few constraints associated with that (4 GiB total
> application + DSO size, some SELinux users will unhappy, lack of lazy
> binding support), but at least it can be turned on in practice.
I agree that that is a good idea. If we can make that change in the
dynamic linker then after a few years, when we can assume that the
updated dynamic linker is deployed everywhere, then we can discard
this linker option. Of course, I expect that processors will be
modified to prevent this attack over time as well.
More information about the Binutils