[comp.bugs.sys5] Unlinking "."

rrw@cci632.UUCP (04/01/87)

Is it possible under vanilla System V to unlink "."? We have
the source, and from what I can tell, it is legal.

If it is legal, should it be OK to be able to remove it when the
directory is not empty?

In our version of Unix*, PERPOS**, it is legal to remove ".", and there
is a raging controversy about whether it should be. I would
appreciate any input.

				Thanks,
					Rick Wessman
					seismo!rochester!cci632!rrw

* Unix is a registered trademark of AT&T.
** PERPOS is a registered trademark of Computer Consoles, Inc.

gwyn@brl-smoke.UUCP (04/02/87)

In article <1059@cci632.UUCP> rrw@cci632.UUCP (Rick Wessman) writes:
>In our version of Unix*, PERPOS**, it is legal to remove ".", and there
>is a raging controversy about whether it should be.

Since directories in the Unix file system are required to have "."
and ".." entries, it does not make sense to permit their removal.

The best solution would seem to be to use system calls to create
and remove directories, instead of super-user privileged processes
that invoke link(2) and unlink(2).  This also lets you avoid race
conditions that the latter approach is heir to.

Current BSD and System V releases have mkdir(2) and rmdir(2) calls.

guy@gorodish.UUCP (04/02/87)

> Since directories in the Unix file system are required to have "."
> and ".." entries, it does not make sense to permit their removal.

I tend to agree, but consider this from the S5R3 "mvdir.sh" script:

	/etc/unlink $t/..

which is required if you are to move directories from one containing
directory to another.

> The best solution would seem to be to use system calls to create
> and remove directories, instead of super-user privileged processes
> that invoke link(2) and unlink(2).  This also lets you avoid race
> conditions that the latter approach is heir to.

The same is true for moving directories.  A "rename(2)" system call
permits you to move directories in unprivileged programs without
having to invoke a privileged directory-moving program.  It also
obviates the need to allow users to remove or create ".." links.

> Current BSD and System V releases have mkdir(2) and rmdir(2) calls.

Current BSD releases have "rename(2)", and since "rename" is in POSIX
future System V releases will probably have it as well.

weinberg@necis.UUCP (04/02/87)

In article <1059@cci632.UUCP> rrw@cci632.UUCP (Rick Wessman) writes:
>Is it possible under vanilla System V to unlink "."? We have
>the source, and from what I can tell, it is legal.

Yes, it is legal.  It has to be, since (at least in versions prior to V.3)
there is no system call to create or delete a directory in one piece.  Thus,
in order to create a directory you have to do a mknod followed by explicit
creation of "." and ".."; to delete it, you must do the opposite, again one
step at a time.

>If it is legal, should it be OK to be able to remove it when the
>directory is not empty?

In my opinion, no, although I can see the "but then it's not UN*X"
responses coming now!  Of course, determining whether or not a directory
is empty is (or at least has the potential to be) a very expensive
operation.  Besides, the "correct" solution is to provide the
mkdir and rmdir system calls and then prohibit any modification of "."
and ".." from outside the kernel.

ron@brl-sem.UUCP (04/02/87)

In article <1059@cci632.UUCP>, rrw@cci632.UUCP (Rick Wessman) writes:
> Is it possible under vanilla System V to unlink "."? We have
> the source, and from what I can tell, it is legal.
> 

rm/rmdir will not let you remove dot.  It is not a good idea to that
and they avoid this pitfall.  But if you are root, and you bypass their
protection by using the link/unlink system calls you can unlink the "."
entries and link directories as well.  This can make an unholy mess
out of your filesystem.

-Ron

jfh@killer.UUCP (04/03/87)

In article <5715@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <1059@cci632.UUCP> rrw@cci632.UUCP (Rick Wessman) writes:
> >In our version of Unix*, PERPOS**, it is legal to remove ".", and there
> >is a raging controversy about whether it should be.
> 
> Since directories in the Unix file system are required to have "."
> and ".." entries, it does not make sense to permit their removal.
> 
> The best solution would seem to be to use system calls to create
> and remove directories, instead of super-user privileged processes
> that invoke link(2) and unlink(2).  This also lets you avoid race
> conditions that the latter approach is heir to.
> 
> Current BSD and System V releases have mkdir(2) and rmdir(2) calls.

In the absense of rmdir(2) and rename(2) calls, you must be able to unlink
directory entries "." and "..".

If your rmdir(1) program doesn't bother to unlink ".", then the directory will
not go away and fsck(1) will decide that it is orphaned and place it in
/lost+found.

