Re: [BUG] Kernel 2.4.0-test1-ac10 changes open of symlink behavior.

From: Andries Brouwer (aeb@veritas.com)
Date: Sun Jun 11 2000 - 17:23:41 EST


On Sun, Jun 11, 2000 at 04:51:33PM -0400, Alexander Viro wrote:

> Case in question: foo/bar/baz being a dangling symlink,
> open() with O_CREATE applied to it. Behaviour mandated by the draft:
> create a file in place where symlink points to. Problem: it is wildly
> inconsistent with every other case when we create/remove/rename objects.

It is the normal path resolution behaviour of symlinks.
The result of path resolution is a directory and a name
to be used (possibly created) in this directory.

Strange that you never looked at these standard texts when deciding
upon the details of implementation. Several pages are devoted to
discussing in detail how symbolic links behave, both w.r.t. system calls
and w.r.t. standard utilities.

Let me quote three fragments. [This is from Draft 3.]
(You should really get the draft yourself.)

Andries

-------------------------------------------------------------------
 3.382 Symbolic Link

A type of file with the property that when the file is encountered
during path name resolution, a string stored by the file is used to
modify the path name resolution. The stored string has a length of
{SYMLINK_MAX} bytes or fewer. Note: Path Name Resolution is defined
in detail in Section 4.5 on page 117.

Rationale
Many implementations associate no attributes, including ownership with
symbolic links. Security experts encouraged consideration for defining
these attributes as optional. Consideration was given to changing
utime( ) to allow modification of the times for a symbolic link, or as
an alternative adding an lutime( ) interface. Modifications to chown( )
were also considered: allow changing symbolic link ownership or
alternatively adding lchown( ). As a result of the problems
encountered in defining attributes for symbolic links (and interfaces
to access/modify those attributes) and since implementations exist
that do not associate these attributes with symbolic links, only the
file type bits in the st_mode member and the st_size member of the
stat structure are required to be applicable to symbolic links.

Historical implementations were followed when determining which
interfaces should apply to symbolic links. Interfaces that
historically followed symbolic links include chmod( ), link( ), and
utime( ). Interfaces that historically do not follow symbolic links
include chown( ), lstat( ), readlink( ), rename( ), remove( ), rmdir(),
and unlink( ). IEEE Std. 1003.1-200x deviates from historical
practice only in the case of chown( ). Because there is no requirement
that there be an association of ownership with symbolic links, there
was no point in requiring an interface to change ownership. In
addition, other implementations of symbolic links have modified chown()
to follow symbolic links.

In the case of symbolic links, IEEE Std. 1003.1-200x states that a
trailing slash is considered to be the final component of a path name
rather than the path name component that preceded it. This is the behavior
of historical implementations. For example, for /a/b and /a/b/, if /a/b is
a symbolic link to a directory, then /a/b refers to the symbolic link,
and /a/b/ is the same as /a/b/., which is the directory to which the
symbolic link points.

For multi-level security purposes, it is possible to have the link read mode
govern permission for the readlink( ) function. It is also possible that
the read permissions of the directory containing the link be used for
this purpose. Implementations may choose to use either of these methods;
however, this is not current practice and neither method is specified.

Several reasons were advanced for requiring that when a symbolic link
is used as the source argument to the link( ) function, the resulting
link will apply to the file named by the contents of the symbolic link
rather than to the symbolic link itself. This is the case in
historical implementations. This action was preferred, as it supported
the traditional idea of persistence with respect to the target of a
hard link. This decision is appropriate in light of a previous
decision not to require association of attributes with symbolic links,
thereby allowing implementations which do not use inodes. Opposition
centered on the lack of symmetry on the part of the link( ) and
unlink( ) function pair with respect to symbolic links. Because a
symbolic link and its referenced object coexist in the file system
name space, confusion can arise in distinguishing between the link
itself and the referenced object. Historically, utilities and system
calls have adopted their own link following conventions in a somewhat
ad hoc fashion. Rules for a uniform approach are outlined here,
although historical practice has been adhered to as much as was
possible. To promote consistent system use, user-written utilities are
encouraged to follow these same rules. Symbolic links are handled
either by operating on the link itself, or by operating on the object
referenced by the link. In the latter case, an application or system
call is said to follow the link. Symbolic links may reference other
symbolic links, in which case links are dereferenced until an object
that is not a symbolic link is found, a symbolic link that references
a file that does not exist is found, or a loop is detected. (Current
implementations do not detect loops, but have a limit on the number of
symbolic links that they will dereference before declaring it an
error.)
There are four domains for which default symbolic link policy
is established in a system. In almost all cases, there are utility
options that override this default behavior. The four domains are as
follows:
1. Symbolic links specified to system calls that take file name arguments
2. Symbolic links specified as command line file name arguments to utilities
that are not performing a traversal of a file hierarchy
3. Symbolic links referencing files not of type directory,
specified to utilities that are performing a traversal of a file hierarchy
4. Symbolic links referencing files of type directory,
specified to utilities that are performing a traversal of a file hierarchy

First Domain. The first domain is considered in earlier rationale.
Second Domain. The reason this category is restricted to
utilities that are not traversing the file hierarchy is that some
standard utilities take an option that specifies a hierarchical
traversal, but by default operate on the arguments
themselves. Generally, users specifying the option for a file
hierarchy traversal wish to operate on a single, physical hierarchy,
and therefore symbolic links, which may reference files outside of the
hierarchy, are ignored. For example, chown owner file is a different
operation from the same command with the -R option specified. ...

4.5 Path Name Resolution
...
If a symbolic link is encountered during path name resolution, the
behavior shall depend on whether the path name component is at the end
of the path name and on the function being performed. If all of the
following are true, then path name resolution is complete: 1. This is
the last path name component of the path name. 2. The path name has
no trailing slash. 3. The function is required to act on the symbolic
link itself, or certain arguments direct that the function act on the
symbolic link itself. In all other cases, the system shall prefix the
remaining path name, if any, with the contents of the symbolic
link. If the combined length exceeds {PATH_MAX}, and the
implementation considers this to be an error, errno shall be set to
[ENAMETOOLONG] and an error indication shall be returned. Otherwise,
the resolved path name shall be the resolution of the path name just
created. If the resulting path name does not begin with a slash, the
predecessor of the first file name of the path name is taken to be the
directory containing the symbolic link.
...

open()
...
In general, the open( ) function follows the symbolic link if path
names a symbolic link. However, the open( ) function, when called with
O_CREAT and O_EXCL, is required to fail with [EEXIST] if path names an
existing symbolic link, even if the symbolic link refers to a
nonexistent file. This behavior is required so that privileged
applications can create a new file in a known location without the
possibility that a symbolic link might cause the file to be created in
a different location.

-
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/



This archive was generated by hypermail 2b29 : Thu Jun 15 2000 - 21:00:24 EST