Solved

how to access user space memory from kernel Module

Posted on 2006-07-19
24
532 Views
Last Modified: 2008-02-01
Hi Experts

how to access user space memory from kernel Module ?

basically the memory belongs to a process in user mode
0
Comment
Question by:mmadhuso
  • 9
  • 8
  • 4
24 Comments
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17144364
copy_from_user()
0
 

Author Comment

by:mmadhuso
ID: 17149918
has any one used do_mumap() function  in a linux Kernel Module

please help me out
0
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17158500
do_mumap() does not occur anywhere in kernel source. Are you sure you have the spelling right?
I can find references to do_munmap(). fs/binfmt_flat.c uses it, and can be compiled as a module. ( Support uClinux FLAT format binaries)
0
 

Expert Comment

by:bmuzal
ID: 17159207
First,  in the kernel, code runs in one of 2 modes,  interrupt context or user context. Code running in interrupt context cannot access user process memory because it in not associate with any process virtual address space.

User context includes such things as system calls. In this case, the kernel memory space is mapped into the same virtual space as the process. Because of this, if you were to dereference a valid user space pointer that happened to be physical memory at the time, it would probably work (at least on x86). However, because you can never be sure if a pointer is going to be valid, it is always best to use the function copy_from_user() when copying data from user space and copy_to_user() to copy to user space. These functions won't segfault, instead if they cannot do a copy, they will return the number bytes that could not be copied.

Second, do_munmap() is defined in mm/mmap.c. do_munmap() can be used *exactly* like the Linux system call munmap(), except that the first argument should be “current->mm” without the quotes.  There is nothing else special that you need to do to make it work. It is preferable to use the function sys_munmap(). The only difference is that sys_munmap() gets current->mm and locks mm's semaphore before calling do_munmap() so always using sys_munmap() will help your code be reentrant. (very important if you run on a preemptible kernel or a machine with more than one CPU)

A very good reference on this topic: http://www.xml.com/ldd/chapter/book/ch13.html

Prototypes:
unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
long sys_munmap(unsigned long addr, size_t len)


