Why do you have to use copy_to_user()/copy_from_user() to access user space from the kernel?
Asked Answered
H

2

23

I'm curious, because I got a kernel panic after trying to access memory directly (then I found these functions).

Hatter answered 1/10, 2012 at 1:9 Comment(0)
N
35

These functions do a few things:

  • They check if the supplied userspace block is entirely within the user portion of the address space (access_ok()) - this prevents userspace applications from asking the kernel to read/write kernel addresses;
  • They return an error if any of the addresses are inaccessible, allowing the error to be returned to userspace (EFAULT) instead of crashing the kernel (this is implemented by special co-operation with the page fault handler, which specifically can detect when a fault occurs in one of the user memory access functions);
  • They allow architecture-specific magic, for example to ensure consistency on architectures with virtually-tagged caches, to disable protections like SMAP or to switch address spaces on architectures with separate user/kernel address spaces like S/390.
Nanoid answered 1/10, 2012 at 1:27 Comment(6)
@ComtriS: I'm not sure what you mean by "allowed", but if you're getting a kernel panic then either you must not have checked the page permissions or not disabled some architecture-specific protection. Note that checking the page permissions and then accessing the pages is going to be racy.Nanoid
is it only for security check (including checking mmu table entry is valid)? if I use just memcpy instead of copy_from/to_user function, can it just run ok in some cases? I want to know if the copy_from/to_user contains address translation(using software) function.Joshi
@ChanKim: It depends on the architecture (see the third point in the answer). For example, SMAP is going to stop you on x86-64 with a modern processor.Nanoid
yes, I can understand the STAC, CLAC commands to access user space. but isn't the user address 'value' virtual address handed from user process (different address space)? how can the kernel access the memory area pointed to by the 'user virtual address' with its kernel mmu table? shouldn't there be address 'value' translation using user process's page table? I looked into the kernel source but it's a little complex for me to follow.. :)Joshi
@ChanKim: Some architectures (e.g. S/390) do use completely separate address spaces for the kernel and user space. However, on others like x86-64 and arm the user addresses for the current process are mapped into the kernel page tables (on x86-64, the kernel address space has all the upper bits of the addresses as 1, and the user part has those upper bits as 0). Without the Spectre/Meltdown countermeasures active, the page table isn't even changed between kernel and user mode - it only changes when switching between processes.Nanoid
ah that was the case. It was a very important fact. Thank you so much.Joshi
C
13

Those functions check whether the memory is accessible. If the kernel attempts to directly access a non-accessible address, it will panic. But in addition, the kernel and user address spaces may be different ... a valid address in the user address space may not be accessible in the kernel, and if it is it may point to kernel stuff rather than user stuff.

For more details, see https://developer.ibm.com/articles/l-kernel-memory-access

On a historical note: once upon a time there were operating systems in which the kernel was designed to be part of the user address space, and in those systems the kernel could always access user space directly. There may still be such systems, but modern linux isn't one. The user process's memory being part of the kernel address space is always an option for the implementation, of course, and that can make copy_to_user and copy_from_user a lot faster.

Chariness answered 1/10, 2012 at 1:13 Comment(2)
Actually, on most architectures modern Linux does use a unified user/kernel address space - for example x86-64. There are exceptions, like the 4G/4G configuration option for the x86 architecture, but there is significant overhead.Nanoid
the link to ibm.com has changed to : developer.ibm.com/articles/l-kernel-memory-accessJoshi

© 2022 - 2024 — McMap. All rights reserved.