Welcome! Log In Create A New Profile

how to copy process-heap to kernel-buffer

Posted by rushikesh 
how to copy process-heap to kernel-buffer
October 13, 2009 01:15PM
Hi friends,
My kernel-module wants to copy another process's heap to its(module's) buffer(kmalloced).
this is performed by " root " user.
Objective:-

I have a very simple process prog1.o which allocates 5 integers using malloc and then waits for user to enter his age from keyboard.
Now,while the prog1.o is waiting for the user's input from keyboard, during that time, my kernel module kern_module.c tries to copy the heap of prog1.o
to kernel-memory.

For copying prog1.o 's heap to my module's buffer i use copy_from_user.
But, somehow the copy_from_user does not copy a single byte from the specified process-heap.
Code is given below :
********************************************************
prog1.c (i.e. prog1.o) ---- run by " root "

int main()
{
int i,age;
int* arr = (int*) malloc(5*sizeof(int)); //allocate 5 integers in heap
for(i=0;i<5;i++) //give some value to dynamic array
arr[i]=i;

printf("Enter age:"winking smiley; //read user-age
scanf("%d",&age); //at this stage of execution, the module kern_module stops this program and tries to copy this program's heap to krnel-space
return 0; // this will never execute.
}

********************************************************
The kernel-module's code is here:-->
kern_module.c (i.e. kern_module.ko) ---- run by " root "
-------------
int copy_heap_to_kernel_space(int pid) //here pid is the process id of prog1.o
{
task_struct* p = find_task_by_pid(pid); //obtain task_struct
if(!p)
{
printk("error.\n"winking smiley; return -1;
}
send_sig(SIGSTOP,p,0); //stop the above prog1.o process

unsigned long heap_len = p->mm->brk - p->mm->start_brk; //length of heap
if( !access_ok(VERIFY_READ,p->mm->start_brk,heap_len) )
{
printk(" NOT access_ok."winking smiley; return -1;
}
void* kernel_buffer = kmalloc(heap_len,GFP_KERNEL);
unsigned long bytes_failed =0;
if(!kernel_buffer)
{
printk("buffer allocatoin failure.\n"winking smiley; return -1;
}
// Till this position, the module works properly, but the following line not works as per expectation.
bytes_failed = copy_from_user(kernel_buffer,p->mm->start_brk,heap_len);// it fails & does not copy a single byte from heap to kernel_buffer
if(bytes_failed!=0)
{
printk("Failed to copy %u bytes.\n",bytes_failed);//always this happens
return -1;
}
else
printk("heap successfully copied to kernel space.\n"winking smiley;


return 0;
}


output :- Failed to copy 135168 bytes.


******************************************************************************
Plz. suggest me a solution , why this happens.
Re: how to copy process-heap to kernel-buffer
October 13, 2009 11:44PM
1. do
send_sig(SIGSTOP,p,0); //stop the above prog1.o process
after your copy action.

2. you'd better try mapping instead of copying if have no special intention.

-Pat
The Effo Staff
Effo Project, [effo.sourceforge.net]
Re: how to copy process-heap to kernel-buffer
October 14, 2009 10:16PM
Dear Effo staff,

As you said:
1. do
send_sig(SIGSTOP,p,0); //stop the above prog1.o process
after your copy action.

I tried, the same as above; but still it does not copy the heap to kernel-space.


And
2. "you'd better try mapping instead of copying if have no special intention. "

Sir, can you please tell me more on this.

Thank you.
Re: how to copy process-heap to kernel-buffer
October 15, 2009 10:01PM
My code works for a 2.6.28.3 kernel, though no signal, fyi:

    static char buf[128];
    struct task_struct *task;
    struct mm_struct *mm;
    long ret;
    task = find_task_by_vpid(4040);
    mm = get_task_mm(task);
    memset(buf, 0, sizeof buf);
    ret = copy_from_user(buf, (void*)mm->mmap->vm_start, sizeof buf);
    printk("ret %ld, 0x%p 0x%p 0x%p 0x%p\n",
            ret,
            (void*)*((unsigned long*)buf + 0),
            (void*)*((unsigned long*)buf + 1),
            (void*)*((unsigned long*)buf + 2),
            (void*)*((unsigned long*)buf + 3)
            );
     return buf;

The output in dmesg:
ret 0, 0x00010102464c457f 0x0000000000000000 0x00000001003e0002 0x0000000000401160

I noted that first bytes of the heap look like "ELF\0" etc, say the heap placement is not that you had expected that you can just read the "int* arr" memory, libc will put some controlling information such as overhead.

"do signal after your copy action" means the process MAY be stopped by the signal so you cannot read its memory space anymore.
For mapping, meant mapping user space memory into the kernel (your kernel module) so you don't need the low performance copying.

If still has problems at your side, send the code to my mail box: staff dot effo at gmail dot com.

-Pat
The Effo Staff
Effo Project, [effo.sourceforge.net]
Re: how to copy process-heap to kernel-buffer
October 28, 2009 06:33AM
Dear Pat, Effo staff,

Thank you for the suggestion.

As you suggested the user-space mapping to kernel-space, I tried the following, but it returns (-22) i.e. error.

unsigned long result = do_mmap( NULL, 0, PROT_READ,MAP_POPULATE,p->mm->start_brk);


But, the above statement fails during execution and retruns a negetive value of -22.

1. Can you tell me what is the problem in above code?
2. Can you please tell me the actual steps for "mapping user space memory into the kernel " ?

Thanking you,
Rushikesh
Re: how to copy process-heap to kernel-buffer
November 01, 2009 09:46AM
Well well, a correct way if map user space memory into the kernel:

// Get user space page number nr_pages
...
down_read(&current->mm->mmap-sem);
rc = get_user_pages(current, current->mm, start & PAGE-MASK, nr-pages, 0 /* do not write*/, 1 /* do force */, pages, NULL);
up_read(&current->mm->mmap-sem);

Please google "map user space memory into kernel get_user_pages" to learn more.
or read the book Linux Device Drivers, 3rd Edition and search "get_user_pages".
Author:

Your Email:


Subject:


Message: