免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: superhappy1
打印 上一主题 下一主题

Linux内核的代码段是只读的吗?进程的代码段呢? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-07-12 18:51 |只看该作者
本帖最后由 kgn28 于 2010-07-12 18:53 编辑

回复 10# new_learner
  1. #include <linux/module.h>
  2. #include <linux/vmalloc.h>
  3. #include <linux/kernel.h>
  4. #include <linux/kmod.h>

  5. MODULE_LICENSE("GPL");

  6. int __init mem_module_init(void)
  7. {
  8.         int i;
  9.         void *p = (void*)0xffffffff80200000;
  10.         void *p1 =(void*)0xffffffff80200001;
  11.         void *p2 =(void*)PAGE_OFFSET + 0x900000;
  12.         int *q  = (int*)p;
  13.         int *q1  = (int*)p1;
  14.         int *q2  = (int*)p2;

  15.         printk("=>PAGE_OFFSET = %lx\n", PAGE_OFFSET);
  16.         printk("=>%d\n", *q);
  17.         *q = 1;
  18.         printk("=>%d\n", *q);
  19.         printk("=>%d\n", *q1);
  20.         *q1 = 1;
  21.         printk("=>%d\n", *q1);
  22.         printk("=>%d\n", *q2);
  23.         *q2 = 1;
  24.         printk("=>%d\n", *q2);
  25.         printk("=>%lx\n", &i);

  26.         return 0;
  27. }

  28. void __exit mem_module_exit(void)
  29. {

  30.         printk("hello modle exit\n");
  31. }

  32. module_init(mem_module_init);
  33. module_exit(mem_module_exit);
复制代码
结果如下:
hello kernel
=>PAGE_OFFSET = ffff880000000000
=>257
=>1
=>0
=>1
=>507
=>1
=>ffff88006d5dbf24

其中0xffffffff80200000是内核代码段开始的地方(见此:http://linux.chinaunix.net/bbs/thread-1151780-1-1.html),那么我把这个地址加1的地方写了一个数,居然可以通过。往PAGE_OFFSET + 0x900000这个地方写也可以通过。
基于一下考虑:
1,PAGE_OFFSET+9M的地方可能是内核需要保护的地方?
2,内核代码段开始+1的地方需要保护?
但是这个测试表明这两个地方分明不需要保护。。。所以这两个地方应该没有代码段区域???
于是,我又测试了0xffffffff80200000->0xffffffff90200000,然后出现(已杀死,dump出一堆信息),0xffffffff80200000->0xffffffff801fffff同样(已杀死,dump出一堆信息),信息如下:
Message from syslogd@ at Mon Jul 12 18:28:44 2010 ...
localhost kernel: Oops: 0000 [#3] SMP
Message from syslogd@ at Mon Jul 12 18:28:44 2010 ...
localhost kernel: last sysfs file: /sys/devices/system/cpu/cpu1/topology/core_siblings
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel: Stack:
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel:  ffffffffa0309420 0000000000602030 000000000001e5e7 ffffffff8025da8e
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel:  0000000000020000 0000000000602050 0000000000000003 00007fff10968bc0
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel: Call Trace:
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel:  [<ffffffff80209051>] ? do_one_initcall+0x50/0x151
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel:  [<ffffffff8025da8e>] ? sys_init_module+0x9e/0x1c4
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel:  [<ffffffff8020ba02>] ? system_call_fastpath+0x16/0x1b
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel: Code: 20 80 48 c7 c7 33 90 30 a0 31 c0 e8 bc 18 f3 df 31 f6 48 c7 c7 33 90 30 a0 c7 04 25 00 00 20 80 00 00 00 00 31 c0 e8 a1 18 f3 df <8b> 34 25 f0 ff 1f 80 48 c7 c7 33 90 30 a0 31 c0 e8 8c 18 f3 df
Message from syslogd@ at Mon Jul 12 18:28:45 2010 ...
localhost kernel: CR2: ffffffff801ffff0


于是,内核代码段放置的位置难道是从0xffffffff80200000向上增加的一个内存区域(0xffffffff80200001可以写,似乎又说不通),但是这个地址和PAGE_OFFSET比较,相减得到的地址(应该是物理地址,按照直接映射的原则)明显大于物理内存???难道代码段的映射不是采用直接映射???

论坛徽章:
0
12 [报告]
发表于 2010-07-12 20:59 |只看该作者
本帖最后由 kgn28 于 2010-07-12 21:02 编辑

我的猜测:X86_64下
    内核代码段式一种特殊映射,从物理地址0x200000,开始的某一个大小(具体多大有待验证)。并且这段确实是可以写的。

论坛徽章:
0
13 [报告]
发表于 2010-07-12 21:14 |只看该作者
回复  new_learner 结果如下:

其中0xffffffff80200000是内核代码段开始的地方(见此:),那么我把这个 ...
kgn28 发表于 2010-07-12 18:51



    你的机器是64位的?

论坛徽章:
0
14 [报告]
发表于 2010-07-12 23:26 |只看该作者
11楼的贴子没看明白.....

PAGE_OFFSET 和内核代码段在哪里没有直接的关系.

LINUX 内核好象有些地方是数据和代码混合在一起的,也许是这个原因造成的可写.

不过前面NEW_LEARNER的那段代码似乎直接就给弄成可写的了. PS; 那个代码是什么版本下面的? X86结构的?

论坛徽章:
0
15 [报告]
发表于 2010-07-12 23:27 |只看该作者
回复 13# new_learner


    恩,是64位的。系统是centos5.3,内核是2.6.30.10。

论坛徽章:
0
16 [报告]
发表于 2010-07-12 23:36 |只看该作者
PAGE_OFFSET 和内核代码段在哪里没有直接的关系.

LINUX 内核好象有些地方是数据和代码混合在一起的,也许是这个原因造成的可写.

应该是没有关系,但是看页表初始的那段代码一头雾水。
这个0xffffffff80200000是_text的地址,这个地址加1,可以被修改,但是减1的内容却不能被修改(不过有可能是地址没有对齐。。。),并且0xffffffff90200000的地址内容不能被修改。而且这么大的地址,肯定不是直接映射,但是代码里面的初始化还是看不懂。。。{:3_183:}

论坛徽章:
0
17 [报告]
发表于 2010-07-12 23:38 |只看该作者
回复 14# accessory


    2.34也是这么写的。如果is_kernel_text,也是具有RW权限。

论坛徽章:
0
18 [报告]
发表于 2010-07-13 05:27 |只看该作者
11楼的贴子没看明白.....

PAGE_OFFSET 和内核代码段在哪里没有直接的关系.

LINUX 内核好象有些地方是 ...
accessory 发表于 2010-07-12 23:26



    2.6.15 X86 32bit

论坛徽章:
0
19 [报告]
发表于 2010-07-13 07:34 |只看该作者
Linux内核的代码段也是只读

论坛徽章:
0
20 [报告]
发表于 2010-07-13 10:30 |只看该作者
Linux内核的代码段也是只读
linux初学三月 发表于 2010-07-13 07:34



    How did you know that?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP