Re: How to forbid user space and kernel executable pages from becoming writable?

2019-01-05 Thread Shachar Shemesh

  
  

On 05/01/2019 22:22, Shachar Shemesh
  wrote:


  
  
  Since the above completely describes what the loader does to an
executable file, I don't see how mprotect can be used there
either.
  

So, I decided to check my assumptions. Sure enough, it seems that
  the loader is using a private mapping when mapping the executables
  into memory. If that's the case, then you should, indeed, be able
  to use mprotect to change the permissions, and change the
  executable code.


Please note, however, that this will not change the data on file
  or for any other process mapping the same section. It will only
  change your process' view of the file. As such, this is not a
  security problem.


If, for whatever reason, you don't want that to happen, you can
  modify the loader (source is in glibc) to use MAP_SHARED when
  mapping the file. This will attack this "attack" vector. This
  will, most probably, also prevent gdb from setting breakpoints in
  your system.


Also, please note that if the aim is to only allow a process to
  execute its predetermined code then this is a futile move. The
  process can still mmap a new memory segment and write whatever it
  wants there.


Shachar

  


___
Linux-il mailing list
Linux-il@cs.huji.ac.il
http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il


Re: How to forbid user space and kernel executable pages from becoming writable?

2019-01-05 Thread Shachar Shemesh

  
  
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 
  #include 
  #include 
  #include 
  #include 
  #include 
  
  int main() {
      int fd = open("testfile", O_CREAT|O_TRUNC|O_WRONLY, 0666);
      ftruncate(fd, 4096);
      close(fd);
  
      fd = open("testfile", O_RDONLY);
      char *map = (char *)mmap( nullptr, 4096, PROT_READ,
  MAP_SHARED|MAP_FILE, fd, 0 );
      if( map==MAP_FAILED ) {
      perror("mmap failed");
      return 1;
      }
  
      if( mprotect(map, 4096, PROT_READ|PROT_WRITE)<0 ) {
      perror("mprotect failed");
      return 1;
      }
  }


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@cs.huji.ac.il
http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il


  


___
Linux-il mailing list
Linux-il@cs.huji.ac.il
http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il


How to forbid user space and kernel executable pages from becoming writable?

2019-01-05 Thread Lev Olshvang
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@cs.huji.ac.il
http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il