Defect report from : Lawrence Mayer , n/a
(Please direct followup comments direct to austin-group-l@xxxxxx)
@ page 549 line 21195 section ln objection {20080427a}
Problem:
Edition of Specification (Year): 2004
Defect code : 1. Error
ABSTRACT
XCU page 549 lines 21195-7
i. not only allows but *requires* ln -s basename target_dir to
create a symlink which points to itself. (Likewise for ln -s basename
target_dir/basename and ln -s basename/ target_dir/basename.)
ii. prohibits ln from writing an error message when it creates a
symlink which points to itself (i).
A symlink which points to itself is a bug which tries to cause an infinite loop
when used. Ln has several idiosyncrasies which make such bugs especially
likely. Proposal A revises ln's Description to prevent these bugs without
otherwise affecting ln's behavior or functionality. Proposals B-C add Examples
and Rationale, respectively.
DEFINITIONS
Throughout this report, the definitions, XCU page 550 lines 21213-7 are used
verbatim:
source_file is a pathname of a file to be linked, and
target_dir is a pathname of an *existing* directory in which the
new directory entries are created
PROBLEM DESCRIPTION
Example 1. The commands:
cd /etc
ln fstab X11/
create a hardlink called /etc/X11/fstab as a synonym for /etc/fstab. When
creating hardlinks, ln resolves all its arguments. Here, both of ln's arguments
are relative paths, which ln resolves relative to working directory /etc.
Example 2. The commands:
cd /etc
ln -s fstab X11/
create a symlink called /etc/X11/fstab whose pointer is the string "fstab".
This symlink points to itself, not to /etc/fstab as might be expected from
Example 1.
Ln has several idiosyncrasies which make bugs like Example 2 especially likely:
a. Ln handles pathnames in an unusual way. Most Unix utilities and shells
resolve all relative paths relative to the working directory, but ln does not.
b. Ln handles pathnames in an inconsistent way:
1. When ln creates hardlinks, all relative paths are resolved in the
usual way (relative to the working directory) (Example 1), but not when ln
creates symlinks (Example 2).
2. Even when ln creates symlinks, a relative path is resolved in the
usual way (relative to the working directory) if it's the final argument but
not if it's a source_file (Example 2).
c. Ln writes no error message when it creates a symlink which points to itself.
An error message only occurs later, when the symlink is used (and attempts to
cause an infinite loop).
Indeed, ln is *prohibited* from writing an error message when it creates a
symlink which points to itself, because lines 21196-7 state: "The ln utility
shall do nothing more with source_file and shall go on to any remaining files."
In order to write an error message, ln *would* have to do something more with
source_file: namely, compare it to the last pathname component of the
destination path in order to test if the symlink would point to itself and an
error message is needed. See Proposal A below.
Action:
Proposal A. Replace ln Description, XCU page 549 lines 21195-7, with the
following:
2. If the -s option is specified:
a. If source_file (minus any trailing slash characters) is a basename
which equals the last pathname component of the destination path, ln shall
write a diagnostic message to standard error.
b. Otherwise, ln shall create a symbolic link named by the destination
path and containing as its pathname source_file.
In either case, the ln utility shall do nothing more with the current
source_file and go on to any remaining source_files.
Note: This Proposal makes ln -s write an error message rather than create a
symlink which points to itself. This Proposal doesn't affect ln in any other
way. Since a symlink which points to itself is a bug, this Proposal prevents
these bugs without otherwise affecting ln's behavior or functionality. In
particular, ln -s still makes no attempt to resolve source_file: 2(a) uses
"source_file" as a string without resolving it as a pathname. See Proposal C
below.
Proposal B. Add the following Examples to XCU page 551 after line 21256:
1. The commands:
cd /etc
ln fstab X11/
create a hardlink called /etc/X11/fstab as a synonym for /etc/fstab. When
creating hardlinks, ln resolves all its arguments. Here, both of ln's arguments
are relative paths, which ln resolves relative to working directory /etc.
2. The commands:
cd /etc
ln -s fstab X11/
generate only an error message. These commands try to create a symlink called
/etc/X11/fstab whose pointer is the string "fstab". This symlink would point to
itself, not to /etc/fstab as might be expected from Example 1. Why?
Ln -s resolves only its final argument: here a relative path (X11/), which ln
-s resolves relative to the working directory (/etc). Ln -s never attempts to
resolve source_file (here "fstab") but rather uses it verbatim as the symlink's
pointer string. The pointer string is only resolved later, when the symlink is
used. If the pointer string is a relative path, it's resolved (when the symlink
is used) *relative to the symlink's parent directory*. So if the symlink's
pointer equaled its basename (as in this Example, where both equal "fstab"),
the symlink would point to itself. Ln writes an error message rather than
create such a symlink.
Proposal C. Add the following Rationale to XCU page 551 after line 21284 (2 new
paragraphs):
Ln -s doesn't resolve source_file as a pathname but rather uses it verbatim as
the symlink's pointer string. That allows ln to create symlinks pointing to
paths that don't yet exist. It also allows ln to create symlinks pointing to
relative paths which are resolved not when the symlink is created but later,
when the symlink is used, *relative to the symlink's parent directory*. A
symlink which points to a relative path is resilient to moving the symlink's
parent directory or any underlying directory.
A danger of this functionality is its potential to create a symlink which
points to itself. Description 2(a) ensures that ln -s writes an error message
rather than create such a symlink.
|