The next problem has to do with renaming directories.  If you do not permit
".." to be removed, then cd .. from the renamed directory won't work.

Doug is right about the races, but if you start moving all of the utilities
into the kernel, Sys5 will wind up looking a little fat.  There are plenty
of good reasons to let people unlink "." and "..".  Fix the races instead.

- john.		(jfh@killer.UUCP)

No disclaimer.  Whatcha gonna do, sue me?

allbery@ncoast.UUCP (04/04/87)

As quoted from <1059@cci632.UUCP> by rrw@cci632.UUCP (Rick Wessman):
+---------------
| Is it possible under vanilla System V to unlink "."? We have
| the source, and from what I can tell, it is legal.
+---------------

Dunno about non-root, but --

Once I was trying to relink our kernel and (being that there was not enough
documentation, Plexus Tech Support finally set me right about :mkuts68; you
did the "make" directly under Plexus Sys3) passed make the wrong arguments.
It unlinked .. and I had to manually relink it -- fsck didn't even complain
about it.

+---------------
| If it is legal, should it be OK to be able to remove it when the
| directory is not empty?
+---------------

A directory is an ordinary file, except that nobody can write to it and
only root can link/unlink it (I hope!).  I think that link() and unlink()
should fail on directories and that mkdir() and rmdir() should be system
calls.  Now if only we had source (Plexus gives you conf.c and name.c, plus
lots of object libraries and low.s, but no kernel source).

++Brando
-- 
 ____   ______________
/    \ / __   __   __ \   Brandon S. Allbery		|      /^\      USS
 ___  | /__> /  \ /  \    aXcess Company		|     A A A  CHALLENGER
/   \ | |    `--, `--,    6615 Center St. #A1-105	|     H V H
|     | \__/ \__/ \__/    Mentor, OH 44060-4101		|     H . H    SEVEN
\____/ \______________/   +1 216 974 9210		|    /  |  \    WHO
________________________________________________________|   /___|___\  DARED
As long as there is the spirit to dare new frontiers, the dream will never die.
cbatt!cwruecmp!ncoast!allbery ncoast!allbery%case.CSNET@relay.CS.NET BALLBERY
	    (UUCP)                      (CSNET/Internet)             (MCIMail)

guy@gorodish.UUCP (04/05/87)

>Doug is right about the races, but if you start moving all of the utilities
>into the kernel, Sys5 will wind up looking a little fat.  There are plenty
>of good reasons to let people unlink "." and "..".  Fix the races instead.

Wrongo.  First of all, you're not moving "the utilities" into the
kernel.  There's more to the "mkdir" and "rmdir" than the system
calls of the same name.

Second of all, there are some annoying restrictions caused by the
lack of these calls; a program that is set-UID to somebody other than
"root" can't create or destroy directories using its set-UID
protection, since the "mkdir" and "rmdir" commands must be set-UID
"root" and, as such, will throw away the old set-UID privileges when
they are run (remember, vanilla V7, S3, and S5 won't let you set the
real UID to match the effective UID).

Third of all, directories are an abstraction whose implementation is
hidden from applications when you do lookups of names in directories
or creation of new names.  As such, the implementation of directories
should be hidden from programs creating or destroying them as well.

You might barely be able to argue against this in systems that
support only one type of file system.  However, both systems using
the Sun "vnode" mechanism or the S5R3 File System Switch can support
many *different* types of file systems, not all of which would permit
you to create directories using the code from the old-style "mkdir"
command or to remove them using the code from the old-style "rmdir"
command.

The cleanest way of doing this is to make "mkdir" and "rmdir" into
system calls and provide per-file-system-type entries for creating
and removing directories.

Even if it were possible to fix the races without providing "mkdir"
and "rmdir" system calls, that wouldn't be a reason to "fix the
races" and leave those calls out of the kernel.  Yeah, it makes the
system fatter, but if you really worry about every single thing that
is put into system you should be running V6.  (I'd rather not, thank
you.)

And if you don't want S5 to acquire "mkdir" and "rmdir", you're too
late.  They're already there.

davidsen@steinmetz.UUCP (04/06/87)

In article <709@brl-sem.ARPA> ron@brl-sem.ARPA (Ron Natalie <ron>) writes:
>...
>rm/rmdir will not let you remove dot.  It is not a good idea to that
>and they avoid this pitfall.  But if you are root, and you bypass their
>protection by using the link/unlink system calls you can unlink the "."
>entries and link directories as well.  This can make an unholy mess
>out of your filesystem.