And let me suggest the Linux Cross Reference if you have to look up kernel functions (http://lxr.linux.no/)
0
 

Expert Comment

by:bmuzal
ID: 17159682
What exactly are you trying to do with munmap?
0
 

Author Comment

by:mmadhuso
ID: 17160501
Hi bmuzal

I would like to deallocate some memory from the Data Segement of a user process while it is running,
basically suspend a process , remove some memory from data segement and resume the process

let me know how this can be acheived

0
 

Expert Comment

by:bmuzal
ID: 17164486
You mean the .data segment that is part of an elf file? My knee jerk reaction is to say WHY IN THE WORLD WOULD YOU WANT TO DO A STRANGE THING LIKE THAT??? But then I remember my grad student days (which weren't to long ago, and technicality aren't over yet) where we did equally strange thing in the name of research. (you are a student right? Maybe in a computer engineering department? You have me very curious to why you are trying to do this.)

The first problem that I see, is that the OS only deals with memory allocation in chunks of memory pages. On my Pentium4, pages are 4KB. Because of this, it seems that there might be more than just the elf's .data section on a given page. So, before you could do anything, you would have to convince the elf loader (fs/binfmt_elf.c) to load the .data section into its own vma (virtual memory area -- contiguous virtual memory space). This may or may not be too dificult. To look at the defined vma's for a process you can read the 'files' /proc/<pid>/maps or /proc/<pid>/smaps  (I know this works on a 2.6 kernel. I don't know about older ones). This is fun, because you can see where all of the shared libs have been loaded into memory.

If you are able to make this change to the elf loader, and youare  okay with being able to only clobber 4KB of data at a time,  then a process could easily unallocate his own .data section  in 4KB increments using the munmap() system call. (it cold read one of those proc files I listed in orderto get the start address of the vma you are interested in. However, it sounds like you want one program to be able to deallocate another program's .data section without the other program knowing about it.  The best way for one process to interrupt another process is through the use of the ptrace() system call. This is the system call that debuggers use. For example, the command "strace -e ptrace gdb <program to debug>" will show whenever gdb uses the ptrace system call.

Anyway, I would suggest expanding the functionality of ptrace to do your dirty work.  In sys_ptrace() [arch/<yourarch>/kernel/ptrace.c] , you  would need to get your target processes mm structure (I saw some code in one of the helper functions in that file that shows how it is done) and then you could sys_munmap() as much as you want. Just give it the mm, the start address of the page you want to clobber, and the length in bytes(in increments of 4K)


 
0
 

Expert Comment

by:bmuzal
ID: 17164512
Oh yea, there is a good chance that your program won't like you moving the .data section from where it was expecting it to be in memory. This could concievabally require a change to binutils (the animal that understands elfs) or a post processing step. I am not sure on this point though.
0
 

Expert Comment

by:bmuzal
ID: 17164667
Oh, I see, you are trying to make a garbage collector. libc calls mmap() (or similar) when it needs more virtual memory for a malloc(). munmap() will certianly undo the allocation. It does not even have to be called from within the kernel.

and by the way

while(1)
{ int buf[10000] }

is not a memory leak. The most memory that it will ever use is 10000 bytes.

0
 

Author Comment

by:mmadhuso
ID: 17168694
hi bmuzal
(1)  well
int *a ;
while (1)
a=(int)calloc(100000,(sizeof(bool)));

is definately a Leak right

[2]  My concern is just remove the allocated memory from a process while is running , i will take care of the consequences of this ,

Can i get a code snippet of what you explained to me , so that i dont get lost
 
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 34

Accepted Solution

by:
Duncan Roe earned 63 total points
ID: 17171717
mmadhuso,
Is this by any chance a flow-on from http://www.experts-exchange.com/Programming/Programming_Platforms/Linux_Programming/Q_21918229.html
You're trying to purge leaked memory, right?
You don't want to munmap memory - you want to deallocate it. Problem is, malloc'd blocks are linked by pointers, so if you punch a hole in the storage arena you're likely to break the chain, causing malloc or free to fail subsequently.
I said then and I say now - you have to fix the leak at its source.
0
 

Author Comment

by:mmadhuso
ID: 17172425
hi Duncan_Roe

Thanks for the follow up , so u say that its impossible to fix the problem at run time  ??

Even if  there is a chance i would like to explore it !!!!!!
I know it sounds stupid but i want to acheive it . Just help me purge some thing then i will find out
which memory to purge .

I want to use this crude approach

please help me out
0
 

Assisted Solution

by:bmuzal
bmuzal earned 62 total points
ID: 17173612
I think that unallocating virtual memory space out from under a process will not be easy to do with out the program crashing. (If you get it to work, I think it will be dependent on a very specific libc malloc() implementation) But if you insist on doing it:

From the "Teach a man to fish" department:
The only tricky part of using do_munmap() is getting the mm structure. After that you just give do_munmap() the start address of the page and the number of bytes(in increments of 4k) you want to release. (see the function prototye that I gave you above) ** You  will have to determine these values on your own because they are specific to your implementation**  As for a code snipit, a very good example of a working piece of code that gets and uses mm is found at http://lxr.linux.no/source/kernel/ptrace.c#L194. If you  want to find out where a function is called so that you can see how a parameter is calculated, just click on the function name and look under the "Referenced" list.

Good luck.

*** Over and Out ***
0
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17179215
Just create a couple of 2G swap discs. If your program really has pages which it's not using, they will drift out to swap. If your program is leaking continuously, it will eventually run out of address space and crash (unless it's a 64-bit program - is it?)
0
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17655030
Actually I think malloc() calls brk(), not mmap(). So do_munmap() may have been along the wrong track. Nevertheless bmuzal did a good job of trying to answer this (misguided) question, although I think my last post was the ultimate answer to mmadhuso's actual problem. Why take the time to deallocate wholly unused memory pages (if any such exist) when they will just drift out to swap anyway? If pages are not wholly unused, the original premise is false (that you can do garbage collection by deallocating them). Points? modesty forbids
0
 

Expert Comment

by:bmuzal
ID: 17657567
Hmmm.... I did say that "libc calls mmap() (or similar)" and brk() is similar to mmap(). Also, sys_brk() which modifies process data segment size calls do_munmap() when it wants to shrink the data segment. (mm/mmap.c) Therefore (I assume because I have never tryed to do this myself), that do_munmap() would be the correct way to release "custom" sections out of the data segment back to the OS.

The real problem the original poster had and cannot solve is, how does one know when memory is being used. A traditional garbage collector maintains reference counts to memory objects (or linked lists... or some other way to hold on to references of garbage memory). How would an external program search a memory space and determine which memory is being used and which memory is garbage? Even if a program had not tuched a memory location for 3 weeks it does not guarantee that it will never need it again.

I think that the idea of the original poster was to never have to worry about freeing continuously leaking memory by releasing the memory back to the operating system. The large swap space idea would just delay the inevitable and is not an answer to the original question on how to release memory.

0
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17658080
Oh I see - brk() is a bit like mmap(..MAP_ANON..) - Ok I take your point.

I think that the idea of the original poster was he had this buggy program and couldn't fix it (no source?) so hoped he could unmap unused pages unbeknownst to the program. Even if it could be ever implemented, this method would run out of address space as surely as the large swapfile method would because the program would keep advancing its  process data segment size until that happened. With a 32-bit program it's perfectly feasible to provide the few gigs of swap needed in the worst case (when every page is dirtied).

In a 64-bit system , the data segment size limit is much higher**, so the program would run out of swap space before it reached it. But either way, it would run for a while and crash eventually. Again, even if you did have the garbage collector, it would eventually reach the brk() limit and crash.

What he seeks to do is misguided if not impossible. I think we both told him that - would you be happy to split the points?

** See http://www.experts-exchange.com/Operating_Systems/Linux/Q_21943270.html
If you have a 64-bit system, fplease do try the test program - what result do you get?
0
 

Expert Comment

by:bmuzal
ID: 17663063
.... I think he was trying to do research for a graduate degree or independent study, but that is only my guess ....

The answer to the title question "Title: how to access user space memory from kernel Module" is best answered by my first post, but I would be ok with a 90% - 10% split.

0
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17663689
Your 90% or mione? Come on - 50/50.  His whole method is doomed to fail
0
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17663711
What he seeks to do cannot be done, so I could claim that I was right to say so and he just doesn't like it.
0
 
LVL 34

Expert Comment

by:Duncan Roe
ID: 17711141
mmadhuso:
Just because you don't *like* an answer is no reason to give it a C grade. If the answer is correct, you must give it at least a B if (although usually an A). See http://www.experts-exchange.com/help.jsp#hi73
I said what you were seeking to do was not possible and I was right.
Please raise a Community Support question asking for the question to be re-opened so you can re-grade it
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Little introduction about CP: CP is a command on linux that use to copy files and folder from one location to another location. Example usage of CP as follow: cp /myfoder /pathto/destination/folder/ cp abc.tar.gz /pathto/destination/folder/ab…
Connecting to an Amazon Linux EC2 Instance from Windows Using PuTTY.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now