bzt wrote:
A dynamic linker is not of a big complexity. Not simple, but not particularly complex either (typically no more than few hundred SLoC).
We're just going to have to agree to disagree on that one. A dynamic linker is a complex piece of software parsing attacker-controlled data, and it is getting nowhere near my kernel.
bzt wrote:
Did you read my post at all? Or did you just read the upper-case letters at the end and forget about the rest?
Let's not get into that discussion or we'll be here all week.
bzt wrote:
Are you serious? What do you think, why did ARM implement WNX permission in hardware if its just a "nonsense"?
Nice evade. You didn't actually answer my question. Nice of ARM to prevent data execution in a centralized way, but x86 has had data execution prevention for a while now as well. And that page doesn't say why you shouldn't allow userspace to map executable pages.
By the way, the "nonsense" was to say "It's more secure". There is no dipstick for security, no pressure gauge, no measuring tape. What attacks will your regime prevent? And if it is just good old stack smash classic, then data execution prevention already prevents this, and attackers are working around it with ROP.
bzt wrote:
Excuse me? Are you saying that text relocations are unsupported by dynamic linkers? And that they shouldn't be ever used?
YES! Textrels are an awful hack only present in non-PIC code that has been linked dynamically. PIC code actually manages to put all the relocations into the data section, and the actual code section remains unaltered. This also means that the dynamic linker only has to support a limited number of relocation types, compared to the link editor. Textrels mean you are writing into the text section, which means it cannot be shared between processes anymore. So the one thing shared libraries are trying to do will be undermined by them.
bzt wrote:
Yes, it does help, because the malicious code cannot modify the existing code (rendering all buffer-overflow attacks impossible once and for all), and it cannot return to non-executable data. There's simply only valid, unmodified code to return to.
No, no, and no. Malicious code already cannot modify existing code. For instance, here I am looking at all Firefox instances on my system, looking for pages that are writable and executable at the same time, and failing to find any:
Code:
$ for i in $(pidof firefox), do grep wx /proc/$i/maps; done
$
This is on a glibc system, which, I'll remind you, supports lazy relocations. Still no writable and executable page.
This entirely fails to prevent buffer-overflow attacks since those are caused by code writing over the limits of their buffers. Code that is already present in the executable, mind you. Strong limit checks on array access would prevent those, but then programmers would start yammering about performance. In any case, not something a kernel can remedy., And just because there is only already-approved code to return to, does not mean a function has to be run from start to end. This is what ROP does, write a bunch of addresses to the stack that are all code, but only the tails of functions, to achieve some desired effect (e.g. set %rdi to some predetermined value, then jump to system()).
bzt wrote:
No, they can't overwrite, that's the point! Having the dynamic linker in the kernel means GOT is only writeable by the kernel, and for user space it's read-only. Any attempt to change the GOT from ring 3 would trigger an exception.
The GOT is in the same segment as the data section. You cannot write-protect one without write-protecting the other. And write-protecting the data section would be kind of counter productive.
bzt wrote:
Think about the things I wrote above. If you still can't see why a user space dynamic linker is bad for security, then I'm sorry, I'm afraid I cannot help you more.
Your arrogance astounds me. You fail to even consider that you might be wrong. This was my last reply on the matter.