Once upon a time I wrote a routine to do sort of a "symbolic link",
putting one directory in another such that directory C seemed to be a
subdirectory of both A nd B. Obviously the value of .. was not
consistant, but I avoided rewriting a large BSD application. Someone
later used this to link a directory in itself (I assume by stupidity
rather than malace). Then they tried to run a dump... You're right, it
DOES make a mess.
-- 
bill davidsen			sixhub \
      ihnp4!seismo!rochester!steinmetz ->  crdos1!davidsen
				chinet /
ARPA: davidsen%crdos1.uucp@ge-crd.ARPA (or davidsen@ge-crd.ARPA)

allbery@ncoast.UUCP (04/08/87)

As quoted from <736@killer.UUCP> by jfh@killer.UUCP (John Haugh):
+---------------
| > In article <1059@cci632.UUCP> rrw@cci632.UUCP (Rick Wessman) writes:
| > >In our version of Unix*, PERPOS**, it is legal to remove ".", and there
| > >is a raging controversy about whether it should be.
|
| Doug is right about the races, but if you start moving all of the utilities
| into the kernel, Sys5 will wind up looking a little fat.  There are plenty
| of good reasons to let people unlink "." and "..".  Fix the races instead.
+---------------

No, there aren't.  When it was decided to go with a directed graph rather
than an arbitrary linked mishmash, "." and ".." became sources of trouble.
Unless you want to go back to the old format (and Ghod help fsck!), it's
best to make the kernel force "." and ".." to be correct via mkdir()/rmdir()/
rename().  Otherwise you're asking for trouble.

System V ld unlinks the destination if it encounters an error.  I once tried
to relink the sysV kernel (as root, due to file permissions) and did it wrong;
ld tried to write ./.., failed for the obvious reasons, and unlinked the
destination.  Worse, fsck didn't let out a peep; I had to use /etc/link to
fix it.

This is a VERY good reason to make "." and ".." only linkable internal to the
kernel and force mkdir()/rmdir()/rename() outside it.

++Brando
-- 
 ____   ______________
/    \ / __   __   __ \   Brandon S. Allbery		|  QUOTE OF THE DAY:
 ___  | /__> /  \ /  \    aXcess Company		|
/   \ | |    `--, `--,    6615 Center St. #A1-105	|	  `
|     | \__/ \__/ \__/    Mentor, OH 44060-4101		|
\____/ \______________/   +1 216 974 9210		|
cbatt!cwruecmp!ncoast!allbery ncoast!allbery%case.CSNET@relay.CS.NET BALLBERY
	    (UUCP)                      (CSNET/Internet)             (MCIMail)

jfh@killer.UUCP (04/09/87)

Yes - I insisted that '.' and '..' should be able to be linked and unlinked.
Yes - Guy Harris jumped all over me for being so stupid.
Yes - I jumped all over Guy Harris for jumping all over me.

But I still haven't figure out how any one proposes you unlink a *single*
directory entry given the restrictions imposed by rmdir(2).

I still think there needs to be some way to do this.  How about rmnod(2)? ...

- John.

Disclaimer:
	No disclaimer.  Whatcha gonna do, sue me?

gwyn@brl-smoke.UUCP (04/10/87)

In article <753@killer.UUCP> jfh@killer.UUCP (John Haugh) writes:
>... but if the
>mkdir(2) and rmdir(2) require you to be root in the first place ...

But they don't, and that's a very important reason for having them.

>...  The applications they
>develope are written to use the minimal subset of features from all Unix
>versions.

But that's pretty minimal indeed (it doesn't include any special
terminal handling, for example).  One of the goals of POSIX (IEEE
1003 standard) is to provide a more functional base than that.

guy@gorodish.UUCP (04/10/87)

>Of course, the system calls are always resident and taking up some of that
>not-so-plentiful-on-all-machines memory.

OK, please give numbers indicating the performance cost of putting
"mkdir" and "rmdir" into the system.

>I haven't looked at the documentation for S5R3 yet, so I really don't know
>what I am talking about here.  It seems that you can always spawn a mkdir(1)
>or rmdir(1) sub-process to create/delete your directories, but if the
>mkdir(2) and rmdir(2) require you to be root in the first place

They don't require you to be "root"; please read the documentation
first.

>(can you imagine
>	void crash ()
>	{
>		for (;;) {
>			mkdir ("a");
>			chdir  ("a");
>		}
>	}
>as you favorite subroutine? :-)

So what?  I can think of lots of things that can hang a system up.
This is hardly any sort of argument against making "mkdir" a system
call.

