bail out with ELOOP earlier in do_link loop
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 24 Dec 2009 07:27:30 +0000 (02:27 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 5 Mar 2010 14:01:22 +0000 (09:01 -0500)
If we'd passed through 32 trailing symlinks already, there's
no sense following the 33rd - we'll bail out anyway.  Better
bugger off earlier.

It *does* change behaviour, after a fashion - if the 33rd happens
to be a procfs-style symlink, original code *would* allow it.
This one will not.  Cry me a river if that hurts you.  Please, do.
And post a video of that, while you are at it.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index 976fc32..84f1ec3 100644 (file)
@@ -1873,7 +1873,7 @@ exit_parent:
 
 do_link:
        error = -ELOOP;
 
 do_link:
        error = -ELOOP;
-       if (flag & O_NOFOLLOW)
+       if ((flag & O_NOFOLLOW) || count++ == 32)
                goto exit_dput;
        /*
         * This is subtle. Instead of calling do_follow_link() we do the
                goto exit_dput;
        /*
         * This is subtle. Instead of calling do_follow_link() we do the
@@ -1915,11 +1915,6 @@ do_link:
                __putname(nd.last.name);
                goto exit;
        }
                __putname(nd.last.name);
                goto exit;
        }
-       error = -ELOOP;
-       if (count++==32) {
-               __putname(nd.last.name);
-               goto exit;
-       }
        filp = do_last(&nd, &path, open_flag, flag, acc_mode, mode,
                       pathname, &is_link);
        __putname(nd.last.name);
        filp = do_last(&nd, &path, open_flag, flag, acc_mode, mode,
                       pathname, &is_link);
        __putname(nd.last.name);