如何从用户空间访问内核空间?

时间:2022-04-23 17:50:02

How exactly is user memory and kernels memory differentiated inside the Linux kernel(in terms of giving security to kernel space)?

在Linux内核中,用户内存和内核内存的区别到底是什么(在给内核空间提供安全性方面)?

What are the different ways I can write in kernel address space from user space?

在内核地址空间中,我可以从用户空间中编写哪些不同的方法?

One way I know is through a system call. There are multiple system calls we can use, but at the end they are all system calls. Even in system calls, we send a data to kernel space, where it(driver or respective module) calls functions like copy_from_user() to copy data from user space to kernel space. Here we exactly are not writing into address space. we are just passing a user pointer which contains the data that needs to be copied into the kernel buffers.

我知道的一种方法是通过系统调用。我们可以使用多个系统调用,但最后它们都是系统调用。即使在系统调用中,我们也将数据发送到内核空间,在内核空间中,它(驱动程序或相应的模块)调用copy_from_user()等函数,将数据从用户空间复制到内核空间。这里我们没有写地址空间。我们只是传递一个用户指针,它包含需要复制到内核缓冲区中的数据。

My question is there any way we can access a physical address that is present in the kernel space and perform operations on it?

我的问题是,我们是否可以访问内核空间中存在的物理地址并对其执行操作?

Second, Apart from system calls are there any other ways I can write into kernel space from an user application?

第二,除了系统调用之外,还有其他可以从用户应用程序写入内核空间的方法吗?

I referred to this link from *. But I think my question is not answered there and is from different perspective. Hence I thought of asking a different question.

我引用了来自*的链接。但我认为我的问题没有得到回答,而是从不同的角度。因此我想问一个不同的问题。

Please share your knowledge... Thanks.

请分享你的知识…谢谢。

2 个解决方案

#1


19  

What are the different ways I can write in kernel address space from user space?

在内核地址空间中,我可以从用户空间中编写哪些不同的方法?

I'm not sure if there're other methods, but you can access physical memory using /dev/mem & system call mmap().

我不确定是否还有其他方法,但是可以使用/dev/mem和system call mmap()访问物理内存。

/dev/mem is a character device file that is an image of the main memory of the computer. It may be used, for example, to examine (and even patch) the system. Byte addresses in mem are interpreted as physical memory addresses.

/dev/mem是一个字符设备文件,它是计算机主存的映像。例如,它可以用于检查(甚至修补)系统。mem中的字节地址被解释为物理内存地址。

more on /dev/mem: http://linux.about.com/library/cmd/blcmdl4_mem.htm

更多关于/dev/mem:http://linux.about.com/library/cmd/blcmdl4_mem.htm

more on mmap(): http://linux.die.net/man/2/mmap

更多关于mmap():http://linux.die.net/man/2/mmap

You can use the mmap() to map a section of /dev/mem and use in your user program. A brief example code:

您可以使用mmap()来映射/dev/mem的一部分,并在您的用户程序中使用。一个简单的示例代码:

#define MAPPED_SIZE //place the size here
#define DDR_RAM_PHYS  //place the physical address here

int _fdmem;
int *map = NULL;
const char memDevice[] = "/dev/mem";

/* open /dev/mem and error checking */
_fdmem = open( memDevice, O_RDWR | O_SYNC );

if (_fdmem < 0){
printf("Failed to open the /dev/mem !\n");
return 0;
}
else{
printf("open /dev/mem successfully !\n");
}

/* mmap() the opened /dev/mem */
map= (int *)(mmap(0,MAPPED_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,_fdmem,DDR_RAM_PHYS));

/* use 'map' pointer to access the mapped area! */
for (i=0,i<100;i++)
printf("content: 0x%x\n",*(map+i));

/* unmap the area & error checking */
if (munmap(map,MAPPED_SIZE)==-1){
perror("Error un-mmapping the file");
}

/* close the character device */
close(_fdmem);

However, please make sure the area you are mapping is not used, for example by the kernel, or it will make your system crash/hang, and you will be forced to reboot using hardware power button.

但是,请确保您正在映射的区域没有被使用,例如由内核使用,或者它将使您的系统崩溃/挂起,并且您将*使用硬件power按钮重新启动。

Hope it helps.

希望它可以帮助。

#2


3  

How exactly is user memory and kernels memory differentiated inside the Linux kernel(in terms of giving security to kernel space)?

在Linux内核中,用户内存和内核内存的区别到底是什么(在给内核空间提供安全性方面)?

Not sure if I understood your question.

不知道我是否理解你的问题。

To the kernel there isn't much difference technically, it's just memory. Why? Because the kernel, which is running in the most privileged CPU mode, can access all memory.

对于内核来说,技术上没有什么不同,只是内存。为什么?因为内核在最特权的CPU模式下运行,可以访问所有内存。

What are the different ways I can write in kernel address space from user space?

在内核地址空间中,我可以从用户空间中编写哪些不同的方法?

Unless there's a security hole in the kernel or kernel mode device drivers, you can't do that, at least not directly. The kernel (or one of its drivers) may, however, copy data from the user mode application's memory to the kernel memory.

除非内核或内核模式设备驱动程序存在安全漏洞,否则您不能这样做,至少不能直接这样做。但是,内核(或其中一个驱动程序)可以将用户模式应用程序的内存中的数据复制到内核内存中。

... is there any way we can access a physical address that is present in the kernel space and perform operations on it?

…我们是否可以访问内核空间中存在的物理地址并对其执行操作?

Same thing, you should not be able to access memory using physical addresses if there's virtual to physical address translation present. Even the kernel itself cannot avoid this translation once it's enabled. It has to create appropriate virtual to physical address mappings in the page tables to access memory at arbitrary physical addresses.