>Nice argument.  I would not like to work on a system with more than one
>or two different types of file systems.  I have a hard enough time fixing
>broken file systems as it is without having to learn another new one.

Other people either want to or need to work on a system with multiple
file system types.  The fact that *you* wouldn't like to work on such
a system doesn't mean such systems shouldn't exist.

>As for the Sun systems you work on, many of the features you are adding
>are not used by developers because of the differences between V7, BSDxxx
>and USG Systems III, IV and V.  If you would like some proof of this,
>talk with some at Uniplex Integration Systems.  The applications they
>develope are written to use the minimal subset of features from all Unix
>versions.

Some developers *do* use those features.  There's a tradeoff between
using various not-available-in-systems-released-prior-to-1980
features (which makes your code more portable, but can reduce its
performance, reliability, or functionality) and using them.  In some
cases it may be better to say "sorry, we won't support this program
under V7".

>It is possible to fix the races in the kernel without adding the calls.

But is it possible to fix the *other* problems caused by the absence
of those calls except by adding them?

>And as for making the system fatter, when I was installing USG 4.0 on
>a PDP-11/45 about 5 or 6 years ago, the system almost didn't fit because
>it had gotten so fat.  When USG 5.0 came out in 81 or 82, it didn't fit
>because there was so much junk in it.  As more stuff is added, it gets
>harder and harder to cram Unix into the limited memory that many of these
>machines have.

So?  It'd be hard to run even V6 on an 8K PDP-8.  Memory is getting
cheaper; sometimes you can use up more memory and get real benefits
from it.

>This is getting a bit ridiculous.

A bold statement, made with no apparent justification.  What is the
dividing line between a ridiculous and a sensible kernel size?  What
is a criterion that can be used for deciding which features "belong"
and which don't?  Do you want a hard limit on the kernel size, which
should apply from the time it's imposed until the heat-death of the
universe?

>There used to be one way to do everything in Unix.  And that was picked
>to be the most flexible one possible.  I guess times have changed.

Yes, times have changed.  The new solution - "mkdir" and "rmdir"
system calls - now offers more *useful* flexibility than the old
solution, given the existence of multiple file system types.

>I don't know if you paid any attention to the discussion about trashed file
>names, but it seems to me that a system call that won't let you unlink a
>directory with file entries in it is going to prevent the usual fix to this
>problem - unlink the directory and run fsck(1).

The *correct* fix to this problem is to have "fsck" treat directory
entries containing names with embedded NUL characters as being
scrambled directory entries, blast those entries, and then if
necessary put entries in "lost+found" for the files referred to those
entries.  The fact that the "usual" fix requires you to unlink
directories is irrelevant here.

kre@munnari.UUCP (04/11/87)

In article <753@killer.UUCP>, jfh@killer.UUCP (John Haugh) writes:
> I don't
> know if you paid any attention to the discussion about trashed file names,
> but it seems to me that a system call that won't let you unlink a directory
> with file entries in it is going to prevent the usual fix to this problem -
> unlink the directory and run fsck(1).
> 

Beats me what kind of trashy fsck you have if you think this will
achieve anything, with any reasonable fsck at all, what you've just
described is a pretty slow way to do ...

	set -- `ls -id $dir`
	mv $dir /.../lost+found/#$1

That is, upon finding an unlinked directory, fsck will simply relink
it into lost+found, all the files in it remain as they were.

kre

allbery@ncoast.UUCP (04/11/87)

