All of the below seemed really strange to me, because I researched it when I wrote fakeroot-ng. To make sure, I wrote the following program:
#include <sys/types.h>
As I expected, the mprotect fails with "Permission denied". It is not possible to change the mapping to allow writing to the memory when it is a shared mapping of a file opened in read-only. I have no idea what the other resources are saying, but this is what I see.
Since the above completely describes what the loader does to an executable file, I don't see how mprotect can be used there either.
With that said, I know that debuggers often change the text segment of debugees in order to insert breakpoints. I have to admit that testing the mechanism by which that happens is on my todo list, but I have not got around to actually doing it. I am guessing that writing from the debugger switches the map mode to MAP_PRIVATE (i.e. - copy on write), which means there is no need to flush the changes to the file.
With that said, I have been unable to find a way to trigger that change by any other means, so a mapping made from a file opened in read only mode is, as far as I can tell, safe from manipulation barring the ptrace route.
Shachar
On 05/01/2019 17:30, Lev Olshvang
wrote:
I am researching this issue and I am confused with the finding Some articles, ex https://shanetully.com/2013/12/writing-a-self-mutating-x86_64-c-program/ state that mprotect() can change protection of executable section. As I understanf pte entry has page protection bits set to RO so mprotect should change pte which is loaded to MMU/TLB. Why kernel can not refuse do perform this mprotect call(). Whu we do norhave kernel config options to forbid user-space mutable code as security feature? >From the other side, when run-time linker or elf_loader loads the executable it uses MAP_DENYWRITE which protect executable file from being overwritten. But writing to executable text will make page dirty and require the write-back which is disabled by MAP_DENYWRITE. (or it might be disable for other processes except current, I am not sure?) To add to the confusion, the following quote from the LWN articlle https://lwn.net/Articles/422487/ about CONFIG_DEBUG_SET_MODULE_RONX "Marking the kernel module pages as RO and/or NX is important not only because it is consistent with how the rest of the kernel pages are handled" Digging dipper I see that ARM since kernel version 4.11 has CONFIG_STRICT_KERNEL_RWX , and as I understand it is enforced in hardware. But I am not sure that some variant of pte_clear(), pte_mkexec(0 can not disable it. So let me cut to final qiestion: Suppose I want to cut off dynamic code instrumentation, like ftrace and friends. Is it achievable at least at ARM architecture to enforce RO+X at hardware or kernel? Thanks to all folks for reading till this point. Regards Lev _______________________________________________ Linux-il mailing list Linux-il@xxxxxxxxxxxxx http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il |
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies