Re: Recursion level of symlinks limitted to five?

Alexander Viro (viro@math.psu.edu)
Wed, 10 Mar 1999 02:44:29 -0500 (EST)


On 9 Mar 1999, Junio Hamano wrote:

> >>>>> "david" == david parsons <o.r.c@p.e.l.l.p.o.r.t.l.a.n.d.o.r.u.s> writes:
>
> david> In article <linux.kernel.7v4snva2bj.fsf@shine.twinsun.com>,
> david> Junio Hamano <junio@twinsun.com> wrote:
> >> Just out of curiosity, couldn't the resolving of symlinks all be
> >> done in the userland?
>
> david> A libc solution requires that everyone use a libc that's been
> david> hacked to do this, umm, method, and not everyone will hack their
> david> version of libc to do that.
>
> Agreed, and that's part of my idea. If non-insignificant number
> of people feel that 5 levels of symlinks are too few for
> real-world applications, either (1) they rewrite their
> application so that it catches ELOOP whenever they call system
If they do not check for ELOOP their applications are broken.

> calls and resolve symlink as needed, or (2) fold such a
They can do it right now. And deal with races.

> check-and-recover scheme into the standard C library so that
> application programmers do not have to worry about this
> limitation over and over again. The key idea here is to fold
And forget about portability. Thanks lot.

> this into the standard C library, not to replace the C library
> with your hacked one.
Ahem... There is more than one C library. There is more than one
UNIX. There is more than one version of Linux kernel, after all.

> When (2) happens, but until everybody updates to the new C
> library, applications running on a configuration where they do
> not see more than 5 levels of symlink indirection work fine with
> both the old and new C library, and in addition, applications
> running with the new C library would not even see 5-level
> restriction imposed by the kernel. Of course, userland C
> library would still have its own limits, depending on the way
> the memory needed to recursively resolve symlinks are allocated.
> Over time, everybody would update their C library if the above
> makes into the standard C library.

Say it to David. Again. And watch the result. Anyway, it's BS,
since you'll get a bloody lot of races that cannot be avoided outside of
kernel. And watch the effect if the thing will happen to contain
/proc/123/fd/4.

> When that happens, there is no reason for the kernel to even
> support 5 levels of indirection. The kernel could even return
> ELOOP when it sees just one symbolic link and let the C library
> resolve the symlink. Of course, on the other hand, we may want
> to have the kernel resolve some levels of indirection itself
> for, say, performance reasons. But an important point of the
Or for, say, sane fs semantics and race avoidance.

> idea outlined above is that it makes how many symlink
> indirections a typical application expects to be supported by
> the kernel irrelevant when the kernel implementor decides how
> many levels of symlinks are supported by the kernel.

Current implementation of symlinks resolving is broken, but fixes
belong to kernel, not to userland. It can (and I hope will) be done in
2.3. The Right Thing (tm): for normal symlinks add a new method that would
do kernel-space readlink (current ->readlink() actually does exactly that
and then copies the stuff to userland). Remove ->follow_link() for them -
it is nothing but kernel-space readlink() followed by lookup_dentry() (I'm
talking about the *current* code). For pseudo-symlinks in /proc leave the
stuff as-is - they can't give any recursion anyway (and are *not*
symlinks). Add a context for lookups (i.e. structure filled before call of
lookup_dentry() and containing the pointer to name + flags + credentials
of caller) (there is a lot of other reasons to do it). Keep the stack of
pointers to buffers returned by kernel-space readlink() inside that
structure. Make lookup_dentry() completely iterative. There you go - you
need 2 pointers + integer for each level of recursion (pointer to
symlink's dentry, pointer to current position in the symlink contents,
length of remaining part of said contents).
Notice that you *can't* rely on arbitrary depth of nested symlinks
in applications - all Unices impose some limit here. You can't assume that
application will never receive ELOOP.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/