Live data from Hacker News

Mandatory enforcement of indirect branch targets

undeadly.org

101–110 of 134 posts

Re: Mandatory enforcement of indirect branch targets

#101
post #97

Earlier quoted context omitted.

It was an old joke that the opposite of "goto" is "come from", or that if goto is considered harmful, nobody said anything about a "come from". Marking something as a branch target reminds me of this. https://en.m.wikipedia.org/wiki/COMEFROM

> GOTO considered harmful COMEFROM considered harm-mitigating It ingeniously makes Return Oriented Programming (ROP) a lot harder.

> COMEFROM considered harm-mitigating

You know, that’d be a fantastic OpenBSD release name.

Here’s hoping a dev sees this comment; there’s already been a few commenting in this thread.

Re: Mandatory enforcement of indirect branch targets

#102
post #43

Earlier quoted context omitted.

> but unless the compiler can prove that they always are (e.g., if they're static and nothing in the same file takes the address), endbr64 is required Then why not just have the compiler break down every non-static function into two blocks: a static function that contains all the logic, and a non-static function that just contains an IBT and a direct jump to the static function? (Or, better yet, place the non-static…

The IBT NOP is "free" in that it will evaporate in the pipeline; it still has to be fetched and decoded to some extent, but it does not consume execution resources. From a tooling perspective, what you're describing (two entrypoints for a function, the jump you mention is pointless) would require changes up and down the toolchain; it would affect the compiler, all linkers, all debuggers, etc. By contrast, just adding…

Doesn't seem like it'd be that difficult to make the change the other direction, i.e. keep endbr64 as-is as the default case, but if there's a direct jump/call to anywhere that starts with endbr64, offset the immediate by 4 bytes; could be done in any single stage of toolchain that has that info with no extra help. But yeah, quite low impact, might not even affect decode throughput & cache usage for at least one of the direct or indirect cases.

Re: Mandatory enforcement of indirect branch targets

#103
post #91

Is this protection really all that helpful? Surely there are functions you can call into the top of to do your diabolical deeds for you. It would be more helpful if callers would store some machine specific hash of the function prototype and the function itself would check the hash, so that you could only redirect to calling a function with the right signature. But that would also increase the overhead further. Alrea…

The entire field of ROP exploits would basically never have been developed if it were as simple as just calling the function you want.

Re: Mandatory enforcement of indirect branch targets

#104

Theo had to get his digs in against Linux in that announcement. Why not just focus on what OpenBSD is doing, and maybe contrast it to what Linux does without the speculation that they will still be doing the same thing in 20 years. He's unquestionably brilliant, but I've had a few encounters with him on the mailing lists and he is so quick to take offense where none was meant and drop into name-calling and insults. I…

I’d just like to interject for a moment. What you’re referring to as Linux, is in fact, NotOpenBSD/Linux, or as I’ve recently taken to calling it, Linux as opposed to OpenBSD…

Re: Mandatory enforcement of indirect branch targets

#105

Earlier quoted context omitted.

Is this theoretically something lto could remove?

If you disable dlopen and ld_preload.

Dlopen() "sees" only functions marked as exported (with macro like DLLEXPORT on Windows), not every function or am I wrong? Is C that bad?

Re: Mandatory enforcement of indirect branch targets

#106

Earlier quoted context omitted.

If you disable dlopen and ld_preload.

Dlopen() "sees" only functions marked as exported (with macro like DLLEXPORT on Windows), not every function or am I wrong? Is C that bad?

On openbsd at least, every global symbol is exported unless you use an explicit symbol list. It's unusual for executables.

Re: Mandatory enforcement of indirect branch targets

#107

Earlier quoted context omitted.

> Assembly doesn't have undefined behavior, but obviously you can have all sorts of issues there. The machine is in the real world and is thus obliged to have some actual behaviour, but it is not always practical to discern what that behaviour would be let alone make it reliable across a product line and document it in an understandable way. As a result actually your CPU's documentation does in effect include "Undefi…

True, when writing my comment I wanted to qualify it to the same effect, but thought it would be an unnecessary subtlety to the general thrust of my point. That is, we can ignore this kind of "undefined behavior in the machine itself" for the purposes of this particular discussion.

I don't see how to ignore it though. If we're defining the behaviour but then our "definition" just doesn't specify the actual behaviour because it's specified in terms of hardware with no clearly defined behaviour for that situation then it's just word play, we're not really doing what I set out.

Re: Mandatory enforcement of indirect branch targets

#108
post #102

Earlier quoted context omitted.

The IBT NOP is "free" in that it will evaporate in the pipeline; it still has to be fetched and decoded to some extent, but it does not consume execution resources. From a tooling perspective, what you're describing (two entrypoints for a function, the jump you mention is pointless) would require changes up and down the toolchain; it would affect the compiler, all linkers, all debuggers, etc. By contrast, just adding…

Doesn't seem like it'd be that difficult to make the change the other direction, i.e. keep endbr64 as-is as the default case, but if there's a direct jump/call to anywhere that starts with endbr64, offset the immediate by 4 bytes; could be done in any single stage of toolchain that has that info with no extra help. But yeah, quite low impact, might not even affect decode throughput & cache usage for at least one of t…

> Doesn't seem like it'd be that difficult

Show me the code -- better yet, submit it to the relevant projects! :)

Re: Mandatory enforcement of indirect branch targets

#109
post #7

Earlier quoted context omitted.

Interesting. I was able to get Clang to generate this using `-fcf-protection=branch`: https://godbolt.org/z/rooP8vPsM It looks like endbr64 is a 4-byte instruction. That could be a significant code size overhead for jump tables with lots of targets: https://godbolt.org/z/xTPToaddh

OpenBSD disables jump tables in Clang on amd64 due to IBT, some architectures also had jump tables disabled as part of the switch to --execute-only ("xonly") binaries by default, e.g: powerpc64/sparc64/hppa. https://marc.info/?l=openbsd-cvs&m=168254711511764&w=2 E.g: https://marc.info/?l=openbsd-cvs&m=167337396024167&w=2

Any idea what the performance impact is?

Re: Mandatory enforcement of indirect branch targets

#110

Earlier quoted context omitted.

> they provide little to prevent unknown bugs bing exploited They provide plenty of mitigations ( https://www.openbsd.org/innovations.html ). In fact OP's article is for preventing unknown bugs from being exploited.

They don't provide any mitigations of the sort I was clearly referencing. Specifically, for restricting malicious code or users that already has access to the system, exploiting insecure software that was not compiled with pledge support.

What kind of mitigations would help here?
Post reply on HN