Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access user space memory from the Linux kernel?

I know that copy_to_user/copy_from_user, get_user/put_user functions are for this purpose.

My question is that, given a user space address/pointer, how can I access the data pointed to by the address from the kernel in general?

I can imagine that first I have to make sure the containing page should be in physical memory (instead of in disk).

What is the next step? Can I use *p, where p is the pointer pointing to some user space data, directly to refer to the data?

Or do I have to first invoke kmap to map the containing physical page frame to the kernel virtual address space? Why?

like image 227
Infinite Avatar asked May 09 '12 04:05

Infinite


People also ask

How do I access user space from kernel?

Whilst a user-space program is not allowed to access kernel memory, it is possible for the kernel to access user memory. However, the kernel must never execute user-space memory and it must also never access user-space memory without explicit expectation to do so.

What is user space in Linux kernel?

User space refers to all of the code in an operating system that lives outside of the kernel. Most Unix-like operating systems (including Linux) come pre-packaged with all kinds of utilities, programming languages, and graphical tools - these are user space applications. We often refer to this as “userland.”

How does kernel communicate with user space?

Communicate with user spaceThe user space must open a file specified by path name using the open() API. This file will be used by both, the user application and the kernel module to interact with each other.

How do you send data from user space to kernel space?

The copy_from_user function copies a block of data from user space into a kernel buffer. it accepts a destination buffer (in kernel space), a source buffer (from user space), and a length defined in bytes.


2 Answers

You'll need to follow an address to get a corresponding page struct (see follow_page for the example). Next, getting the page struct you'll need to map it to kernel's address space via kmap or kmap_atomic.

like image 161
Ilya Matveychikov Avatar answered Sep 23 '22 15:09

Ilya Matveychikov


You may find this useful.

Let us repeat that the buff argument to the read and write methods is a user-space pointer. Therefore, it cannot be directly dereferenced by kernel code. There are a few reasons for this restriction:

  • Depending on which architecture your driver is running on, and how the kernel was configured, the user-space pointer may not be valid while running in kernel mode at all. There may be no mapping for that address, or it could point to some other, random data.

  • Even if the pointer does mean the same thing in kernel space, user-space memory is paged, and the memory in question might not be resident in RAM when the system call is made. Attempting to reference the user-space memory directly could generate a page fault, which is something that kernel code is not allowed to do. The result would be an "oops," which would result in the death of the process that made the system call.

  • The pointer in question has been supplied by a user program, which could be buggy or malicious. If your driver ever blindly dereferences a user-supplied pointer, it provides an open doorway allowing a user-space program to access or overwrite memory anywhere in the system. If you do not wish to be responsible for compromising the security of your users' systems, you cannot ever dereference a user-space pointer directly.

Source: http://www.makelinux.net/ldd3/chp-3-sect-7

That said, I am myself curious to know what happens if the user-space address is indeed valid, and none of the above conditions apply...

like image 32
gjain Avatar answered Sep 22 '22 15:09

gjain