kernel oops (Unable to handle kernel paging request at virtual address )三种内存访问异常

一、linux内核、用户空间的内存划分:

如下图:内核空间划分0~3G为用户空间,3~4G为内核空间。详细请参考《Linux用户空间与内核空间》

kernel oops (Unable to handle kernel paging request at virtual address )三种内存访问异常_第1张图片


注意:内核地址空间的范围是 0xC0000000 ~ 0xFFFFFFFF 


二、异常内存访问导致的oops:


1、Unable to handle kernel paging request at virtual address 00000000

         =====》越出内核地址空间范围,原因是由于使用空NULL指针


2、Unable to handle kernel paging request at virtual address 20100110

    =====》越出内核地址空间范围,原因是的内存越界导致该指针

     所在内存被破坏了。 接下来的困难是在什么地方这个内存被修改?为什么被修改?


3、Unable to handle kernel paging request at virtual address c074838c

      =====》没有越出内核地址空间范围,为什么也oops?

     这种情况我称之为:试图篡改受限制内存。比如:声明为const的变量!

     还有其它形式的受限制内存吗?


三、访问受限制内存导致oops:

const在C语言当中声明一个变量为只读,
如果试图直接修改const变量,build阶段 编译器,就检查出来,并报read only错误,
如下:
const int i = 1;
i = 10;
build error: assignment of read-only variable 'i'  //只读变量赋值错误

但是如果通过指针间接修改const变量,编译器是检查不出来的。
如下:
const int i = 1;
int *p = &i;    
*p = 10;
不出所料地编译成功了! 但不要高兴,这样的代码是有隐患的!
因为,很显然,我们将变量声明为const,是希望它能受到保护的!
既然编译器检查不出这种隐患,由谁负责保护它呢?
我想,linux只有运行时,由mm模块来保护声明为const的变量了!!!???
但遗憾的是,linux 3.4.5以前的版本一直没有这个保护功能,应该老版本linux自身的漏洞吧!
直到约 linux 3.4.67 (android 4.4)才有运行时保护受限制内存的功能。


如果这么简直地直接使用指针显示地间接修改一个某const变量,还是很容易查出来的。

下面举一个掩蔽的例子:

static struct file_operations *new_file_operations = NULL;
static struct file_operations original_file_operations = {0};
ssize_t new_file_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
    if(!isCanWrite(filp))
    {
        return -ENOSPC;
    }

    return original_file_operations.write(filp, buf, len, ppos);
}

static int __init lowmemdetect_init(void)
{
    myfile = filp_open("/data", O_WRONLY | O_CREAT, 0);
    if (!IS_ERR(myfile) && (myfile->f_op != NULL))
    {
        original_file_operations.write = myfile->f_op->write;  //it point to do_sync_write()
        original_file_operations.aio_write = myfile->f_op->aio_write; //it point to ext4_file_write()
        new_file_operations = myfile->f_op;    //it point to ext4_file_operations
 //这句掩蔽地间接将new_file_operations指针指向kernel\fs\ext4\file.c的一个const变量ext4_file_operations
        new_file_operations->write = new_file_write;   //modify ext4_file_operations->write 
 //这句掩蔽地间接修改const变量ext4_file_operations,它在新版本linux 3.4.67 (android 4.4)中运行导致oops 。
        filp_close(myfile, NULL);
    }
}

/*   声明const变量:
kernel\fs\ext4\file.c
const struct file_operations ext4_file_operations = {
.llseek = ext4_llseek,
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = ext4_file_write,
*/

linux 3.4.67 (android 4.4)版本kernel是如何保护受限制内存的呢? 还有待进一步研究。

你可能感兴趣的:(linux)