同样,如果存在虚拟到物理地址转换,则不应该使用物理地址访问内存。即使内核本身也无法避免这种转换,一旦启用了这种转换。它必须在页表中创建适当的虚拟到物理地址映射,以便在任意物理地址访问内存。

Apart from system calls are there any other ways I can write into kernel space from an user application?

除了系统调用之外,还有其他方法可以从用户应用程序写入内核空间吗?

You can also force the CPU to switch to the kernel code by triggering an exception (e.g. division by 0, page fault, general protection fault, etc). The kernel is the first one to handle exceptions. The kernel will change its memory as needed in response to an exception. It may load data from somewhere (e.g. disk) on a page fault.

您还可以通过触发一个异常(例如除0、页错误、一般保护错误等)迫使CPU切换到内核代码。内核是第一个处理异常的内核。内核将根据需要更改内存以响应异常。它可以在页面错误上从某个地方(例如磁盘)加载数据。

#1


19  

What are the different ways I can write in kernel address space from user space?

在内核地址空间中,我可以从用户空间中编写哪些不同的方法?

I'm not sure if there're other methods, but you can access physical memory using /dev/mem & system call mmap().

我不确定是否还有其他方法,但是可以使用/dev/mem和system call mmap()访问物理内存。

/dev/mem is a character device file that is an image of the main memory of the computer. It may be used, for example, to examine (and even patch) the system. Byte addresses in mem are interpreted as physical memory addresses.

/dev/mem是一个字符设备文件,它是计算机主存的映像。例如,它可以用于检查(甚至修补)系统。mem中的字节地址被解释为物理内存地址。

more on /dev/mem: http://linux.about.com/library/cmd/blcmdl4_mem.htm

更多关于/dev/mem:http://linux.about.com/library/cmd/blcmdl4_mem.htm

more on mmap(): http://linux.die.net/man/2/mmap

更多关于mmap():http://linux.die.net/man/2/mmap

You can use the mmap() to map a section of /dev/mem and use in your user program. A brief example code:

您可以使用mmap()来映射/dev/mem的一部分,并在您的用户程序中使用。一个简单的示例代码:

#define MAPPED_SIZE //place the size here
#define DDR_RAM_PHYS  //place the physical address here

int _fdmem;
int *map = NULL;
const char memDevice[] = "/dev/mem";

/* open /dev/mem and error checking */
_fdmem = open( memDevice, O_RDWR | O_SYNC );

if (_fdmem < 0){
printf("Failed to open the /dev/mem !\n");
return 0;
}
else{
printf("open /dev/mem successfully !\n");
}

/* mmap() the opened /dev/mem */
map= (int *)(mmap(0,MAPPED_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,_fdmem,DDR_RAM_PHYS));

/* use 'map' pointer to access the mapped area! */
for (i=0,i<100;i++)
printf("content: 0x%x\n",*(map+i));

/* unmap the area & error checking */
if (munmap(map,MAPPED_SIZE)==-1){
perror("Error un-mmapping the file");
}

/* close the character device */
close(_fdmem);

However, please make sure the area you are mapping is not used, for example by the kernel, or it will make your system crash/hang, and you will be forced to reboot using hardware power button.

但是,请确保您正在映射的区域没有被使用,例如由内核使用,或者它将使您的系统崩溃/挂起,并且您将*使用硬件power按钮重新启动。

Hope it helps.

希望它可以帮助。

#2


3  

How exactly is user memory and kernels memory differentiated inside the Linux kernel(in terms of giving security to kernel space)?

在Linux内核中,用户内存和内核内存的区别到底是什么(在给内核空间提供安全性方面)?

Not sure if I understood your question.

不知道我是否理解你的问题。

To the kernel there isn't much difference technically, it's just memory. Why? Because the kernel, which is running in the most privileged CPU mode, can access all memory.

对于内核来说,技术上没有什么不同,只是内存。为什么?因为内核在最特权的CPU模式下运行,可以访问所有内存。

What are the different ways I can write in kernel address space from user space?

在内核地址空间中,我可以从用户空间中编写哪些不同的方法?

Unless there's a security hole in the kernel or kernel mode device drivers, you can't do that, at least not directly. The kernel (or one of its drivers) may, however, copy data from the user mode application's memory to the kernel memory.

除非内核或内核模式设备驱动程序存在安全漏洞,否则您不能这样做,至少不能直接这样做。但是,内核(或其中一个驱动程序)可以将用户模式应用程序的内存中的数据复制到内核内存中。

... is there any way we can access a physical address that is present in the kernel space and perform operations on it?

…我们是否可以访问内核空间中存在的物理地址并对其执行操作?

Same thing, you should not be able to access memory using physical addresses if there's virtual to physical address translation present. Even the kernel itself cannot avoid this translation once it's enabled. It has to create appropriate virtual to physical address mappings in the page tables to access memory at arbitrary physical addresses.

同样,如果存在虚拟到物理地址转换,则不应该使用物理地址访问内存。即使内核本身也无法避免这种转换,一旦启用了这种转换。它必须在页表中创建适当的虚拟到物理地址映射,以便在任意物理地址访问内存。

Apart from system calls are there any other ways I can write into kernel space from an user application?

除了系统调用之外,还有其他方法可以从用户应用程序写入内核空间吗?

You can also force the CPU to switch to the kernel code by triggering an exception (e.g. division by 0, page fault, general protection fault, etc). The kernel is the first one to handle exceptions. The kernel will change its memory as needed in response to an exception. It may load data from somewhere (e.g. disk) on a page fault.

您还可以通过触发一个异常(例如除0、页错误、一般保护错误等)迫使CPU切换到内核代码。内核是第一个处理异常的内核。内核将根据需要更改内存以响应异常。它可以在页面错误上从某个地方(例如磁盘)加载数据。