ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.57k stars 2.53k forks source link

support PIE (Position Independent Executables) #4503

Closed andrewrk closed 3 years ago

andrewrk commented 4 years ago

@LemonBoy did initial work for this in #3960 but it didn't get merged yet because it's blocking on #1917. Implementation of this issue will probably start by referring to that diff.

This proposal is to enable ASLR, by default only in ReleaseSafe mode, but can be overridden to be enabled or disabled in any build mode.

As far as I can tell, from Zig's perspective ASLR and PIE are the same thing. Any explanations of the distinction here are welcome.

daurnimator commented 4 years ago

Position Independent Executables are traditionally used to create files that are both libraries and executables. Have a close look at e.g. /lib/ld-linux.so.2 or /usr/lib/libc.so.6

andrewrk commented 4 years ago

Thanks that's a really helpful use case.

OK so this issue is mainly for supporting PIEs.

If it solves ASLR (Address Space Layout Randomization) in ReleaseSafe mode at the same time, that's a bonus, otherwise that can be extracted into a separate issue.

JesseRMeyer commented 4 years ago

ASLR's effectiveness has come under scrutiny after recent attention from CPU cache information side-channel leaks.

This paper, https://download.vusec.net/papers/anc_ndss17.pdf, (lead author is a security researcher at Intel) argues that ASLR is 'fundamentally insecure on modern cache based architectures'. AMD is vulnerable too. Unsure about non-x86 family of processors. So, I don't think ALSR is valuable as a default option across the board.

adontz commented 4 years ago

This paper, https://download.vusec.net/papers/anc_ndss17.pdf, (lead author is a security researcher at Intel) argues that ASLR is 'fundamentally insecure on modern cache based architectures'. AMD is vulnerable too. Unsure about non-x86 family of processors. So, I don't think ALSR is valuable as a default option across the board.

As far as I understand, ALSR support is not that hard, you need it anyway for SO/DLL, so why not?

JesseRMeyer commented 4 years ago

Why do you need ALSR for SO/DLLs? PIE's are valuable for shared libraries (so multiple instances can live in the same address space, if I understand it correctly, otherwise they'd stomp over each other), and ALSR builds on top of that. So if you need it, it's not because PIE requires it, it's an operating system requirement that extends it -- no?

My point is why support a security protocol that is fundamentally insecure? But hey, if Zig needs to support ALSR as a compromise to play ball with popular operating systems, then sadly its hand is forced.

adontz commented 4 years ago

Why do you need ALSR for SO/DLLs?

Because this is the way OS vendors want us to be more secure.

Is it security LARP? Maybe. I don't know. I don't consider myself security expert. But the same reason should lead you to browse web without JavaScript and never use cloud computing.

Why not just do what is considered industry standard if it does not bring any harm?

JesseRMeyer commented 4 years ago

Because this is the way OS vendors want us to be more secure.

If you don't accept the paper's conclusions, then OK, show how they're wrong. But I don't know how to respond if you think ALSR is actually a valid security measure. I've already said that if we are forced to provide ALSR to satisfy an OS's constraints, sure, but let's not pretend we are doing it in the same of security when we are not.

Why not just do what is considered industry standard if it does not bring any harm?

How does it not bring harm?

The industry standard is demonstratively wrong. It's hugely harmful. If you deployed ASLR because you thought you were being safe when you are actually exposing yourself, you've shown up to a gun fight with chain mail.

adontz commented 4 years ago

If you don't accept the paper's conclusions, then OK, show how they're wrong.

I did not say paper is wrong. But relevant attack vectors may vary. Again, speculative execution related side-channel attacks ruined everything. Now what? Don't use any security measures, because all of them suddenly became useless?

How does it not bring harm? The industry standard is demonstratively wrong. It's hugely harmful. If you deployed ASLR because you thought you were being safe when you are actually exposing yourself, you've shown up to a gun fight with chain mail.

By harm I mean measurable application slowdown or technical limitations, not developers depression :-)

Under windows all executables must have COM or EXE file name extension, under Linux they must have execute access permissions bit set. Does it make it more secure? No. Does it make any harm? No. I am not discussing if it is valid/effective security measure, I am saying that it is default for modern compilers, default for modern OSes, so Zig should have it.

JesseRMeyer commented 4 years ago

Now what? Don't use any security measures, because all of them suddenly became useless?

We're specifically discussing ASLR. Let's not throw the baby out with the bath water. ;) But security on modern chips is sort of suspect to begin with.

By harm I mean measurable application slowdown or technical limitations, not developers depression :-)

I know that the Linux kernel had a difficult time implementing ASLR / PIE in a way that didn't noticeably slow the system down. They may have made improvements there by now. Apparently Window's didn't suffer as steep a performance problem, but that could've simply just been that it was slow to begin with. Here's the thing -- why keep complexity when it's only cost and no value?

Under windows all executables must have COM or EXE file name extension, under Linux they must have execute access permissions bit set. Does it make it more secure? No.

It depends on the threat model. You can't answer the question in a vacuum like that. ALSR is supposed to be protection against very capable adversaries, and not protecting users from themselves.

adontz commented 4 years ago

ALSR is supposed to be protection against very capable adversaries, and not protecting users from themselves.

ALSR protects from buffer overrides. It still does. Does it protect from buffer override+side channel or any other magic? Probably no.

JesseRMeyer commented 4 years ago

ALSR protects from buffer overrides.

I thought this was a property of PIE. Could you elaborate?

adontz commented 4 years ago

ALSR protects from buffer overrides. I thought this was a property of PIE. Could you elaborate?

As far as I understand (and what I know is related to Windows only) if buffer is overrun and stack is filled with some machine code, an attacker cannot return, because stack protection will fire. So the attacker has to jump. There is no way for the attacker to call any dynamically loaded library function, because function address is random, because module base address is random. There are only ordinary function calls in dynamically loaded system or CRT libraries, no direct syscalls like in Linux. Base address on application is kind of irrelevant. On Linux with static linking you'll need PIE, because it's just one monolith executable with one base address.

JesseRMeyer commented 4 years ago

Thanks.

From the paper:

an attacker can de-randomize virtual addresses of a victim’s code and data by locating the cache lines that store the page-table entries used for address translation.

An attacker can determine where to jump.

adontz commented 4 years ago

ALSR protects from buffer overruns. ALSR does not protect from buffer overrun+other magic.

JesseRMeyer commented 4 years ago

I see -- thanks. For accidental overruns, I see benefit in crashing the program ASAP which ASLR is likely to achieve. The follow-up question, which may have a OS dependent answer, is whether compiler-inserted stack probes are a better choice of protection against that class of bugs. For example, I also don't know if Zig is immune to stack return address stomping. Return addresses on the stack are dangerous, and when data is laid out in a direction towards the return address, you're just asking for trouble.

adontz commented 4 years ago

For example, I also don't know if Zig is immune to stack return address stomping.

https://github.com/ziglang/zig/issues/4542

llebout commented 4 years ago

A use case I some times can have is rapidly compile something to a PIE shellcode, it means basically supporting language features without any help from the host os executable file format.

In C, I usually archieve this by following some conventions such as avoiding to use strings but instead declare them as unsigned char arrays as locals on the stack, but it's a bit hacky.

On Windows for example, ASLR depends on executable loader pre-processing and applying relocation fixups.

If your binary doesnt have any absolute address references in the machine code, then there's no need for these fixups and ASLR works out of the box. It has the benefit of also supporting PIE shellcodes that can be copied to a buffer and jumped to and everything works as expected.