[comp.databases] getcwd

peter@ficc.uu.net (Peter da Silva) (04/04/89)

One thing that really would make things a lot easier would be a fchdir()
call, that took a file descriptor and tried to chdir to it. All the info
that UNIX needs for the chdir is available via the fd.

Then you could do this:

	cwfd = open(".", 0);
	/* chdir around building cwd */
	fchdir(cwfd);
	close(cwfd);

One of the few features AmigaDOS has over UNIX...
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.

Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.
Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.

jfh@rpp386.Dallas.TX.US (John F. Haugh II) (04/05/89)

In article <3675@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>One thing that really would make things a lot easier would be a fchdir()
>call, that took a file descriptor and tried to chdir to it. All the info
>that UNIX needs for the chdir is available via the fd.

Cromix worked this way, perhaps not with a fchdir() call, but most of
the system calls under Cromix had file descriptor versions.

However ... all of the information needed for a chdir() is not present
in the file descriptor.  It is possible to be handed a file descriptor
which you would not be able to have opened because some component of
the search path denies access now, but at some point in the past did
allow access.
-- 
John F. Haugh II                        +-Quote of the Week:-------------------
VoiceNet: (214) 250-3311   Data: -6272  | "Porsche does not recommend
InterNet: jfh@rpp386.Dallas.TX.US       |  exceeding any speed limits"
UucpNet : <backbone>!killer!rpp386!jfh  +--        -- Porsche Ad   ------------

ed@mtxinu.COM (Ed Gould) (04/05/89)

 >>One thing that really would make things a lot easier would be a fchdir()
 >>call, that took a file descriptor and tried to chdir to it.

 >However ... all of the information needed for a chdir() is not present
 >in the file descriptor.  It is possible to be handed a file descriptor
 >which you would not be able to have opened because some component of
 >the search path denies access now, but at some point in the past did
 >allow access.

Worse than that, the permission required to open a directory is "r"
(since one may not open a directory for writing), whereas the
permission required to change to one is "x".  Hence, Unix protection
would be completely violated by the existance of fchdir().

-- 
Ed Gould                    mt Xinu, 2560 Ninth St., Berkeley, CA  94710  USA
ed@mtxinu.COM		    +1 415 644 0146

"I'll fight them as a woman, not a lady.  I'll fight them as an engineer."

flee@shire.cs.psu.edu (Felix Lee) (04/05/89)

In article <3675@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>One thing that really would make things a lot easier would be a fchdir()
>call, that took a file descriptor and tried to chdir to it. All the info
>that UNIX needs for the chdir is available via the fd.

This would open up holes with chroot(), but anyway...

You need another open() mode, O_EXEC, open for execution.  Then you
could fchdir(), fexecve(), and so forth.  With a little work, you
could then replace all the standard system calls with library routines
that call the corresponding f-function.  Then knowledge of path names
would be localized to the open() function (making it easier to add
file access hooks).

flink(), funlink(), and frename() are problematical because you also
need descriptors to the directories involved, unless you attach
knowledge of name and location to file descriptors.

Probably not worth the effort.  Now if you want to come up with a more
powerful model of data storage that lets you layer Unix filesystem
semantics on top of it...

(Aside from all that, pushdir()/popdir() routines would be handy.)
--
Felix Lee	flee@shire.cs.psu.edu	*!psuvax1!shire!flee

danl@cbnewsc.ATT.COM (daniel.r.levy) (04/05/89)

In article <811@mtxinu.UUCP>, ed@mtxinu.COM (Ed Gould) writes:
<  >>One thing that really would make things a lot easier would be a fchdir()
<  >>call, that took a file descriptor and tried to chdir to it.
<  >However ... all of the information needed for a chdir() is not present
<  >in the file descriptor.  It is possible to be handed a file descriptor
<  >which you would not be able to have opened because some component of
<  >the search path denies access now, but at some point in the past did
<  >allow access.
< Worse than that, the permission required to open a directory is "r"
< (since one may not open a directory for writing), whereas the
< permission required to change to one is "x".  Hence, Unix protection
< would be completely violated by the existance of fchdir().

Umm, somehow SUNOS 4.0 manages to have a fchdir(), without creating a gaping
security hole.  I tested it; it won't let me fchdir() into a mode 444 directory
even though I can open a file descriptor for reading onto that directory.
Granted, it has no way of knowing the search path, and could get you into a
directory, still having execute permission to you, that you had successfully
opened earlier but which you could not open now.  But you could also have
fork()'ed earlier and had the child chdir() into the once-accessible directory,
or into its parent if the directory were read-only then and only now has become
searchable.  Then you could communicate with that child process via some
interprocess communication method to get it to do its dastardly deeds, so
the fchdir() "hole" isn't any more of a hole than exists already.

Note: SUNOS 4.0 also allows fchdir() to be disabled, by means of turning
on auditing.  The call will always fail in this case.
-- 
Dan'l Levy                 UNIX(R) mail:  att!ttbcad!levy, att!cbnewsc!danl
AT&T Bell Laboratories
5555 West Touhy Avenue     Any opinions expressed in the message above are
Skokie, Illinois  60077    mine, and not necessarily AT&T's.

peter@ficc.uu.net (Peter da Silva) (04/05/89)

In article <3675@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>One thing that really would make things a lot easier would be a fchdir()
>call, that took a file descriptor and tried to chdir to it. All the info
>that UNIX needs for the chdir is available via the fd.

In article <14689@rpp386.Dallas.TX.US>, jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes:
> However ... all of the information needed for a chdir() is not present
> in the file descriptor.  It is possible to be handed a file descriptor
> which you would not be able to have opened because some component of
> the search path denies access now, but at some point in the past did
> allow access.

That's an issue worth considering, but I'm not sure that it's really
a security problem. After all, you could always spawn a child in a
directory and send it messages over a pipe. Same thing, just a little more
complex.

It would be really nice to be able to pass an fd to another program, too.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.

Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.
Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.

guy@auspex.auspex.com (Guy Harris) (04/05/89)

>Worse than that, the permission required to open a directory is "r"
>(since one may not open a directory for writing), whereas the
>permission required to change to one is "x".  Hence, Unix protection
>would be completely violated by the existance of fchdir().

Oh dearie me.  From SunOS 4.0:

NAME
     chdir - change current working directory

SYNOPSIS
     int chdir (path)
     char *path;

     int fchdir (fd)
     int fd;

DESCRIPTION
     chdir() and fchdir cause a directory to become  the  current
     working directory, that is, the starting point for pathnames
     not beginning with `/'.

     In order for a directory to become the current directory,  a
     process must have execute (search) access to the directory.

     The path argument to chdir() points to  the  pathname  of  a
     directory.   The  fd  argument  to  fchdir  is the open file
     descriptor of a directory.

RETURN VALUE
     Upon successful completion, a value of 0 is returned.   Oth-
     erwise,  a value of -1 is returned and errno is set to indi-
     cate the error.

WARNING
     fchdir is provided  as  a  performance  enhancement  and  is
     guaranteed to fail under certain conditions.  In particular,
     if auditing is active the call will never succeed, and  EIN-
     VAL  will  be  returned.  Applications which use this system
     call must be coded to detect  this  failure  and  switch  to
     using chdir() from that point on.

Fortunately, "fchdir" requires you to have execute permission on the
directory in question, so you're safe there, even if it won't let you
change to some directories to which you could otherwise change....

flee@shire.cs.psu.edu (Felix Lee) (04/06/89)

In article <3684@ficc.uu.net>,
   peter@ficc.uu.net (Peter da Silva) writes:

>It would be really nice to be able to pass an fd to another program, too.

Surprise!  sendmsg() in 4.3bsd lets you do this.  SunOS4.0 looks like
it may also.  See the recv(2) man page, in the paragraph describing
msg_accrights.
--
Felix Lee	flee@shire.cs.psu.edu	*!psuvax1!shire!flee

peter@ficc.uu.net (Peter da Silva) (04/06/89)

In article <FLEE.89Apr4223010@shire.cs.psu.edu>, flee@shire.cs.psu.edu (Felix Lee) writes:
> flink(), funlink(), and frename() are problematical because you also
> need descriptors to the directories involved, unless you attach
> knowledge of name and location to file descriptors.

Maybe funlink() and frename(), but flink() would just need the device an
inode number.

Hey, you're right. UNIX++ is gonna be pretty cool :->. It's looking more and
more like AmigaDOS. Now how about adding asynchronous I/O and using mapped
files to move SYSV's streams/queues into the file system...?
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.

Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.
Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.

chris@mimsy.UUCP (Chris Torek) (04/06/89)

In article <FLEE.89Apr4223010@shire.cs.psu.edu> flee@shire.cs.psu.edu
(Felix Lee) writes:
>You need another open() mode, O_EXEC, open for execution.  Then you
>could fchdir(), fexecve(), and so forth. ... [but]
>flink(), funlink(), and frename() [would remain] problematical ...

Actually, flink would be no problem even now.  (fsymlink, on the other
hand, has the same problem as funlink and frename.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

les@chinet.chi.il.us (Leslie Mikesell) (04/06/89)

In article <3675@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>One thing that really would make things a lot easier would be a fchdir()
>call, that took a file descriptor and tried to chdir to it. All the info
>that UNIX needs for the chdir is available via the fd.
>

Better yet would be a per-process *name* of the current working
directory stored somewhere, built according the the way you
happened to get there.  This would make getcwd() amount to printing
static data instead of the contortions it does now, and as a
side effect, it would make ".." mean something unsuprising in the
presence of linked directories.  Is there some reason this isn't done?

Les Mikesell

john@frog.UUCP (John Woods) (04/06/89)

In article <811@mtxinu.UUCP>, ed@mtxinu.COM (Ed Gould) writes:
>>>One thing that really would make things a lot easier would be a fchdir()
>>>call, that took a file descriptor and tried to chdir to it.
>>However ... all of the information needed for a chdir() is not present
>>in the file descriptor.  It is possible to be handed a file descriptor
>>which you would not be able to have opened because some component of
>>the search path denies access now, but at some point in the past did
>>allow access.

This objection had occurred to me also, but isn't necessarily SO bad, since
changing access permissions on directories doesn't cause you to lose your
current working directory.

> Worse than that, the permission required to open a directory is "r"
> (since one may not open a directory for writing), whereas the
> permission required to change to one is "x".

This one is a killer.

Perhaps a better model might be a pushd()/popd() arrangement (perhaps 
even with a swapd()).  A stack depth of 2 is enough to make it useful
for getcwd().  You lose the ability to necessarily shut a process out
of a directory if it happens to lose it, but that doesn't seem too much
a loss; you don't lose the distinction between r and x access modes.
A stack depth greater than two seems to be to start on a "slippery-slope"
problem; the more you allow, the more resources a badly written process
can take up, but the more uses it can have (though to use it for a shell
directory stack, you would want an arbitrary (or at least very large) limit,
which is clearly unacceptable).

-- 
John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101
...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu

			Remainder Khomeini!

tim@phobos.sybase.com (Tim Wood) (04/07/89)

Friends, this discussion does not belong in comp.databases.
-TW
tim@sybase.com		{pacbell,pyramid,sun,{uunet,ucbvax}!mtxinu}!sybase!tim
Voluntary disclaimer: This message is solely my personal opinion.
		      It is not a representation of Sybase, Inc.  OK.