Hello
I am attempting to run some user code with kernel space permission. I am using the ppc64 kernel version 2.6.16-rc4-3-ppc64 for IBM Power5 processors.
In this kernel module I am trying to implement a function that can be called from user space.
I have found through various posts that using unused system calls and replacing them temporarily can acheive this objective.
This is what I am doing, but its not working, please bear with the slightly long code that follows:
1) since the 2.6 kernel does not export sys_call_table, I grep it from the boot image
2) Next I write the kernel module as :
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
unsigned long **sctable;
void *org_func; /***** Copy of the original calls address ********/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
unsigned long **sctable;
void *org_func; /***** Copy of the original calls address ********/
asmlinkage int mitesh_func(void)
{
printk(KERN_ALERT "Executing mitesh_func...\n");
return 2;
}
{
printk(KERN_ALERT "Executing mitesh_func...\n");
return 2;
}
int init_module(void)
{
unsigned long ptr;
unsigned long *p;
ptr = 0x23203404; /*** some hard coded addresses from grepping for sys_call_table *****/
{
unsigned long ptr;
unsigned long *p;
ptr = 0x23203404; /*** some hard coded addresses from grepping for sys_call_table *****/
p = (unsigned long *)ptr;
sctable = (unsigned long **)p;
printk("The address of the system call table is: 0x%x\n",&sctable[0]);
printk("The address of syscall #137 is: 0x%x\n",sctable[137]);
ptr = 0xc0000000005dbd30;
p = (unsigned long *)ptr;
sctable = (unsigned long **)p;
printk("The address of the system call table is: 0x%x\n",&sctable[0]);
printk("The address of syscall #137 is: 0x%x\n",sctable[137]);
sctable = (unsigned long **)p;
printk("The address of the system call table is: 0x%x\n",&sctable[0]);
printk("The address of syscall #137 is: 0x%x\n",sctable[137]);
ptr = 0xc0000000005dbd30;
p = (unsigned long *)ptr;
sctable = (unsigned long **)p;
printk("The address of the system call table is: 0x%x\n",&sctable[0]);
printk("The address of syscall #137 is: 0x%x\n",sctable[137]);
org_func = (void *) (sctable[137]); /**** Store the original sys call ****/
printk("Original func address 0x%x stored \n",org_func);
printk("Original func address 0x%x stored \n",org_func);
sctable[137] = (void *) mitesh_func; /**** replace with mitesh_func ****/
printk("The new sys call address is 0x%x and stored as : 0x%x\n",mitesh_func, sctable[137]);
return 0;
}
return 0;
}
void cleanup_module(void)
{
sctable[137] = (void *) org_func;
{
sctable[137] = (void *) org_func;
printk("Upon module unload the sctable #137 address is :0x%x\n",sctable[137]);
printk("Module is unloaded!\n");
}
printk("Module is unloaded!\n");
}
3) My user app looks like this:
#include <stdio.h>
#include <errno.h>
#include <asm-ppc64/unistd.h>
#define __NR_mitesh_func 137
_syscall0(int, mitesh_func);
#include <errno.h>
#include <asm-ppc64/unistd.h>
#define __NR_mitesh_func 137
_syscall0(int, mitesh_func);
void main()
{
int x=0;
x=mitesh_func();
{
int x=0;
x=mitesh_func();
printf("mitesh_func returned %d\n",x);
}
4) I verify from the system logs that when I insmod the kernel module I get all the print statements. I verified from the logs that the address of the sys_call_table is correctly passed and from /proc/kallsysms I can see that my function mitesh_func has been defined and has the address as indicated in the logs.
The problem is that when I execute my user app I expect to see two things:
a) I should see a message in the log "Executing mitesh_func..." and
b) A return value of 2
However I get an error value -1 returned.
Any help and ideas are highly appreciated.
Please also let me know if there is an alternate approach for executing user code in kernel space with a way of invoking it.
Thank you in advance,
Mitesh