Hacker News new | ask | show | jobs
by meditationapp 3304 days ago
How does using the "unused" bits of a 64-bit pointer differ, functionally, from address space randomization with 64 bits? The search space is the same. Misses are still trivially detectable.

By my reading, this allows not a whitelist of pages, but a whitelist of arbitrary addresses. Different granularities entirely. Can anyone else bring a light to bear on this?

2 comments

It looks like this will prevent attacks that use information leakage to figure out valid addresses. With ASLR, you can defeat it if you can get the target to send a return address or other code pointer back to you, because you'll then be able to see where the code is loaded. With this, a pointer to code is likely useless: the authentication code depends on the target address, so you wouldn't be able to forge a valid pointer to a different address, and it depends on the current stack pointer, so you wouldn't even be able to reuse the value to point to the same address unless you found an exploit with the exact same stack depth.
> the authentication code depends on the target address

The authentication code is a combination of key and context: there are 5 total keys in the system, and then an unlimited number of contexts. Contexts are I think most useable on the "return" edges, because you can add the current stack pointer value to the context when you push the boxed return address onto the stack, then re-derive that context when you're at the return site.

That exact scheme doesn't work that well on the forward edge, because the stack pointers will be different when calling function pointer F in function A vs function B. What you can probably do is encode something about the type of F into the context. However, as they outline in the white paper, this isn't enough on its own because the type signature of gets and system are really similar and if your type-to-context encoding scheme maps them to the same context, an attacker could take a call to gets-via-function-pointer and replace that value with the value of system as it appears elsewhere in your program.

The difference is the threat model. ASLR does kind of poorly when the attacker can read and write arbitrary memory, because the attacker can just learn what the addresses of all the objects are by dumping memory, then adjust their attack on-line. If you think that's far-fetched, it isn't, exploits for operating system kernels and web browsers do this.

Authenticated pointers can assume this threat model. The attacker can read and write arbitrary memory, but it doesn't do anything for their ability to hijack the control flow of the application because all values stored in memory that relate to control flow are signed and encrypted. The attacker can't create a new code-pointer value and write it in to memory without knowledge of the secret keys, which are not in memory. The attacker could cause the program to crash or exit early, but oh well.