4

I've read this Does Linux kernel use DEP for kernel memory?

but I'm debugging linux kernel (x86_64) on Vmware using vmware stub. I've attached gdb to my linux kernel. the kernel version is 3.x

and I changed executable memory of linux kernel in one place

(gdb) x/i $rip
=> 0xffffffff81190930 <sys_getdents>:   push   rbp
(gdb) set{long}0xffffffff81190930=0
(gdb) x/x 0xffffffff81190930
0xffffffff81190930 <sys_getdents>:      0x00000000
(gdb) x/i $rip
=> 0xffffffff81190930 <sys_getdents>:   add    BYTE PTR [rax],al

why is that? is this because I'n in virtual machine?

second question. I know that I can list pages using this command

(gdb) info files
Symbols from "/home/a/vmlinux".
Remote serial target in gdb-specific protocol:
Debugging a target over a serial line.
        While running this, GDB does not access memory from...
Local exec file:
        `/home/a/vmlinux', file type elf64-x86-64.
warning: Cannot find section for the entry point of /home/a/vmlinux.
        Entry point: 0x1000000
        0xffffffff81000000 - 0xffffffff815f795f is .text
        0xffffffff815f7960 - 0xffffffff815f7adc is .notes
        0xffffffff815f7ae0 - 0xffffffff815fbb00 is __ex_table
        0xffffffff81600000 - 0xffffffff818427ce is .rodata
        0xffffffff818427d0 - 0xffffffff81849ed4 is __bug_table

but how to list permissions to these pages - rwx ?

tigger
  • 41
  • 1
  • I was asking why I can write to kernel memory which is marked as executable. The answer is that gdb can bypass that there is no permission for saving – tigger Oct 25 '16 at 11:28

1 Answers1

3

I have never debugged the kernel, so I may be wrong, but I believe that what you are seeing makes complete sense. Let's go through it:

add BYTE PTR [rax],al

why is that? is this because I'n in virtual machine?

That is what I would actually expect from 0x0000. This is easy to test:

[~]$ uname -a
Linux haps 4.7.6-1-ARCH #1 SMP PREEMPT Fri Sep 30 19:28:42 CEST 2016 x86_64 GNU/Linux
[~]$ perl -e 'print "\x00\x00\x00\x00"' > pp
[~]$ ndisasm pp
00000000  0000              add [bx+si],al
00000002  0000              add [bx+si],al

So yeah, 0x0000 is add into the first byte of RAX (i.e. al).


but how to list permissions to these pages - rwx ?

I will argue that that does not make sense. A common misunderstanding is thinking that the kernel runs as root, that completely untrue. The kernel runs in kernelmode, and everything else runs in usermode (unless it is in the middle of a syscall, that is).

In the global page directory the pages used by the kernel have the DLP (Descriptor Privilege Level) set to 0, meaning kernelmode. All userspace used pages have the DLP set to 3, meaning usermode. When the CPU is executing a userspce process it is in usermode, therefore if it tries to access a page that has a DLP of 0 (or 1 or 2, but those are not used in Linux) then the CPU will shoot an exception (an interrupt) and tell the kernel to clean the mess. The kernel, in turn, will simply queue a SEGFAULT in the signal queue of the process that is currently active.

In summary, any userspace process that tries to access those pages will get segfaulted. It does not matter if the process is run with root privileges or not. Therefore it does not really make sense to give a set of permissions to the memory pages that are used by the kernel.

Extra note

You may ask: but what about /dev/mem? That's kernel memory that can be seen from userspace. Well, reading and writing to /dev/mem (or /dev/kmem) provokes a syscall. And something like copy_to_user or copy_from_user is called to pass data between DLP 3 and DLP 0 pages.

grochmal
  • 5,677
  • 2
  • 19
  • 30
  • 1
    @tigger - I am clueless about what you mean by GDB without permissions to write into the VM memory. It definitely can do it. As for different permissions in kernelspace pages that's another thing i'm clueless about. Linux only uses DLP 3 (which literally means userspace) and DLP 0 (which literally means kernelspace), other DLP settings are simply not used. The kernel maintains permissions for all pages in userspace, and it assigns permissions when a page is copied to userspace (but see dirtyc0w for an example where it does this the wrong way, hehehe). – grochmal Oct 24 '16 at 19:14
  • `ndisasm -b 64`: Your disassebly looked incorrect. – Mukesh Sai Kumar Jan 11 '18 at 11:47