Link to home
Start Free TrialLog in
Avatar of mmadhuso
mmadhuso

asked on

how to access user space memory from kernel Module

Hi Experts

how to access user space memory from kernel Module ?

basically the memory belongs to a process in user mode
Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

copy_from_user()
Avatar of mmadhuso
mmadhuso

ASKER

has any one used do_mumap() function  in a linux Kernel Module

please help me out
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)
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/)
What exactly are you trying to do with munmap?
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

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)


 
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.
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.

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
 
ASKER CERTIFIED SOLUTION
Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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?)
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
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.

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 https://www.experts-exchange.com/questions/21943270/x86-64-and-process-vmemory-limit.html
If you have a 64-bit system, fplease do try the test program - what result do you get?
.... 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.

Your 90% or mione? Come on - 50/50.  His whole method is doomed to fail
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.
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 https://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