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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Fybon/article/details/18044369

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

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


注意:内核地址空间的范围是 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是如何保护受限制内存的呢? 还有待进一步研究。

展开阅读全文

请教 Unable to handle kernel paging request at virtual address 60519ad0 问题

09-22

在开发板上运行程序, 程序运行一段时间之后(这个时间不好确定,有时候是几分钟有时候是几个小时)程序就会退出不再执行,通过串口的打印可以看到如下的信息:rnrnUnable to handle kernel paging request at virtual address 60519ad0rnrnpgd = c1e60000rnrn[60519ad0] *pgd=00000000rnrnInternal error: Oops: 5 [#1]rnrnModules linked in: hi3510_vs pcf8563 hi_sio tlv320 adv7171 hi_i2c ohci_hcd misc_gpio hi_gpio hi3510_wdtrnrnCPU: 0rnrnPC is at 0xc0510720rnrnLR is at 0x10rnrnpc : [] lr : [<00000010>] Not taintedrnrnsp : c100de64 ip : 00000000 fp : c100df24rnrnr10: 00000000 r9 : c16501f8 r8 : 00000003rnrnr7 : 00000048 r6 : bf000000 r5 : c100de70 r4 : 00000000rnrnr3 : 60519ad0 r2 : 00000010 r1 : c100de70 r0 : bddffbb8rnrnFlags: nzCv IRQs on FIQs on Mode SVC_32 Segment userrnrnControl: 5317F Table: 61E60000 DAC: 00000015rnrnProcess dec_server (pid: 265, stack limit = 0xc100c194)rnrnStack: (0xc100de64 to 0xc100e000)rnrnde60: bddffbb8 c100de7c c0505790 bf027428 c100de7c c1e0f6cc 00000000 rnrnde80: 00000001 00000000 00000005 00000160 00000120 00000000 00000000 626c6100 rnrndea0: 62732100 00000000 00000300 00000300 00000000 00000001 bddffc00 00000000 rnrndec0: 00000001 c1e8ad00 c100df14 c100ded8 c01f5c70 c0037238 c1ee89b4 00000f30 rnrndee0: c1ee8abc 98c88520 0000111a 001cb213 00000002 c100c000 c100df18 c1e0f6cc rnrndf00: ffffffe7 c0484806 bddffbb8 00000000 c100c000 000c9104 c100df38 c100df28 rnrndf20: bf027820 bf01e914 bf027418 c100df58 c100df3c c00922f0 bf027814 c1e0f6cc rnrndf40: c16501f8 bddffbb8 00000011 c100df84 c100df5c c00925f4 c0092284 c007e544 rnrndf60: c0037238 c1e0f6cc fffffff7 c0484806 00000036 c0021f64 c100dfa4 c100df88 rnrndf80: c0092654 c0092314 00000001 000e3094 bddffd28 00000000 00000000 c100dfa8 rnrndfa0: c0021de0 c0092624 000e3094 c01f5610 00000011 c0484806 bddffbb8 00000001 rnrndfc0: 000e3094 bddffd28 00000000 000002a0 bddffc00 0016ad3c 000c9104 00000000 rnrndfe0: 00000011 bddffba0 0009c8e8 0009c8b0 a0000010 00000011 0606e306 e30606e3 rnrnBacktrace: rnrn[] (CMPI_UserCopy+0x0/0x19c [hi3510_vs]) from [] (DRV_VDEC_Ioctl+0x1c/0x24 [hi3510_vs])rnrn[] (DRV_VDEC_Ioctl+0x0/0x24 [hi3510_vs]) from [] (do_ioctl+0x7c/0x90)rnrn[] (do_ioctl+0x0/0x90) from [] (vfs_ioctl+0x2f0/0x310)rnrn r7 = 00000011 r6 = BDDFFBB8 r5 = C16501F8 r4 = C1E0F6CCrnrn[] (vfs_ioctl+0x0/0x310) from [] (sys_ioctl+0x40/0x60)rnrn r8 = C0021F64 r7 = 00000036 r6 = C0484806 r5 = FFFFFFF7rnrn r4 = C1E0F6CC rnrn[] (sys_ioctl+0x0/0x60) from [] (ret_fast_syscall+0x0/0x2c)rnrn r6 = 00000000 r5 = BDDFFD28 r4 = 000E3094 rnrnCode: e024249e e2800001 e5d0c000 e59f3044 (e7d3300c) rnrn rnrnrnrnrn研究了半天始终没搞明白为什么会出这种问题。不知道是程序的问题还是底层驱动的问题。rn请各位帮小弟看看这应该是哪个地方的问题。 论坛

没有更多推荐了,返回首页