linux kernel read,内存管理 – Linux内核API probe_kernel_read

本文详细介绍了Linux内核中的probe_kernel_read函数,该函数用于安全地从用户空间复制数据到内核空间。通过一个具体的测试案例,展示了如何使用probe_kernel_read函数,并分析了函数的返回值和拷贝效果,揭示了内核空间与用户空间数据交互的过程。
摘要由CSDN通过智能技术生成

probe_kernel_read函数功能描述:probe_kernel_read( )函数通过函数__probe_kernel_read( )安全地尝试将用户空间地址src开始的大小为size的数据块拷贝到内核空间地址dst开始的目标地址空间中。

probe_kernel_read文件包含

#include

probe_kernel_read函数定义

在内核源码中的位置:linux-3.19.3/mm/maccess.c

函数定义格式:

long __weak probe_kernel_read(void *dst, const void *src, size_t size)

__attribute__((alias(“__probe_kernel_read”)));

probe_kernel_read输入参数说明

src:指源起始地址,它指向某一用户空间的地址。

dst:指目标起始地址,它指向某一内核空间的地址。

size:指从src到dst要拷贝的数据块大小,它以字节为单位。

probe_kernel_read返回值说明

该函数返回一个长整型:如果操作成功,函数返回0,即该长整型值为0;如果操作失败(或发生内核错误),函数返回-EFAULT,其值为-14。

probe_kernel_read实例解析

编写测试文件:probe_kernel_read.c

头文件及全局变量声明如下:

#include

#include

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

static int __init probe_kernel_read_init(void);

static void __exit probe_kernel_read_exit(void);

模块初始化函数:

int __init probe_kernel_read_init(void)

{

struct mm_struct *mm = current->mm; //mm指向当前进程的地址空间

unsigned long mm_start = mm->mmap->vm_start; //mm_start指当前进程地址空间的起始地址

unsigned long * src = NULL;

src = (unsigned long *)mm_start; //将源地址设置为用户空间的起始地址

printk("mm_start = 0x%lx\n", mm_start);

printk("*src = %lx\n", *src);

unsigned long * dst = NULL;

dst = (unsigned long *)kmalloc(sizeof(unsigned long), GFP_KERNEL);

// 目标地址为内核空间的地址

*dst = 5;

printk("*dst = %ld\n", *dst);

long ret = probe_kernel_read(dst, src, sizeof(unsigned long));

// 调用函数实现源地址到目标地址内容的拷贝

printk("ret = %ld\n", ret);

printk("after probe_kernel_read, *dst = %lx\n", *dst);

kfree(dst);

return 0;

}

模块退出函数:

void __exit probe_kernel_read_exit(void)

{

printk("exit! \n");

}

模块初始化及退出函数调用:

module_init(probe_kernel_read_init);

module_exit(probe_kernel_read_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod probe_kernel_read.ko插入模块,然后执行命令dmesg-c,会出现如图所示的结果。

f35607905ccf51e6e4d83c8ced00a161.png

结果分析:

该测试程序中先获取用户空间的某一地址当作待拷贝的源地址src,这里取当前进程首地址,由输出结果可知为0x7fa3dc336000,输出其内容为*src = 0x10102464c457f。然后开辟一个内核地址dst,将该地址开始的一个字节内容设置为5(*dst=5)。为了使程序简单,测试时令参数size=sizeof(unsigned long),即拷贝一定字节内容,调用函数probe_kernel_read(dst, src, sizeof(unsigned long)),由输出结果可知返回值ret = 0(即拷贝成功),并且*dst =0x10102464c457f = *src。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值