免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 944 | 回复: 0
打印 上一主题 下一主题

kernel 2.4.18中mount可能引起的crash [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-20 15:57 |只看该作者 |倒序浏览

                由于工作需要,这两天在学习《Linux内核情景分析》里文件系统部分的章节,看到通过mount安装文件系统的时候,本来是对
copy_mount_options()这个函数中的两句代码不理解,结果在google上却查到了一片相关的文章,如下,指出了其中一个潜在的可以使
kernel崩溃的bug:
I have experienced rare kernel crashs when
mounting a filesystem with busybox-mount. After
digging deeper into the matter, i found out the
following:
Bug Analysis
============
In file linux-2.4.x/fs/namespace.c in
function copy_mount_options(), you can read
----- 8 PAGE_SIZE)
    size = PAGE_SIZE;
  i = size - copy_from_user((void *)page, data, size);
----- >8 -----
where TASK_SIZE is defined as 0xf0000000.
In this case, "data" will be always located in physical
RAM (i.e. ranging from i.e. 0x0 to 0x3fffff on an MCF5272C3
board). Unless you have 3.75 GByte of physical RAM :-), it is
quite obvious that
size = TASK_SIZE - (unsigned long)data
while always be bigger than PAGE_SIZE, finaly resulting in
size = PAGE_SIZE
Means, whereever "data" is stored, you will have to ensure
that at least 4096 bytes are subsequently readable from
this location.
So far, so good, but when now looking at file
user/busybox/mount.c in function mount_one(),
you can read
----- 88 -----
where "buf" will be equal to the location of "data" described above.
Means: "buf/data" is allocated somewhere on the task stack.
When the stack accidently gets allocated at the
last page(s) of the physical ram (i.e. at the top of 4MB), then
there is a good chance that "buf/data" equals something like 0x3fffa0.
Consequence: copy_mount_options() tries to copy the area
from 0x3fffa0 to 0x400f9f (with memcpy), and this doesn't work
on MCF5272, because the kernel segfaults when trying
to access the non-mapped memory regions beyond 0x3fffff.
Solutions
=========
One solution would be to change the line
size = TASK_SIZE - (unsigned long)data;
in copy_mount_options() in linux-2.4.x/fs/namespace.c to
somewhat like
size = "END_OF_PHYSICAL_MEMORY" - (unsigned long)data;
But i don't know how to determine "END_OF_PHYSICAL_MEMORY"
for all platforms. Maybe you know it and can tell me :-)
The other solution is to introduce a statically allocated
buffer of 4096 bytes to bb-mount rather than
the stack-allocated 255 bytes buffer (see patch attached).
this is IMHO not the best solution, because the
kernel-bug still remains!
best regards
Bernhard
--
Bernhard Kuhn, Software Engineer, Lineo Inc. (Where Open Meets Smart)
--- mount.c.orig        Mon Jan 14 03:17:25 2002
+++ mount.c        Mon Jan 14 03:07:23 2002
@@ -233,6 +233,9 @@
        }
}

+
+static char fstbuf[4096];
+
static int
mount_one(char *blockDevice, char *directory, char *filesystemType,
                  unsigned long flags, char *string_flags, int useMtab, int fakeIt,
@@ -244,10 +247,9 @@
                static const char *noauto_array[] = { "tmpfs", "shm", "proc", "ramfs", "devpts", "devfs", 0 };
                const char **noauto_fstype;
                const int num_of_filesystems = sysfs(3, 0, 0);
-                char buf[255];
                int i=0;

-                filesystemType=buf;
+                filesystemType=fstbuf;

                while(i bkuhn@lineo.com[/email]
)
    上边的大概意思是说, 在copy_mount_option()代码中的
        size = TASK_SIZE - (unsigned long)data
这一句, 在特殊的情况下可能会使内存访问越界,而导致系统崩溃, 我看了一下,这个问题确实很有可能发生,尤其是在嵌入式的环境下.可根据上文中提到的方法修改一下,我准备选择第一种.
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/6609/showart_102498.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP