Subject: Re: utmp file format change
To: James Graham <greywolf@starwolf.com>
From: Andrew Brown <atatat@atatdot.net>
List: tech-userlevel
Date: 09/29/2001 00:09:04
># as for flink(2), no.  flink(2) would be a terribly bad idea.  consider
># that when opening a file, *all* the permissions on *all* the inodes in
># the path to the file are considered.  if you were able to get some
># process to hand you an open file descriptor to some file somewhere
># that relies on being protected by permissions in the path and you were
># able to flink(2) it to some arbitrary name, you could bypass the
># permissions set that had been established.
>
>If you can get some process to hand you said open file descriptor,
>assuming that said file descriptor pointed to a file that would meet
>all the physical conditions of a link() call (exclusive only of path
>navigation), what's to keep you from doing
>
>	lseek(fd, (off_t) 0, SEEK_SET);
>	while((len = read(fd, (char *) buf, buffer_size)) > 0) {
>		write(outfd, (char *) buf, len);
>	}
>
>in the first place?

you could do that, sure, or pass the fd off to another process so that
it could do that, too, but then you have only a static copy of what
the "thing" is, not constant and ongoing access.  that's what flink(2)
would give you, and that's what is not allowed.

>If you had an flink(fd, path, mode), it would have to go through normal
>semantics, i.e. no creation of directories on the fly (that's not the
>job of a syscall), make sure you can create said path as an end node,
>make sure said end node lives on the same device (making a symlink to
>a nonexistent file would be awfully silly, wouldn't it?)

well...first of all, mode would not be a part of it.  remember, you'd
only be creating a link to an inode that was already allocated, so the
permissions would already be set up.

no, it wouldn't create directories on the fly.  mkdir -p does that.

sure, it would have to live on the same device, but this is nothing
new.

so...?

>I've often wished for an flink() call, as well as an funlink() call.
>Now BEFORE you jump on me for the last one, I do realise its folly, because
>it would effectively do a 'clri' on the inode pointed to by the fd in
>question -- unlink() should be restricted to pathnames and not operate
>on file descriptors EVER.  A user-accessible clri routine is the last
>thing we want floating around.

funlink(2)?  that's weird...especially since the link count might be
anything when you do it.  that would probably produce bad effects in
too many places.

>A user-accessible way to link in an fd to an anonymous place, however, does
>not strike me as all that odd of an idea.

not odd, but bad.

>Take into account the requirements of a link() call; if you've got the
>fd, you've got access to the data of the file as it is.  Chances are rather
>good that if it's protected by directory accesses and such, those directories
>will live on a filesystem that does not have publicly writable space in which
>to store a hard link to said file.  And since cross-device hard links are
>prohibited, and given the properties of symbolic links to be useless in
>a case like this, I don't see that we're losing, here.

take ssh and agent forwarding.  suppose there's a reason i might pass
you an open fd to my agent.  it's a local domain socket.  it's in a
directory that you can't get to.  you need to use it once.  with
flink(2), there's nothing stopping you from adding a link to it in a
place where you can get to it a second or a third time, perhaps
checking periodically to see if its got any new keys in it.  i might
have wanted an easy way to pass you a single key.  flink(2) gives you
a way to steal all the keys i put into that agent.

granted, fd passing doesn't happen much in my world (that i know of),
so this is perhaps a bit contrived.  i've seen it used once, and i
thought it was a bad place to use it.  in the absence of fd passing,
the only way you'll end up with a file descriptor is if you were
writing to a temp file and decided that you want to the keep the data
instead of losing it.  in that case, you are perfectly within your
writes and current capabilities to open a new file, not unlink that
one, and copy the data over so that you have it for later.

>Of course, we'd have to prove that it is not inherently insecure to
>permit this and then get everyone else to pick up the system call.

we can't.  it is.  they won't.

-- 
|-----< "CODE WARRIOR" >-----|
codewarrior@daemon.org             * "ah!  i see you have the internet
twofsonet@graffiti.com (Andrew Brown)                that goes *ping*!"
andrew@crossbar.com       * "information is power -- share the wealth."