Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.4.11 /fs/namei.c

Filename:/fs/namei.c
Lines Added:21
Lines Deleted:5
Also changed in: (Previous) 2.4.10  2.4.10-pre15  2.4.10-pre14  2.4.10-pre13  2.4.10-pre12  2.4.10-pre11 
(Following) 2.4.12  2.4.13-pre4  2.4.13-pre5  2.4.13-pre6  2.4.13  2.4.18-pre7 

Location
[  2.4.11
  [  fs
     o  namei.c

Patch

diff -u --recursive --new-file v2.4.10/linux/fs/namei.c linux/fs/namei.c
--- v2.4.10/linux/fs/namei.c   Sun Sep 23 11:41:00 2001
+++ linux/fs/namei.c   Tue Oct  9 09:56:10 2001
@@ -324,19 +324,28 @@
    return result;
 }
 
+/*
+ * Yes, this really increments the link_count by 5, and
+ * decrements it by 4. Together with checking against 40,
+ * this limits recursive symlink follows to 8, while
+ * limiting consecutive symlinks to 40.
+ *
+ * Without that kind of total limit, nasty chains of consecutive
+ * symlinks can cause almost arbitrarily long lookups. 
+ */
 static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
    int err;
-   if (current->link_count >= 8)
+   if (current->link_count >= 40)
       goto loop;
    if (current->need_resched) {
       current->state = TASK_RUNNING;
       schedule();
    }
-   current->link_count++;
+   current->link_count += 5;
    UPDATE_ATIME(dentry->d_inode);
    err = dentry->d_inode->i_op->follow_link(dentry, nd);
-   current->link_count--;
+   current->link_count -= 4;
    return err;
 loop:
    path_release(nd);
@@ -425,6 +434,7 @@
       nd->mnt = parent;
    }
 }
+
 /*
  * Name resolution.
  *
@@ -433,7 +443,7 @@
  *
  * We expect 'base' to be positive and a directory.
  */
-int path_walk(const char * name, struct nameidata *nd)
+int link_path_walk(const char * name, struct nameidata *nd)
 {
    struct dentry *dentry;
    struct inode *inode;
@@ -624,6 +634,12 @@
    return err;
 }
 
+int path_walk(const char * name, struct nameidata *nd)
+{
+   current->link_count = 0;
+   return link_path_walk(name, nd);
+}
+
 /* SMP-safe */
 /* returns 1 if everything is done */
 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
@@ -1935,7 +1951,7 @@
          /* weird __emul_prefix() stuff did it */
          goto out;
    }
-   res = path_walk(link, nd);
+   res = link_path_walk(link, nd);
 out:
    if (current->link_count || res || nd->last_type!=LAST_NORM)
       return res;


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.