Welcome to the new Woodmann RCE Messageboards Regroupment
Please be patient while the rest of the site is restored.

To all Members of the old RCE Forums:
In order to log in, it will be necessary to reset your forum login password ("I forgot my password") using the original email address you registered with. You will be sent an email with a link to reset your password for that member account.

The old vBulletin forum was converted to phpBB format, requiring the passwords to be reset. If this is a problem for some because of a forgotten email address, please feel free to re-register with a new username. We are happy to welcome old and new members back to the forums! Thanks.

All new accounts are manually activated before you can post. Any questions can be PM'ed to Kayaker.

[Solved] Linux Kernel memory page protection? (ARM architecture)

RCE of Linux tools and programs.
Locked
nothize
Junior Member
Posts: 10
Joined: Wed Oct 07, 2009 12:13 pm

[Solved] Linux Kernel memory page protection? (ARM architecture)

Post by nothize »

Kernel fault Oops 80d occurred when I loaded a kernel module to write 4 bytes to kernel code that can be found from /proc/kallsyms.

However, root user using /dev/kmem with mmap can write to the same location and value with no problem.

Is it because the mapped kernel address c0xxxxxx have write protection? So if mmap to another location will have a different access right descriptor?

How may I adjust the access right descriptor for the kernel memory within a kernel module?

What's interesting is that I can do this without any problem in another kernel(same 2.6.29) that is very similar(same machine) but for older device.


The partial panic log:
<1>[ 761.930450] Unable to handle kernel paging request at virtual address c0******
<1>[ 761.939392] pgd = d005c000
<1>[ 761.942230] [c0******] *pgd=80e0840e(bad)
<4>[ 761.947845] Internal error: Oops: 80d [#1] PREEMPT
:
:
<4>[ 762.008178] Flags: NzCv IRQs on FIQs off Mode SVC_32 ISA ARM Segment user


The PC was at a STR R1, [R3] where R3 is the virtual address c0******.

fsr = 80d

800 is write?

fault.c:__do_page_fault(...)
:
good_area:
if (fsr & (1 << 11)) /* write? */
mask = VM_WRITE;
:

d is section permission fault?

fault.c:fsr_info[] (entry 13)
:
{ do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" },
:
fault.c:do_dataAbort(...)
:
const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
:
if (!inf->fn(addr, fsr, regs))
:
It shows that the fsr can be used to lookup the fsr_info table. So value d refers to the sect fault handler...

Ahha, found the suspect in arch/arm/mm/mmu.c. Some read only kernel memory section is being created for the executable area.

So now the question become:
How to alter what mmu.c has done on the page prot setting in the kernel module way?

After some trial and error when using codes inside probe_kernel_write(...), it has been proven that using set_fs(KERNEL_DS), which will change the curr_limit to something, could prevent the section access permission check being taken.

Practically, this is to first saving the current value from get_fs()....then set_fs(KERNEL_DS), after the job is done(writing to kernel text), set_fs(old_fs) to avoid any side effect.

This solution is the simplest form I believe, no pte/pmd need to be modified.
nothize
Junior Member
Posts: 10
Joined: Wed Oct 07, 2009 12:13 pm

[Solved] Linux Kernel memory page protection? (ARM architecture)

Post by nothize »

Solved
Locked