As quoted from <753@killer.UUCP> by jfh@killer.UUCP (John Haugh):
+---------------
| In article <16186@sun.uucp>, guy%gorodish@Sun.COM (Guy Harris) writes:
| > Second of all, there are some annoying restrictions caused by the
| > lack of these calls; a program that is set-UID to somebody other than
| > "root" can't create or destroy directories using its set-UID
| > protection, since the "mkdir" and "rmdir" commands must be set-UID
| > "root" and, as such, will throw away the old set-UID privileges when
| > they are run (remember, vanilla V7, S3, and S5 won't let you set the
| > real UID to match the effective UID).
| > 
| I haven't looked at the documentation for S5R3 yet, so I really don't know
| what I am talking about here.  It seems that you can always spawn a mkdir(1)
| or rmdir(1) sub-process to create/delete your directories, but if the
| mkdir(2) and rmdir(2) require you to be root in the first place (can you
+---------------

No, you can't.  Please note that my UNaXcess Conferencing provides its own
mkdir command (mkconf) because the UC directories are not readable or writeable
by anyone but the owner of UC, and the "ua" executable runs setuid.  Therefore
a mkdir will FAIL ALWAYS because it runs as uid=who-ran-ua, euid=root but UC
needs uid=owner-of-ua.

This is (to say the least) a bad solution to a bad problem.  Unfortunately,
there is no GOOD solution short of moving mkdir() into the kernel.

Why don't I just allow anyone to scribble in the UC directories?  Ever heard
of security?

+---------------
| > the Sun "vnode" mechanism or the S5R3 File System Switch can support
| > many *different* types of file systems, not all of which would permit
| > you to create directories using the code from the old-style "mkdir"
| > command or to remove them using the code from the old-style "rmdir"
| > command.
| > 
| As for the Sun systems you work on, many of the features you are adding
| are not used by developers because of the differences between V7, BSDxxx
| and USG Systems III, IV and V.  If you would like some proof of this,
| talk with some at Uniplex Integration Systems.  The applications they
| develope are written to use the minimal subset of features from all Unix
| versions.
+---------------

Counterexample:  Informix Software, Inc.  Informix-SQL uses directories,
and is capable of being networked.  (In fact, they also use my solution:
look up $INFORMIXDIR/lib/makedir.)

+---------------
| It is possible to fix the races in the kernel without adding the calls.
| And as for making the system fatter, when I was installing USG 4.0 on
| a PDP-11/45 about 5 or 6 years ago, the system almost didn't fit because
| it had gotten so fat.  When USG 5.0 came out in 81 or 82, it didn't fit
| because there was so much junk in it.  As more stuff is added, it gets
| harder and harder to cram Unix into the limited memory that many of these
| machines have.  Sure, M68000's don't have a 64K text space.  But, many
| modern CPU's have such squirrely addressing that a massively huge Unix
| kernel really puts a dent in either the performance, or the amount of
| available memory.
+---------------

And lack of them really puts a dent in database operations -- the SINGLE
biggest use of computers in business.  System V provides THREE kinds of
mutual-exclusion primitives:  record locking (Vr3), semaphores, and messages
(see a good book on message-passing systems for info on how to use messages
for mut/ex).  V7 supplies NONE, and databases can therefore get into trouble.

BTW, what do you define as a modern CPU?  PDP/11?  iAPXx86?  I laugh.  The
first is dated, the second is a glorified 8080 no matter what its address
space it.  (80386 is the exception.  Intel finally decided to build a CPU
that wasn't an 8080 with cheap bank switching.)

MODERN CPUs are 68020, 32032, MicroVAX, etc. -- all of which handle the
address space needed for real work in the real world (read databases).

+---------------
| Yes, I run Version 7 at home.  Running size(1) on /unix gives me numbers
| something like 57000+20000+32000 or about 110K.  But have you looked at
| YOUR kernel lately?  Here are two 5.2 systems I use:
| 
| 3B2/400:	168704+25576+801536=972K
| Plexus P/60:	247060+18528+162740=418K
+---------------

So?  (NB:  I use a P/60 with SysV at work.)  If you need the features, they
have to go in.  And I dare you to set up a multiuser database under V7 that
will NEVER suffer from lock problems due to race conditions.

+---------------
| There used to be one way to do everything in Unix.  And that was picked
| to be the most flexible one possible.  I guess times have changed.  I don't
| know if you paid any attention to the discussion about trashed file names,
| but it seems to me that a system call that won't let you unlink a directory
| with file entries in it is going to prevent the usual fix to this problem -
| unlink the directory and run fsck(1).
+---------------

The correct fix is to fsdb the directory.  The REAL correct fix is to make
fsck put files with bad names in lost+found.

Flexible -- fine.  `.' and `..' are in fact flexible.  TOO flexible.  UNIX
went to directed graphs (and made `.' and `..' obsolete) when it was discovered
that arbitrarily linked directories could NOT be checked for consistency.  If
you disagree, remove setuid from mkdir and rmdir and tell the kernel that it's
okay for nonroot to link and unlink directories; then you have `.' and `..' in
their most flexible form, and you can kiss fsck goodbye.  Soon afterward you
can kiss your file system goodbye.

Small is beautiful, but too small is useless and therefore ugly.

++Brando
-- 
.--, .-----------,	Brandon S. Allbery	cbatt!cwruecmp!ncoast!allbery
    Y .-, .-, .-,	aXcess Company		ncoast!allbery@case.CSNET
.--,| +-' `-, `-,	6615 Center St. #A1-105		(@relay.cs.net)
|   A `-' `-' `-'	Mentor, OH 44060-4101	MCIMail: BALLBERY
`--' `-----------'	+01 216 974 9210	(UANet: "UANet FlagShip":Sysop)